WPF Reusing Xaml Effectively
- by Steve
Hi,
I've recently been working on a project using WPF to produce a diagram. In this I must show text alongside symbols that illustrate information associated with the text.
To draw the symbols I initially used some png images I had produced. Within my diagram these images appeared blurry and only looked worse when zoomed in on. To improve on this I decided I would use a vector rather than a rastor image format. Below is the method I used to get the rastor image from a file path:
protected Image GetSymbolImage(string symbolPath, int symbolHeight)
{
Image symbol = new Image();
symbol.Height = symbolHeight;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.UriSource = new Uri(symbolPath);
bitmapImage.DecodePixelHeight = symbolHeight;
bitmapImage.EndInit();
symbol.Source = bitmapImage;
return symbol;
}
Unfortunately this does not recognise vector image formats. So instead I used a method like the following, where "path" is the file path to a vector image of the format .xaml:
public static Canvas LoadXamlCanvas(string path)
{
//if a file exists at the specified path
if (File.Exists(path))
{
//store the text in the file
string text = File.ReadAllText(path);
//produce a canvas from the text
StringReader stringReader = new StringReader(text);
XmlReader xmlReader = XmlReader.Create(stringReader);
Canvas c = (Canvas)XamlReader.Load(xmlReader);
//return the canvas
return c;
}
return null;
}
This worked but drastically killed performance when called repeatedly.
I found the logic necessary for text to canvas conversion (see above) was the main cause of the performance problem therefore embedding the .xaml images would not alone resolve the performance issue.
I tried using this method only on the initial load of my application and storing the resulting canvases in a dictionary that could later be accessed much quicker but I later realised when using the canvases within the dictionary I would have to make copies of them. All the logic I found online associated with making copies used a XamlWriter and XamlReader which would again just introduce a performance problem.
The solution I used was to copy the contents of each .xaml image into its own user control and then make use of these user controls where appropriate. This means I now display vector graphics and performance is much better.
However this solution to me seems pretty clumsy. I'm new to WPF and wonder if there is some built in way of storing and reusing xaml throughout an application?
Apologies for the length of this question. I thought having a record of my attempts might help someone with any similar problem.
Thanks.