我在资源中有两个数据模板,DataTemplateSelector可以在它们之间进行选择:
<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>
以下是选择器的代码隐藏:
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);
}
}
只要我将MyTemplateSelector用于一个DataColumn(比如Name1),它就可以正常工作。但我的DataGrid有两个模板列绑定到两个字符串字段:Name1和Name2
<DataGridTemplateColumn CellTemplateSelector="{StaticResource MyTemplateSelector}" > // Should be bound to Name1
<DataGridTemplateColumn CellTemplateSelector="{StaticResource MyTemplateSelector}" > // Should be bound to Name2
我的问题是:如何在Binding中设置正确的Path(Name1或Name2)(而不是Name1OrName2,见上文)。谢谢。
答案 0 :(得分:3)
看起来我的原始答案是由于对问题的误解,并且要求不是关于数据模板选择器,而是如何参数化绑定绑定的属性,因此您可以使用相同的两个不同属性的模板。
快速回答:这不是XAML的设计方式。您无法参数化Path
的{{1}}属性。传统的解决方案是为每种情况编写一个模板。如果您可以通过Binding
或DataGridTemplateColumn
属性指定Binding
要显示的属性/字段,然后将该值传递给模板,那将是很好的 - 但它不这样做。
I found a likely-looking workaround here,但我不确定相对于复制和粘贴DisplayMemberPath
并继续您的生活,其上的投资回报率会很好。
如果模板很复杂,需要考虑维护,你可以这样解决:
XAML资源:
DataTemplate
原始答案
这是一种常见模式:您需要相同<DataTemplate x:Key="RedBaseTemplate">
<Border BorderBrush="Green" BorderThickness="2" Margin="1">
<Label x:Name="Text" Background="Red" Content="{Binding}" />
</Border>
</DataTemplate>
<DataTemplate x:Key="GreenBaseTemplate">
<Border BorderBrush="Red" BorderThickness="2" Margin="1">
<Label x:Name="Text" Background="Green" Content="{Binding}" />
</Border>
</DataTemplate>
<DataTemplate x:Key="RedTemplateA">
<ContentControl
Content="{Binding A}"
ContentTemplate="{StaticResource RedBaseTemplate}"
/>
</DataTemplate>
<DataTemplate x:Key="RedTemplateB">
<ContentControl
Content="{Binding B}"
ContentTemplate="{StaticResource RedBaseTemplate}"
/>
</DataTemplate>
<DataTemplate x:Key="GreenTemplateA">
<ContentControl
Content="{Binding A}"
ContentTemplate="{StaticResource GreenBaseTemplate}"
/>
</DataTemplate>
<DataTemplate x:Key="GreenTemplateB">
<ContentControl
Content="{Binding B}"
ContentTemplate="{StaticResource GreenBaseTemplate}"
/>
</DataTemplate>
(或值转换器,但经常使用)的多个实例,但具有不同的参数。解决方案是从DataTemplateSelector
派生,因此您可以使用自己的唯一参数在使用点实例化事物,而不是在其他地方创建一个共享实例作为资源。在这种情况下,MarkupExtension
是一个类而不是一个界面,因此您无法从DataTemplateSelector
派生您的选择器。相反,你写一个快速MarkupExtension
返回你的选择器。
我想在XAML中使用MarkupExtension
或RedGreenTemplateSelectorExtension
将模板本身传递给StaticResource
,但XAML解析器并不喜欢这个想法。但这很好用。
DynamicResource
XAML
public class RedGreenTemplateSelectorExtension : MarkupExtension
{
public Object RedTemplateKey { get; set; }
public Object GreenTemplateKey { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
var redTemplate = new StaticResourceExtension(RedTemplateKey)
.ProvideValue(serviceProvider) as DataTemplate;
var greenTemplate = new StaticResourceExtension(GreenTemplateKey)
.ProvideValue(serviceProvider) as DataTemplate;
return new RedGreenTemplateSelector() {
RedTemplate = redTemplate,
GreenTemplate = greenTemplate
};
}
}
public class RedGreenTemplateSelector : 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);
}
}
P.S。 StaticResource
和Binding
是两个非常不同的类,可以执行非常不同的操作。人们滥用&#34;绑定&#34;意思是&#34;任务&#34;。不是。你根本没有使用任何绑定。