WPF:根据ListBox项目大小动态更改ListBox的ItemTemplate

时间:2010-08-03 00:07:50

标签: wpf listbox datatemplate listboxitem

我需要根据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,一旦我将两个或更多项添加到绑定列表,数据模板就会按预期更改(从其他更改为默认值)。但是,如果我删除列表中包含两个以上项目的第一项,则整个列表框将变为空(我验证绑定列表是非空的)。删除两个项目列表中的第二个项目工作正常(即模板从默认更改为其他)。

为什么会发生这种情况?或许我采取了错误的方法来解决这个问题?

2 个答案:

答案 0 :(得分:2)

您可以使用数据触发器,或者您可以使用DataTemplateSelector Here是一篇展示基础知识的文章。并且here是将MSDN应用于项目控件(也是列表框)的MSDN

答案 1 :(得分:2)

我不能说出确切的问题或原因,但这是因为当计数为1且只有1时,DataTrigger正在设置模板。

你可以做3件事中的1件来解决这个问题,但我只推荐1件。

a)通过派生System.Windows.TriggerBase

实现您自己的DataTrigger

b)使用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'列表。