Обратный DataTrigger? - PullRequest
       12

Обратный DataTrigger?

1 голос
/ 11 февраля 2009

Я могу активировать настройки свойств в своем шаблоне ListBoxItem на основе свойств базового объекта данных, используя DataTrigger с чем-то вроде этого

<DataTrigger Binding="{Binding Path=IsMouseOver}" Value="true">
  <Setter TargetName="ItemText" Property="TextBlock.TextDecorations" Value="Underline">
  </Setter>
</DataTrigger>

Но что, если я хочу сделать обратное? Я имею в виду установить значение свойства базового объекта данных на основе значения свойства моего ListBoxItem. Что-то вроде:

<Trigger Property="IsMouseOver" Value="True">
  <Setter Property="MyClass.IsHilited" Value="True"></Setter>
</Trigger>

Существует ли механизм для чего-то подобного или какой рекомендуемый подход для решения подобных ситуаций?

Спасибо.

Ответы [ 2 ]

2 голосов
/ 11 февраля 2009

Я думаю, что вы могли бы использовать EventSetter , чтобы делать в XAML то, что Джош Дж предложил в коде. Может быть, создать один для событий MouseEnter и MouseLeave и соответствующим образом оформить элемент управления для каждого?

Обновление : Вы можете настроить события следующим образом:

<ListBox>
    <ListBox.Resources>
        <Style TargetType="{x:Type ListBoxItem}">
            <EventSetter Event="MouseEnter" Handler="OnListBoxItemMouseEnter" />
            <EventSetter Event="MouseLeave" Handler="OnListBoxItemMouseLeave" />
        </Style>
    </ListBox.Resources>
    <ListBoxItem>Item 1</ListBoxItem>
    <ListBoxItem>Item 2</ListBoxItem>
    <ListBoxItem>Item 3</ListBoxItem>
    <ListBoxItem>Item 4</ListBoxItem>
    <ListBoxItem>Item 5</ListBoxItem>
</ListBox>

Стиль регистрирует события MouseEnter и MouseLeave для всех ListBoxItems, определенных в этом ListBox.

А затем в вашем коде за файлом:

private void OnListBoxItemMouseEnter(object sender, RoutedEventArgs e)
{
    ListBoxItem lvi = sender as ListBoxItem;
    if(null != lvi)
    {
        lvi.Foreground = new SolidColorBrush(Colors.Red);
    }
}

private void OnListBoxItemMouseLeave(object sender, RoutedEventArgs e)
{
    ListBoxItem lvi = sender as ListBoxItem;
    if(null != lvi)
    {
        lvi.Foreground = new SolidColorBrush(Colors.Black);
    }
}

Эти обработчики устанавливают цвет текста ListBoxItem на красный, когда мышь находится над элементом, и обратно на черный, когда мышь покидает его.

1 голос
/ 11 февраля 2009

Триггеры WPF предназначены для создания визуальных изменений. Установочные объекты внутри триггеров вызывают изменения свойств в элементе управления.

Если вы хотите ответить на событие (например, EventTrigger), вы всегда можете просто подписаться на событие в коде и затем установить свойство data в обработчике.

Таким способом вы можете использовать MouseEnter и MouseLeave. Например:

listBox.MouseEnter += listBox_MouseEnter;
listBox.MouseLeave += listBox_MouseLeave;

void listBox_MouseEnter(object sender, MouseEventArgs e)
{
    listBox.MyClass.IsHilited = true;
}

void listBox_MouseLeave(object sender, MouseEventArgs e)
{
    listBox.MyClass.IsHilited = false;
}

Некоторые свойства элемента управления, к которым можно привязать свойство объекта данных, например:

Binding myBind = new Binding("IsHilited");
myBind.Source = listBox.DataContext;
listBox.SetBinding(listBox.IsEnabled, myBind);

Однако нельзя использовать IsMouseOver в привязке.

Если вы создаете пользовательский элемент управления, вы можете иметь еще большую гибкость для встраивания подобной привязки в элемент управления. Вы можете создать собственное свойство зависимости и синхронизировать его со свойством данных в обработчике DependencyPropertyChanged. Затем вы можете установить это свойство зависимости с помощью триггера WPF.

Вот пример:

public static readonly DependencyProperty IsHilitedProperty =
    DependencyProperty.Register("IsHilited", typeof(bool), typeof(CustomListBox),
    new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnIsHilitedChanged)));

public double IsHilited
{
    get
    {
        return (bool)GetValue(IsHilitedProperty);
    }
    set
    {
        SetValue(IsHilitedProperty, value);
    }
}


private static void OnIsHilitedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
    CustomListBox box = obj as CustomListBox;

    if (box != null)
        box.MyClass.IsHilited = box.IsHilited;

   // Or:
   // Class myClass = box.DataContext as Class;
   // myClass.IsHilited = box.isHilited;
}

<Trigger Property="IsMouseOver" Value="True">
    <Setter Property="IsHilited" Value="True"/>
</Trigger>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...