我希望它ContentTemplate根据中的值而变化DataTrigger.
是的,我考虑使用a DataTemplateSelector,但现在我需要一个DataTrigger或更好的说a MultiDataTrigger.
请看下面的示例应用程序,DataTemplate不会改变:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:WpfApplication1">
<StackPanel>
<CheckBox IsChecked="{Binding BoolProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:Window1}}}" Content="BoolProperty"/>
<ContentControl Content="{Binding BoolProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:Window1}}}">
<ContentControl.ContentTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding BoolProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:Window1}}}" Content="Template 1"/>
</DataTemplate>
</ContentControl.ContentTemplate>
<ContentControl.Resources>
<DataTemplate x:Key="Template2">
<CheckBox IsChecked="{Binding BoolProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:Window1}}}" Content="Template 2"/>
</DataTemplate>
</ContentControl.Resources>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding BoolProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:Window1}}}" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource Template2}"/>
</DataTrigger> …Run Code Online (Sandbox Code Playgroud) 前言
我创建了两个不同的数据DataTemplates,以便更快地加载数据网格单元.一个基本上是文本块,另一个是更昂贵的UserControl.在加载时,数据模板选择器决定是否需要加载廉价和更昂贵的控件,这会将首次加载/性能从~12秒提高到~2,因为大多数单元不需要复杂且加载简单模板所需的时间与其他模板相比几乎没有.
无论如何,它在负载上运行良好.但是,当我更改下面的数据时,会引发属性更改,并且应该强制DataTemplateSelector再次调用SelectTemplate()来重新评估要使用的数据模板 - 嗯,它不会.
有趣的是,在上面的失败之后,当我点击一个单元格时,它会调用SelectTemplate()并在需要时翻转DataTemplate.
码
<DataGrid>
.....
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl Content="{Binding Intervals[0].Self}"
ContentTemplateSelector="{StaticResource TxtVsExpensiveCell_TemplateSelector}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
Run Code Online (Sandbox Code Playgroud)
请注意,DataTemplate选择器选择的更复杂的控件与我在没有DataTemplateSelector的情况下测试时的工作方式完美相同.另外,关于Binding Intervals [0]的注释.自我是一个返回"this"的属性,我绑定的Object的ref,唯一的原因是(当Self被提升时)到强制重新评估DataTemplate.显然这不太奏效.
题
如何强制数据模板重新评估?
支持代码*
这是我的资源词典(没什么特别的)
<DataTemplate x:Key="SimpleTemplate">
<TextBlock DataContext="{Binding}"/>
</DataTemplate>
<DataTemplate x:Key="ComplexTemplate">
<Views:ComplexCell DataContext="{Binding}"/>
</DataTemplate>
<Views:MyTemplateSelector
x:Key="TxtVsExpensiveCell_TemplateSelector"
SimpleTemplate="{StaticResource SimpleTemplate}"
ComplexTemplate="{StaticResource ComplexTemplate}"/>
Run Code Online (Sandbox Code Playgroud)
显然我有MyTemplateSelector类覆盖SelectTemplate并且工作得很好......
有一个包含大量对象的视图,它们从DataTemplate声明中获取它们的视图:
<DataTemplate DataType="{x:Type vm:StatusAViewModel}" >
<vw:StatusAView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:StatusBViewModel}" >
<vw:StatusBView />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
现在我想根据要包含的数据类型显示一个包含其内容的弹出窗口:
<Popup AllowsTransparency="True"
IsOpen="{Binding IsPopupOpen,Mode=OneWay}"
PlacementTarget="{Binding PopupPlacementElement}" Placement="{Binding PopupPlacementMode}"
HorizontalOffset="{Binding PopupHOffset}" VerticalOffset="{Binding PopupVOffset}">
<ContentPresenter x:Name="StuckHere" Content="{Binding PopupData}" />
</Popup>
Run Code Online (Sandbox Code Playgroud)
StuckHere上的ContentTemplateSelector不起作用,因为它只被评估一次,当PopupData发生更改时,不会重新选择模板.
我可以找到的所有示例都依赖于默认的datatemplate,我不能在我的情况下使用,因为我已经为主视图提供了默认的DataTemplate,我只希望这个不同的模板影响我的弹出窗口.
有线索吗?