我将ContentControl.DataTemplateSelector设置为我想要的。(。) 我希望根据命令或其他任何方法,调用ContentControl以通过xaml或代码从选择器重新选择模板。
感谢
答案 0 :(得分:19)
参加晚会,我知道。 =)
当遇到这个问题时,我发现最简单的方法是显式设置一个像
这样的新TemplateSelectorMyContentControl.ContentTemplateSelector =
new MyDataTemplateSelector();
答案 1 :(得分:9)
我不知道有任何(非kludgy)方法:当WPF需要选择模板时调用DataTemplateSelector,就WPF而言,这是一次性的决定。 (你可以通过让WPF认为内容已经改变来克服它,例如通过将内容设置为null然后再返回 - 我认为这样可行但是没有测试它 - 但这非常难看!)如果有一个很好的方法,我也有兴趣知道!
但是,有一种替代方法可以更改 更新内容的方式,以响应数据更改,即通过触发器。您可以在DataTemplate.Triggers
集合中使用DataTriggers来显示和隐藏元素,具体取决于内容数据。要更改整个显示,您可以例如在网格中设置两个渲染,并使用触发器来控制哪个是可见的。您甚至可以将数据模板设置为ContentControl,并使用触发器来更改ContentTemplate。当然,这取决于将模板更改为可绑定属性的标准,但情况并非总是如此。
Here's some brief discussion of selectors vs. triggers,虽然情况略有不同。
答案 2 :(得分:8)
我想我甚至稍后参加聚会,但是对于一个可以帮助某人的不同想法......
您还可以尝试使用ValueConverter
ContentControl
媒体资源上的ContentTemplate
而不是DataTemplateSelector
。
只需在DataContext
中绑定一个属性即可,例如ScreenNumber
。然后在ValueConverter
中返回与DataTemplate
相关联的ScreenNumber
。
ValueConverter示例:
public class ValueDataTemplateConverter : IValueConverter
{
public DataTemplate TemplateA { get; set; }
public DataTemplate TemplateB { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is ValueType valueType)
switch (valueType)
{
case ValueType.TypeA:
return TemplateA;
case ValueType.TypeB:
return TemplateB;
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
示例xaml资源:
<converters:ValueDataTemplateConverter x:Key="ValueDataTemplateConverter">
<converters:ValueDataTemplateConverter.TemplateA>
<DataTemplate>
<TextBox Text="{Binding Value}" />
</DataTemplate>
</converters:ValueDataTemplateConverter.TemplateA>
<converters:ValueDataTemplateConverter.TemplateB>
<DataTemplate>
<CheckBox IsChecked="{Binding Value}" />
</DataTemplate>
</converters:ValueDataTemplateConverter.TemplateB>
</converters:ValueDataTemplateConverter>
答案 3 :(得分:5)
与Jens回答类似,您可以使用DataTemplateSelector
的现有实例,而不是创建新实例。
var currentSelector = MyContentControl.ContentTemplateSelector;
MyContentControl.ContentTemplateSelector = null;
MyContentControl.ContentTemplateSelector = currentSelector;