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!


Comments (0)