我需要根据ListBox项目计数更改ListBox的DataTemplate。我想出了以下XAML:
<Window.Resources>
<DataTemplate x:Key="DefaultTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Text}"/>
<TextBlock Text="default template" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="OtherTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Text}"/>
<TextBlock Text="other template" />
</StackPanel>
</DataTemplate>
</Window.Resources>
<ListBox Name="listBox1" ItemsSource="{Binding Path=Items}">
<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
<Setter Property="ItemTemplate" Value="{StaticResource DefaultTemplate}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Items.Count}" Value="1">
<Setter Property="ItemTemplate" Value="{StaticResource OtherTemplate}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.Style>
</ListBox>
使用上面的XAML,一旦我将两个或更多项添加到绑定列表,数据模板就会按预期更改(从其他更改为默认值)。但是,如果我删除列表中包含两个以上项目的第一项,则整个列表框将变为空(我验证绑定列表是非空的)。删除两个项目列表中的第二个项目工作正常(即模板从默认更改为其他)。
为什么会发生这种情况?或许我采取了错误的方法来解决这个问题?
答案 0 :(得分:2)
答案 1 :(得分:2)
我不能说出确切的问题或原因,但这是因为当计数为1且只有1时,DataTrigger正在设置模板。
你可以做3件事中的1件来解决这个问题,但我只推荐1件。
a)通过派生System.Windows.TriggerBase
实现您自己的DataTriggerb)使用System.Windows.Data.IValueConverter的实现,它将ItemsControl.Items.Count转换为DataTemplate。通过将元素放在资源范围内作为Binding.ConverterParameter检索模板,将它们转换为FrameWorkElement并调用FrameWorkElement.FindResource()。
C)这是我的建议,写下你自己的DataTemplateSelector来做咕噜咕噜的工作。此机制专门针对您实现的功能。我最近写了一个将根据源对象的类型选择一个DataTemplate,而不需要没有x:Key集的DataTemplate。使用模板选择器上的Properties,您可以使用XAML将DataTemplates传递到DataTemplateSelector,删除FindResource代码'todo'列表。