我是WPF的新手,但我设法慢慢推进编写我的第一个认真的项目。我不确定我是否使用了正确的条款,所以请耐心等待。
我实现了一组ItemsControl(用户控件)。项目来源是项目的集合。每个项目都包含很多数据,包括它自己的ID。当鼠标悬停在这组ItemsControl外的另一个控件上时,我希望用户控件更改属性。 为了使事情复杂化,另一个控件也是另一个 ItemsControl集的一个元素。
我已经设法将hovered-over控件的ID存储在顶级属性中(在顶部的DataContext中),但是我找不到从DataTemplate中隐藏的元素内部绑定它的方法。 / p>
在此示例中,用户将鼠标悬停在 14 频道上 - 因此,底部轴 X 和 Z 应突出显示(我随意选择它们) - 根据存储在数据库中的数据)。
我很感激任何想法。我们非常欢迎这些例子!
答案 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
属性。如果是这种情况,那么您应该能够使用EventTrigger
和ChangePropertyAction
(在FindAncestor
或ElementName
绑定中)来更新它。像这样:
<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>