WPF:如何将ItemsControl.ItemTemplate中的MouseEnter事件绑定到此ItemsControl之外的元素

时间:2013-12-18 20:50:01

标签: wpf binding itemscontrol

我是WPF的新手,但我设法慢慢推进编写我的第一个认真的项目。我不确定我是否使用了正确的条款,所以请耐心等待。

我实现了一组ItemsControl(用户控件)。项目来源是项目的集合。每个项目都包含很多数据,包括它自己的ID。当鼠标悬停在这组ItemsControl外的另一个控件上时,我希望用户控件更改属性。 为了使事情复杂化,另一个控件也是另一个 ItemsControl集的一个元素。

我已经设法将hovered-over控件的ID存储在顶级属性中(在顶部的DataContext中),但是我找不到从DataTemplate中隐藏的元素内部绑定它的方法。 / p>

这是截图:

Selecting Channel 14

在此示例中,用户将鼠标悬停在 14 频道上 - 因此,底部轴 X Z 应突出显示(我随意选择它们) - 根据存储在数据库中的数据)。

我很感激任何想法。我们非常欢迎这些例子!

2 个答案:

答案 0 :(得分:2)

假设: 1)您正在使用MVVM设计模式。 2)ItemsControl中的每个项目都有一个基础ViewModel。

然后您需要做的是在视图中处理MouseEnter和MouseLeave事件,并让它们在视图模型中触发命令。然后让这些ViewModel更新其他ViewModel中的属性,让它们突出显示其他ItemsControl中的相应项。

<UserControl x:Class="ClassName"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
             xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4">
    <i:Interaction.Triggers>
        <!-- this will call the associated commands on your viewmodel when the mouse enters/leaves the corresponding view in your itemscontrol, from there you can create the viewmodel functionality you'd like-->
        <i:EventTrigger EventName="MouseEnter">
            <i:InvokeCommandAction Command="{Binding MouseEnterCommand}"/>
        </i:EventTrigger>
        <i:EventTrigger EventName="MouseLeave">
            <i:InvokeCommandAction Command="{Binding MouseLeaveCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>

    <Grid Height="10" Width="10">
        <!--the content of your usercontrol-->  
    </Grid>

</UserControl>

一旦你得到正确的命令通知你的viewmodel鼠标悬停在它上面(或离开它)。您可以管理视图模型的状态以创建您要查找的效果。

答案 1 :(得分:1)

我非常喜欢Blend SDK这样的东西。

由于您提到属性中有悬停ID设置,因此您可以从根级别的PropertyChangedTrigger开始。接下来,您可能希望调用命令(而不仅仅是方法),因为您的操作包含参数(ID)。请使用InvokeCommandAction。您可以在视图或视图模型上触发命令。如果要在视图上触发它,那么您可能希望使用ElementName作为绑定。

这是一个例子。

<UserControl>
    <i:Interaction.Triggers>
        <!-- When "SelectedID" changes, invoke the "SelectedIDChangedCommand" on the 
             element "AxesAndButtons".  Pass the value of "SelectedID" as the 
             command parameter -->
        <ei:PropertyChangedTrigger Binding="{Binding SelectedID}">
            <i:InvokeCommandAction CommandParameter="{Binding SelectedID}"
                Command="{Binding ElementName=AxesAndButtons,Path=SelectedIDChangedCommand}" />
        </ei:PropertyChangedTrigger>
    <i:Interaction.Triggers>

    <my:AxesAndButtonsControl x:Name="AxesAndButtons">
    </my:AxesAndButtonsControl>
</UserControl>

我假设被更改的ID属性称为“SelectedID”(并且是根数据上下文的属性)。此外,您的目标用户控件具有定义的ICommand“SelectedIDChangedCommand”依赖项属性,用于执行更新。就是这样:

public class AxesAndButtonsControl : UserControl
{
    public static readonly DependencyProperty SelectedIDChangedCommand = DependencyProperty.Register("SelectedIDChangedCommand", 
        typeof(ICommand), 
        typeof(AxesAndButtonsControl),
        new PropertyMetadata(null));

    public AxesAndButtonsControl()
    {
        SelectedIDChangedCommand = new DelegateCommand(id => {
            // highlight "X" and "Z" or whatever
        });
    }
}

编辑我刚注意到您可能还没有绑定MouseOver事件来更新SelectedID属性。如果是这种情况,那么您应该能够使用EventTriggerChangePropertyAction(在FindAncestorElementName绑定中)来更新它。像这样:

<DataTemplate>
    <Grid>
        <i:Interaction.Triggers>
            <!-- When "MouseEnter" gets triggered, set the property "SelectedID" on the 
                 data context of the closest "UserControl" parent to the value of "ItemID" 
                 in the current data context -->
            <i:EventTrigger EventName="MouseEnter">
                <ei:ChangePropertyAction Value="{Binding ItemID}"
                    TargetObject="{Binding RelativeSource={RelativeSource AncestorType=UserControl},Path=DataContext}"
                    PropertyName="SelectedID" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Grid>
</DataTemplate>