Given the following XML file:
<assets> <asset name="tile"> <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Path x:Name="top" Width="24" Height="12" Stretch="Fill" Fill="#FF065F02" Stroke="#10000000" Data="F1 M 0,6L 12,12L 24,6L 12,0L 0,6 Z "/> </Canvas> </asset> </assets>
It’s easy enough to create reusable assets in Silverlight and load them on demand from XML, and refer to the various pieces that make up the asset by name.
First, add an XML file to your Silverlight project. Set the Build Action to “Content” and the Copy to Output Directory to “Do not copy”. In the example below, it’s “r.xml”.
Next, add the following methods to a class (probably your UserControl):
private Canvas CreateXamlAsset(string assetName) { return XamlReader.Load(LoadAsset(assetName)) as Canvas; } private string LoadAsset(string assetName) { var e = from a in XDocument.Load("r.xml").Descendants("assets") where (string) a.Attribute("name") == assetName select a.FirstNode; return e.First().ToString(); }
The code uses LINQ to extract the asset and create it using the XamlReader.Load method. It assumes that the type being returned is a Canvas (it needs to be a container type and for these types of situations I normally use Canvas).
Once the canvas is created, you can call methods such as this:
private Shape FindShape(Canvas c, string name) { return c.FindName(name) as Shape; }
to locate the named elements within the dynamically created Xaml. For example, given the XAML at the top of this post, I could call the FindShape method like this:
Shape top = FindShape(canvas, "top");
That would return the Path named “top" in the XAML.
Make sure that you actually add the asset being returned from CreateXamlAsset to a parent control at some point! :)
this.Children.Add(canvas);