WPF: динамически изменять ItemTemplate ListBox на основе размера элементов ListBox - PullRequest
0 голосов
/ 03 августа 2010

Мне нужно изменить DataTemplate моего ListBox, основываясь на количестве элементов ListBox. Я придумал следующий 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 ]

2 голосов
/ 18 января 2011

Я не могу сказать точную проблему или причину, но это потому, что DataTrigger устанавливает шаблон, когда счетчик равен 1 и только 1.

Вы можете сделать 1 из 3 вещей, чтобы решить эту проблему, но я бы порекомендовал только 1.

a) Реализуйте свой собственный DataTrigger, выведя из System.Windows.TriggerBase

b) Используйте реализацию System.Windows.Data.IValueConverter , которая преобразует из ItemsControl.Items.Count в DataTemplate. Получите шаблоны, поместив элемент в область ваших ресурсов как Binding.ConverterParameter, приведя их к FrameWorkElement и вызвав FrameWorkElement.FindResource ().

C) Это моя рекомендация, напишите свой DataTemplateSelector , чтобы выполнить грубую работу. Этот механизм специально нацелен на функциональность, которую вы достигаете. Недавно я написал один, который будет выбирать DataTemplate на основе типа исходного объекта, не требуя DataTemplate без набора x: Key. Используя Свойства в селекторе шаблонов, вы можете передать DataTemplates в DataTemplateSelector с помощью XAML, удалив этот список FindResource «todo».

2 голосов
/ 03 августа 2010

вы можете использовать триггеры данных, или вы можете использовать DataTemplateSelector Здесь - статья, которая показывает основы.и здесь - это MSDN, применяемый к элементу управления элементами (а также к списку)

...