TreeViewItem для уведомления ViewModel при наведении курсора

В настоящее время я использую код из этого сообщения в блоге чтобы мой TreeView выделял те элементы, которые в данный момент наведены мышью. Это работает по назначению, однако теперь я хочу, чтобы TreeViewItems уведомлял свои прикрепленные ViewModels, когда они зависают / не зависают.

Однако я не понимаю, как мне этого добиться. Соответствующий код XAML выглядит следующим образом:

<Style TargetType="{x:Type TreeViewItem}">
    <Style.Triggers>
        <Trigger Property="Controls:TreeViewHelper.IsMouseDirectlyOverItem" Value="True">
            <Setter Property="Background" Value="Green" />
        </Trigger>
    </Stile.Triggers>
</Style>

Как я могу связать свойство из моей модели ViewModel с именем TreeNodeModel.IsHovered с TreeViewItem (или, возможно, с прикрепленным свойством зависимости IsMouseDirectlyOverItem), чтобы я мог реагировать на эти изменения из моего кода?

Все примеры, которые я нашел через Google, объясняли только, как установить цвет фона. Заранее благодарим за то, что уделили время, вероятно, тривиальному ответу.


person Simon    schedule 19.04.2013    source источник


Ответы (1)


В вашем Style попробуйте добавить Setter, который связывает IsMouseDirectlyOverItem с IsHovered, и используйте режим привязки OneWayToSource, чтобы подтолкнуть значение правильным образом:

<Style TargetType="{x:Type TreeViewItem}">
    <Setter Property="Controls:TreeViewHelper.IsMouseDirectlyOverItem"
            Value="{Binding Path=IsHovered, Mode=OneWayToSource}" />

    <Style.Triggers>
        ...
</Style>

РЕДАКТИРОВАТЬ: Поскольку IsMouseDirectlyOver доступен только для чтения, а DP, доступные только для чтения, не могут быть целью каких-либо привязок, PushBinding Фредрика Хедблада может быть возможным обходным решением: Привязка OneWayToSource для свойства зависимости только для чтения

<Style TargetType="{x:Type TreeViewItem}">
    <Setter Property="pb:PushBindingManager.StylePushBindings">
        <Setter.Value>
            <pb:PushBindingCollection>
                <pb:PushBinding TargetDependencyProperty="Controls:TreeViewHelper.IsMouseDirectlyOverItem" 
                                Path="IsHovered" />
            </pb:PushBindingCollection>
        </Setter.Value>
    </Setter>

    <Style.Triggers>
        ...
</Style>
person Sphinxxx    schedule 19.04.2013
comment
Я пробовал это, но получаю исключение при запуске программы. Дополнительная информация: объект Setter не может указывать значение для свойства IsMouseDirectlyOverItem, доступного только для чтения. Исключение имеет смысл, поскольку свойство действительно доступно только для чтения. Менять его на чтение / запись мне не кажется логичным. Есть ли другой способ уведомить мою модель просмотра? - person Simon; 20.04.2013
comment
Хм .. Если вы не хотите изменять IsMouseDirectlyOver на чтение / запись, этот ответ на связанный вопрос SO может иметь для вас обходной путь: Привязка OneWayToSource из свойства только для чтения в Xaml - person Sphinxxx; 20.04.2013
comment
..а также прочтите раздел «Обновление: использование PushBinding в стиле» в сопроводительном сообщении блога Hedblad: Привязка OneWayToSource для свойства зависимости только для чтения. - person Sphinxxx; 20.04.2013
comment
Мне потребовалось некоторое время, чтобы попробовать это. Однако я все еще не могу заставить его работать. Я думаю, что это сводится к тому факту, что я не могу указать присоединенное свойство только для чтения (которым является вышеупомянутый IsMouseDirectlyOverItem) в качестве TargetProperty в PushBinding, а также я не могу указать привязку в пути, который, как я подозреваю, мне нужно сделать, так как я хочу, чтобы он уведомлял мою модель представления. Думаю, сейчас я буду использовать программный код. Но спасибо за вашу помощь. - person Simon; 23.04.2013
comment
Насколько я понимаю, вам нужно просто установить Path="IsHovered", но TargetProperty все равно доставит вам неприятности. Читая код PushBinding, я вижу, что TargetProperty - это просто строка, поэтому указание присоединенного свойства не сработает сразу. Но я вижу, что PushBinding также имеет TargetDependencyProperty, который можно использовать вместо TargetProperty. Если вы хотите попробовать еще раз, возможно, что-то вроде этого сработает: <pb:PushBinding TargetDependencyProperty="Controls:TreeViewHelper.IsMouseDirectlyOverItem" Path="IsHovered" /> - person Sphinxxx; 24.04.2013
comment
Спасибо за вашу настойчивость. Ваши предложения работают, поскольку он компилируется, однако я не могу найти правильный раздел xaml, в который я должен поместить этот код. В настоящее время я помещаю привязку push в раздел ItemTemplate своего древовидного представления. У меня не было ошибок привязки, и, похоже, это сработало, поскольку свойство IsHovered моих моделей вызывается, но только один раз с false. Впоследствии при наведении указателя мыши на элемент присоединенный DP изменяет свое значение, однако IsHovered больше не вызывается. Я не понимаю, в чем может быть причина такого поведения. - person Simon; 24.04.2013
comment
Его определенно не должно быть не в ItemTemplate, потому что ItemTemplate на самом деле ничего не знает о TreeViewItem - только связанные данные (ViewModel). Он должен находиться в TreeViewItem Style (там, где вы пробовали триггер). Я обновил свой ответ предлагаемым решением. - person Sphinxxx; 24.04.2013
comment
Я подозревал, что это так, но мне было трудно поместить это в раздел стилей. Ваше решение прекрасно работает, большое вам спасибо. - person Simon; 24.04.2013