我有ContentPresenter和DataTemplateSelector:
...
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var model = item as ItemControlViewModel;
if (model.CurrentStatus == PrerequisitesStatus.Required)
{
return RequiredTemplate;
}
if (model.CurrentStatus == PrerequisitesStatus.Completed)
{
return FinishedTemplate;
}
...
return InProgressTemplate;
}
更改CurrentStatus时,将调用OnPropertyChanged。
我需要以某种方式在更改属性时触发此DataTemplateSelector并更改ContentPresenter DataTemplate。有什么建议吗?
Threre是类似的问题: 1 2,但由于状态太多,我不想使用任何DataTriggers。
尝试使用DataTriggers
<ContentPresenter
Grid.Column="1"
Height="16"
Width="16"
Margin="3">
<ContentPresenter.Triggers>
<DataTrigger Binding="{Binding Path=CurrentStatus}" Value="0">
<Setter Property="ContentPresenter.ContentTemplate" Value="{StaticResource ResourceKey=_requiredStatusTemplate}" />
</DataTrigger>
</ContentPresenter.Triggers>
</ContentPresenter>
但得到了一个错误: 触发器集合成员必须是EventTrigger类型:(
答案 0 :(得分:35)
正如您在评论中请求了数据触发器的示例,您在这里:
FrameworkElement只能有EventTriggers,因此您会收到错误消息触发器集合成员必须是EventTrigger类型
并且不要直接使用ContentPresenter,它应该在ControlTemplate中使用。当您想拥有动态内容时,最好使用ContentControl。 见What's the difference between ContentControl and ContentPresenter?
最后,这是对DataTrigger问题的建议。我把它放在了可重用的风格中....
XAML:
<Window x:Class="WpfApplication88.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate x:Key="requiredTemplate">
<TextBlock Text="requiredTemplate"></TextBlock>
<!--your stuff here-->
</DataTemplate>
<DataTemplate x:Key="completedTemplate">
<TextBlock Text="CompletedTemplate"></TextBlock>
<!--your stuff here-->
</DataTemplate>
<Style x:Key="selectableContentStyle" TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=CurrentStatus}" Value="Required">
<Setter Property="ContentTemplate" Value="{StaticResource requiredTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=CurrentStatus}" Value="Completed">
<Setter Property="ContentTemplate" Value="{StaticResource completedTemplate}" />
</DataTrigger>
<!-- your other Status' here -->
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<ContentControl Width="100" Height="100" Style="{StaticResource selectableContentStyle}"/>
</Grid>
</Window>
答案 1 :(得分:6)
我可能错了,但我相信DataTemplateSelector
仅在ItemContainerGenerator
为添加到集合中的项目创建容器时使用。由于在属性值更改时未生成新容器,因此永远不会通过选择器应用新的DataTemplate
。
正如评论中所建议的那样,我建议您查看VisualStateManager
或数据触发器,否则当一个或多个属性更改值时,您将不得不为每个项重新创建容器。
答案 2 :(得分:2)
作为一个额外的选择 - 如果你想坚持你的模板,只需使用s绑定转换器。