将鼠标悬停在列表中的某个项目上时,如何将另一个元素的属性设置为列表项的DataContext?
我正在尝试创建一个区域,我可以在其中显示鼠标光标下方当前项目的预览。我可以使用代码隐藏来实现这一点,但我想找到一种可以使用EventSetters / Binding / Triggers / AttachedProperties或任何其他方法的替代方法。
目标是在更松散耦合的场景中应用解决方案,其中ListView控件可以位于单独的资源文件中,并且PreviewControl可能由多个ListView共享以显示不同类型的预览。
以下代码可以使用,但需要代码隐藏:
<Window x:Class="Previewer.PreviewWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="PreviewWindow" Height="300" Width="300">
<Window.Resources>
<x:Array x:Key="Data" Type="sys:String">
<sys:String>First</sys:String>
<sys:String>Second</sys:String>
</x:Array>
<CollectionViewSource x:Key="DataSource" Source="{StaticResource Data}"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" x:Name="PreviewControl"/>
<ListView Grid.Row="1" ItemsSource="{Binding Source={StaticResource DataSource}}">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<EventSetter Event="MouseEnter" Handler="ListViewItem_MouseEnter"/>
<EventSetter Event="MouseLeave" Handler="ListViewItem_MouseLeave"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</Grid>
目前的代码隐藏技巧:
public partial class PreviewWindow : Window
{
public PreviewWindow()
{
InitializeComponent();
}
private void ListViewItem_MouseEnter(object sender, MouseEventArgs e)
{
var listViewItem = (ListViewItem)sender;
PreviewControl.Content= listViewItem.DataContext;
}
private void ListViewItem_MouseLeave(object sender, MouseEventArgs e)
{
var listViewItem = (ListViewItem)sender;
PreviewControl.Content= null;
}
}
答案 0 :(得分:1)
解决方案1 (不是通用但简单且有效):
将已实现的逻辑封装到自定义控件中,该控件具有新的依赖项属性(typeof(object)),表示HoveredItemContext。在自定义列表视图的构造函数中,您可以创建ContainerStyle并附加事件。在此EventHandlers中设置HoveredItemContext,您可以从外部绑定到此属性:
<ContentControl Grid.Row="0" x:Name="PreviewControl"
Content="{Binding ElementName=MyListView, Path=HoveredItemContext}"/>
<local:MyListView Grid.Row="1" x:Name="MyListView"
ItemsSource="{Binding Source={StaticResource DataSource}}" />
这里的自定义控件(有效):
public class MyListView : ListView
{
public static readonly DependencyProperty HoveredItemContextProperty = DependencyProperty.Register(
"HoveredItemContext",
typeof(object),
typeof(MyListView),
new PropertyMetadata(null));
public object HoveredItemContext
{
get { return GetValue(HoveredItemContextProperty); }
set { SetValue(HoveredItemContextProperty, value); }
}
public MyListView()
{
this.ItemContainerStyle = new Style()
{
TargetType = typeof(ListViewItem),
};
this.ItemContainerStyle.Setters.Add(new EventSetter(ListViewItem.MouseEnterEvent,
(MouseEventHandler)((s, e) =>
{
this.HoveredItemContext = (s as ListViewItem).DataContext;
})));
this.ItemContainerStyle.Setters.Add(new EventSetter(ListViewItem.MouseLeaveEvent,
(MouseEventHandler)((s, e) =>
{
this.HoveredItemContext = null;
})));
}
}
解决方案2 (更通用):
我仍在研究类似的问题,但还没有完成;)如果我把它结束,我会在这里发布。