I've got two data templates in the resources and a DataTemplateSelector to choose between them:
<DataGrid.Resources>
<DataTemplate x:Key="RedTemplate">
<TextBlock Text="{Binding **Name1OrName2**}" />
</DataTemplate >
<DataTemplate x:Key="GreenTemplate">
....
</DataTemplate>
<local:MyTemplateSelector x:Key="MyTemplateSelector"
RedTemplate="{StaticResource RedTemplate}"
GreenTemplate="{StaticResource GreenTemplate}" />
</DataGrid.Resources>
Here is the code-behind of the selector:
public class MyTemplateSelector : DataTemplateSelector
{
public DataTemplate RedTemplate { get; set; }
public DataTemplate GreenTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is RedItem) return RedTemplate;
else if (item is GreenItem) return GreenTemplate;
else return base.SelectTemplate(item, container);
}
}
As long as I use MyTemplateSelector for one DataColumn (say, Name1), it works fine. But my DataGrid has two template columns to be bound to two string fields: Name1 and Name2
<DataGridTemplateColumn CellTemplateSelector="{StaticResource MyTemplateSelector}" > // Should be bound to Name1
<DataGridTemplateColumn CellTemplateSelector="{StaticResource MyTemplateSelector}" > // Should be bound to Name2
My question is: how can I set the proper Path (Name1 or Name2) in the Binding (instead of Name1OrName2, see above). Thank you.
It looks like my original answer was due to a misunderstanding of the question, and the requirement isn't about the data template selector, but rather how to parameterize the property a binding binds to, so you can use the same template for two different properties.
Quick answer: That's not the way XAML is designed to be used. You can't parameterize the
Path
property of aBinding
. The conventional solution is to write one template for each case. It would be nice if you could specify which property/field aDataGridTemplateColumn
is meant to display, via aBinding
orDisplayMemberPath
property, and then passed that value to the template -- but it doesn't work that way.I found a likely-looking workaround here, but I'm not sure the ROI on it would stack up well relative to copying and pasting a
DataTemplate
and getting on with your life.If the templates are complicated enough for maintenance to be a concern, you can work around that like so:
XAML resources:
Original Answer
This is a common pattern: You want multiple instances of the same
DataTemplateSelector
(or value converter, quite often), but with different parameters. The solution is to derive fromMarkupExtension
, so you can instantiate the thing at the point of use with its own unique parameters, rather than creating one shared instance someplace else as a resource. In this caseDataTemplateSelector
is a class rather than an interface, so you can't derive your selector fromMarkupExtension
. Instead you write a quickMarkupExtension
that returns your selector.I wanted to pass the templates themselves to
RedGreenTemplateSelectorExtension
usingStaticResource
orDynamicResource
in the XAML, but the XAML parser didn't like the idea. But this works well enough.XAML
P.S.
StaticResource
andBinding
are two very different classes that do very different things. People misuse "binding" to mean "assignment". It's not. You aren't using any bindings at all here.