gpt4 book ai didi

wpf - 是否有一种通用方法可以将鼠标下方的 ItemContainer 的 DataContext 设置为其他控件的属性?

转载 作者:行者123 更新时间:2023-12-02 04:14:37 25 4
gpt4 key购买 nike

将鼠标悬停在列表中的某个项目上时,如何将另一个元素上的属性设置为列表项的 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;
}
}

最佳答案

解决方案1(不是那么通用但简单且有效):

将你已经实现的逻辑封装到一个自定义控件中,它有一个新的依赖属性(typeof(object)),它代表了HoveredItemContext。在自定义 ListView 的构造函数中,您可以创建 ContainerStyle 并附加事件。在这个 EventHandlers 中设置 HoveredItemContext,你可以从外部绑定(bind)到这个属性:

 <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(更通用):

我仍在研究类似的问题,但尚未完成;)如果我结束它,我将在此处发布。

关于wpf - 是否有一种通用方法可以将鼠标下方的 ItemContainer 的 DataContext 设置为其他控件的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3434568/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com