настраиваемый шаблонный триггер привязки списка - PullRequest
1 голос
/ 03 октября 2011

У меня есть класс, унаследованный от ListBox, и пользовательский ControlTemplate для ListBoxItems. Я хочу изменить фон ListBoxItems, если условие истинно. Я пытался использовать DataTrigger для этого. Я не хочу проверять условие в объекте контекста ListBoxItems, я хочу проверить его в унаследованном классе ListBox.

Вопрос в том, как связать в ControlTemplate Trigger свойство ListBox, когда ему нужно определить правильное значение для каждого ListBoxItem во время выполнения?

    <Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border Name="bd">
                        <TextBlock Name="lbl" Text="{Binding Path=DataChar}" FontWeight="ExtraBold" FontSize="15" Margin="5"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding RelativeSource={ RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}, Path=IsSymbolExists}" Value="True">
                            <Setter TargetName="bd" Property="Background" Value="Yellow" />
                        </DataTrigger>
                    </ControlTemplate.Triggers>
                 </ControlTemplate>
             </Setter.Value>
         </Setter>
    </Style>


public class CustomListBox : ListBox
{
 ...
     public bool IsSymbolExists
     {
          if(/*condition is true for the ListBoxItem*/)
              return true;
          return false;
     }
}

1 Ответ

1 голос
/ 03 октября 2011

Хорошо, сначала несколько предложений ...

Имеет ли ваш пользовательский элемент управления listbox только новые свойства (IsSymbolExists и т. Д.) И никакого реального поведения. Если так, пожалуйста, объявите их как Прикрепленные свойства

Во-вторых, когда это значение IsSymbolExists становится истинным для ListBox ALL , его элементы будут выделены по отдельности желтой рамкой. Это не похоже на продуманное поведение пользовательского интерфейса. Извините, если это кажется вам немного грубым!

Кроме того, с точки зрения связывания свойство DataChar выглядит как свойство, основанное на контексте данных, т.е. происходит из некоторой модели. Если это так, то его привязка должна выполняться через ItemTemplate в ListBox, а не в TextBlock в ControlTemplate из ListBoxItem. И по той же причине DataTrigger не будет работать правильно в ControlTemplate.

Они будут работать правильно в ItemTemplate.

Итак, подведем итог, ваш код должен быть исправлен следующим образом ...

  1. Вы можете избавиться от CustomListBox. Создайте логическое присоединенное свойство с именем MyListBoxBehavior.IsSymbolExists. Прикрепите его к вашему ListBox.

  2. Вы должны избавиться от ListBoxItem ControlTemplate.

В ListBox возьмите helpm из этого ... (этот код не скомпилируется как есть): -)

    <ListBox local:MyListBoxBehavior.IsSymbolExists="{Binding WhateverBoolean}"
             ItemsSource="{Binding WhateverCollection}">
        <ListBox.ItemTemplate>
           <DataTemplate>
              <Border>
               <Border.Style>
                  <Style TargetType="{x:Type Border}">
                      <Style.Triggers>
                         <DataTrigger
                                Binding="{Binding
                                            RelativeSource={RelativeSource
                                               Mode=FindAncestor,
                                                 AncestorType={x:Type ListBox}},
                                        Path=local:MyListBoxBehavior.IsSymbolExists}"
                                Value="True">
                             <Setter Property="Background" Value="Yellow" />
                         </DataTrigger>
                      </Style.Triggers> 
                   </Style>
                </Border.Style> 
                <TextBlock Name="lbl"
                           Text="{Binding Path=DataChar}"
                           FontWeight="ExtraBold"
                           FontSize="15"
                           Margin="5"/>
              </Border>
           </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

Надеюсь, это поможет.

...