Collections of Items in Resources
Recently, I was trying to figure out how to reuse resources within multiple collections all defined in WPF XAML. For example, suppose I have the following:
<MeshGeometry3D.Positions>
<Point3D X="0" Y="0" Z="0"/>
<Point3D X="5" Y="0" Z="0"/>
<Point3D X="0" Y="0" Z="5"/>
</MeshGeometry3D.Positions>
What if I wanted to put the 3 Point3D instances in a resource and use them to populate a collection? Hmmm.... how about this?
<Window.Resources>
<Point3D x:Key="PointA" X="0" Y="0" Z="0"/>
<Point3D x:Key="PointB" X="5" Y="0" Z="0"/>
<Point3D x:Key="PointC" X="0" Y="0" Z="5"/>
</Window.Resources>
<MeshGeometry3D.Positions>
{StaticResource PointA}
{StaticResource PointB}
{StaticResource PointC}
</MeshGeometry3D.Positions>
Sure enough, that doesn't work. When you have something like this:
<SomeElement>
{Binding ... }
</SomeElement>
The "{Binding...}" string actually gets sent to the SomeElement type converter instead of being treated like a markup extension.
So as jfo pointed out to me, I can do this:
<Window.Resources>
<Point3DCollection x:Key="MyPoints">
<Point3D X="0" Y="0" Z="0"/>
<Point3D X="5" Y="0" Z="0"/>
<Point3D X="0" Y="0" Z="5"/>
</Point3DCollection>
</Window.Resources>
<MeshGeometry3D.Positions="{StaticResource MyPoints}">
Ok, not bad, but now, what if I want to share those points on multiple resources (I know this is getting contrived but I can imagine there being a reason to want to do this to avoid duplication in some scenario), I can't go back and do this:
<Window.Resources>
<Point3D x:Key="PointA" X="0" Y="0" Z="0"/>
<Point3D x:Key="PointB" X="5" Y="0" Z="0"/>
<Point3D x:Key="PointC" X="0" Y="0" Z="5"/>
<Point3DCollection x:Key="MyPoints">
{StaticResource PointA}
{StaticResource PointB}
{StaticResource PointC}
</Point3DCollection>
<Point3DCollection x:Key="MyOtherPoints">
{StaticResource PointA}
{StaticResource PointC}
</Point3DCollection>
</Window.Resources>
So how would I do this in such a way that I can avoid duplicating those Point3D values?
Well, off to Chuck I go. His answer? Element Syntax for Markup Extensions:
<Window.Resources>
<Point3D x:Key="First" X="0" Y="0" Z="0"/>
<Point3D x:Key="Second" X="5" Y="0" Z="0"/>
<Point3D x:Key="Third" X="0" Y="0" Z="5"/>
<Point3DCollection x:Key="MyPoints">
<StaticResource ResourceKey="First"/>
<StaticResource ResourceKey="Second"/>
<StaticResource ResourceKey="Third"/>
</Point3DCollection>
<Point3DCollection x:Key="MyOtherPoints">
<StaticResource ResourceKey="First"/>
<StaticResource ResourceKey="Third"/>
</Point3DCollection>
</Window.Resources>
I thought that was pretty cool. I wasn't aware of that syntax. Very useful. I've also seen it with Binding where this:
<TextBlock FontSize="12" Foreground="Red" Text="{Binding XPath=@ISBN}"/>
Is replaced by this:
<TextBlock FontSize="12" Foreground="Red">
<TextBlock.Text>
<Binding XPath="@ISBN"/>
</TextBlock.Text>
</TextBlock>
Cool and useful!