Supporting additional Uri Schemas for the Image.Source property - wpf

Is there a way to make the following code behind expression to evaluate to true given the Xaml below. I'm asking this question because I have to work with a Library that converts FlowDocuments containing Images to HTML. Only the "Source" Attribute of the Image Control is persisted and you can't use the standard approach of using a BitmapImage because this won't convert back to a Uri String.
Debug.Assert(this.image1.Source.ToString() == "data:image/x-png .. <rest of the Image.Source Property below>")
<Image x:Name="image1" Source="data:image/x-png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAy1JREFUeNpMU1toVFcUXefc18zNZJJJZmLHSDAmCiqKrbV/7U8Rv5oPQT9URKgobUVQQRD88cOfVq20NNZGSotIqQpaTXzGiM+KQWK0kvEVw0xGzENm4sxkzr3nnHt77jRT3HDhcs7ea+219j7E930Ekc1m8ezFMJrq7E88I/RwYmzcHR3NQNM0xGIxNCRmQWfvVuqRukFHyPGR4WEMDQ2BYiaIZoBI3jx2/seu0suHm6gVrpwLIeCBQIeck/nz8JFc/7XdeqimWga9WCyqagopeEO+53B3/t75peEHfT8n1u0rw4wcB3dACYmnf9/fk+071/b6bu+u+RJMa164NwDQ5rW14emTfxK5cwe7iwNXP7YjddCdIhGpvzt4Y+tj124YMXuPXZi+f2mFGY6Ac4nJ/hufUTuqvwvHrpO29nbYvtO6sWnyTnuDndQUqkUJ4LoQVnS6HEmmrPSTjwQx4HCg5HooMo7jo+43I1ZjJ6lqqbfo3D3La7uXx43FxAMMKHOFB58LuL4Ol/tg3EOeeeh8xbY8mBJdFQlVACb9/K2M89eiWrmqJWI2UVWvK/OIrzgUoCeBQpm73w+Vtg+UvKP/m9/R0VH5kVLizfgkklGr5SszNRgDrycega8KXcXsMIF+fdbpi+H2NaKQr+QXCgVFMLMHQVy42gd658RRevv0ZotqVFNXVYASk+BaiGmrv975Ot56JP0shXQ6DT2XywWNYFpITPX+dsi4fXJLjdoBJVmxqCvPr5gnlZRyoRgq/Hqg0/l8rXBqP+jinEMrM4YbN29ambOd3xkDl3fouqloidoLwBE+skU5YQE1TCG6ShJzlalPH38hqc7ydv1dzZUeRl+kmhZMPPolahlh1YgyzEcwiVMZ9tMPw2zDHIt+2qiR5lIAEpiqah69ykw85/QMsW0b1LAQcaaW7VhoX4kbNEFVce+Y88eJjLNeifDDFPGts60rrRb9UCjwewVx5tRbsTbYdLwfyRBd9u3SyOSXc0M97484iBBFYlvSHNyUMPpIsCbVMaoveFBKOCqvJ6qTJWXpZ1S3WfyXGOQEdnKToEU1Zypr3s6wl/8VYACfeYRluTSjlQAAAABJRU5ErkJggg=="></Image>

The solution is to implement a pluggable protocol for the "data" Scheme. This way the Source property acts exactly as with the built-in protocols for Image retrieval. The technique is described here.

Related

Is there a way to programmatically convert other Xaml elements to path elements?

In Blend, it is possible to convert certain Xaml elements to Path, using Object->Path->Convert to Path option.
Is there some API to do the same programmatically, in a WPF application?
Thanks
Having dived into the source-code of Expression Blend with DotPeek (for research purposes of course), I can say that the Convert to Path API is not exposed in a useful way.
Internally it uses a number of private methods to convert RichTextBox content, TextBlocks, TextBoxes and simply geometry.
The only external method is in Microsoft.Expression.DesignSurface.Geometry:
public static PathGeometry[] ConvertToPathGeometries(SceneElement element)
But the parameter SceneElement is a type used only within Expression blend and has a huge number of dependencies. There appears no easy way to create SceneElements for your own Silverlight objects outside of Expression Blend. You could probably execute the functionality as a Blend add-in but I don't see you getting it working in a stand-alone application.
It was an interesting exercise, but unsuccessful. Sorry.

Serializing WPF RichTextBox to XAML vs RTF

I have a RichTextBox and need to serialize its content to my database purely for storage purposes. It would appear that I have a choice between serializing as XAML or as RTF, and am wondering if there are any advantages to serializing to XAML over RTF, which I would consider as more "standard".
In particular, am I losing any capability by serializing to RTF instead of XAML? I understand XAML supports custom classes inside the FlowDocument, but I'm not currently using any custom classes (though the potential for extensibility might be enough reason to use XAML).
Update: I ended up going with RTF because of its support for text-encoded embedded images. XAML doesn't seem to include image data in its encoding, and XamlPackage encodes to binary, so RTF just works better for me. So far I haven't noticed any lack in capability.
If all your users are doing is typing in the RichTextBox and doing character formatting, RTF is as good as XAML. However there are many FlowDocument capabilities you may expose in your UI that are not convertible to RTF.
Here are some examples of FlowDocument (and RichTextBox) features that are not expressable in RTF or are implemented differently:
A Block can have an arbitrary BorderBrush, including gradient brushes with stops, VisualBrush
A Section has the HasTrailingParagraphBreakOnPaste property
Floater / ClearFloaters is implemented differently
Hyphenation can be enabled/disabled per block, not just per paragraph
WPF Styles and ResourceDictionaries can be included in the Resources property
Arbitrary WPF UI such as bound CheckBoxes, etc, can be embedded inside the RichTextBox and can be cut-and-pasted from other windows.
For example, suppose you want to allow users to drag or cut/paste in a "current date/time" field into your RichTextBox that would always show the current date and time. This could be done by adding a second read-only RichTextBox that has the InlineUIContainer and the already-bound control. This even works when cutting and pasting from other applications and does not require custom controls.
Another consideration is that the code to convert between FlowDocument and RTF is relatively complex so it may have lower performance than going with XAML. Of course loose XAML doesn't include images and such - for that you need to use XamlPackage. I store my XamlPackage in the database as a byte[], but you can also choose to Base64 encode it for storage as a string.
The bottom line is that it really depends on whether you want the user to be able to use features not available in RTF. Even if your application doesn't include tools to generate FlowDocuments that use these features, it is possible to cut-and-paste them from other applications.
Be aware that in Wpf RichTextBox's method called TextRange.Save has a bug whereby it loses any end of line terminator. Microsoft will not fix.
https://connect.microsoft.com/WPF/feedback/ViewFeedback.aspx?FeedbackID=478640&wa=wsignin1.0#tabs

Get XAML source of WPF Window

I would like to get the XAML source of a WPF Window (MainWindow). Clicking on a button on that window would return the XAML of the window and I would save it in another file.
Is this possible and how can it be achieved?
You can use the XamlWriter:
using (Stream stream = File.OpenWrite("D:\\Test.xaml"))
{
XamlWriter.Save(this, stream);
}
You can use XamlWriter for some basic Xaml Serialization.
In particular, look at this article on its limitations.
The earlier answers are both correct, but I think it should also be mentioned that you can also extract the original XAML used to create the window (if desired) using the API for Reflector's BAMLViewer extension.
BAMLViewer solves a different problem than XamlWriter: Using Reflector / BAMLViewer will return the original source XAML with all bindings, etc intact but will not include current property values. Using XamlWriter will include current property values but such things as resource references and markup extensions will be lost. Also, some things will not serialize using XamlWriter.
You must choose between these based on your application needs.

Modify XAML string dynamically

I want to add/remove some part of XAML dynamically i.e. from code behind file in C#.how to Add any specific XAML string on specified location (means under some tag) from .cs file. Please help.
XAML is xml you can use XmlReader and XmlWriter or any other of the XML serialization mechanismn of .NET to write/read XML (XMlDocument is probably the best approach here to modify existing xml). ALso there are the XamlReader and XamlWriter class that allow ou to (de)serialize any object graph from/to XAML automatically. If you can use .NET 4.0, you have even more fine grained possibilities to athor XAML because it has a new XAML stack. Use this as a starting point.
What is it that modifying the XAML will do for you?
If you just want to change the appearance of your WPF application (perhaps by adding some more content at certain locations), it will most likely be easier to do this by referencing the objects in question. So, if you need to add some text to a button, name the button with x:Name="myButton" and in code set: myButton.Content = "Click Me"
XAML is really a technology for constructing object hierarchies. Pretty much every element in the XAML corresponds to a .NET CLR class. When loaded, these classes are instantiated nd populated according to the attributes used in the XAML. Once loaded, the XAML has finished it's job and is essentially unloaded/unavailable.
You might need to do something beyond this, but from your brief question it doesn't seem like it. I would just work on the object model and leave the XAML be.

Serialize an image in XAML using XamlWriter

I'm using XamlWriter to serialize a group of WPF objects. One of these objects is an Image control whose Source is set to a file on disk.
When the XamlWriter serializes the objects, it sets the source image to an Uri that points to the file on the filesystem. Is there a way to include that data in the Xaml so that instead of referencing the file, the information is stored in xaml?
Thanks
From MSDN:
Serialization Limitations of XamlWriter.Save
"Images are also serialized as object references to images as they exist in the project, rather than as original source references, losing whatever filename or URI was originally referenced."
Well, what I did in the end was build a wrapper class that used a binary serializer to store the images and the xaml code from the XamlWriter.

Resources