WPF .NET Core如何查找依赖属性变更事件的触发源对象
现有实现的核心问题
你当前的写法存在两个直接导致需求无法实现的缺陷:
- 循环内反复给同一个
ItemMouseOverProperty设置绑定,每一次新绑定都会覆盖上一次的配置,最终只有最后一个ListViewItem的IsMouseOver状态能同步到该依赖属性,其余项悬停根本不会触发变更回调 - 依赖属性的变更回调仅能拿到属性所属的宿主对象(当前场景下就是MainWindow实例)和属性值的前后变化,不会携带绑定源对象的信息,天然无法直接拿到触发变更的
ListViewItem
首选解决方案:直接注册鼠标事件
不需要绕依赖属性绑定的逻辑,直接给每个生成的ListViewItem注册悬停相关事件即可,sender参数就是触发事件的目标项:
private void ProcessListItems() { foreach (var item in settings.items) { var i = lst.ItemContainerGenerator.ContainerFromItem(item) as ListViewItem; if (i == null) continue; // 注册悬停进入、离开事件,按需添加即可 i.MouseEnter += OnListViewItemHover; i.MouseLeave += OnListViewItemHoverEnd; } } private void OnListViewItemHover(object sender, MouseEventArgs e) { // 转换sender即可拿到触发悬停的ListViewItem实例 var hoverItem = (ListViewItem)sender; // 如需获取该项绑定的业务数据,直接取DataContext即可 var businessData = hoverItem.DataContext; // 此处写入你要执行的悬停逻辑 } private void OnListViewItemHoverEnd(object sender, MouseEventArgs e) { var leaveItem = (ListViewItem)sender; // 此处写入悬停结束的逻辑 }
若必须使用依赖属性绑定的替代方案
如果你的场景确实需要通过绑定实现,可以使用附加属性封装逻辑,附加属性的变更回调可以直接拿到关联的ListViewItem实例:
public static class ListViewItemHoverExtensions { public static readonly DependencyProperty IsHoverEnabledProperty = DependencyProperty.RegisterAttached( "IsHoverEnabled", typeof(bool), typeof(ListViewItemHoverExtensions), new PropertyMetadata(false, OnIsHoverEnabledChanged)); private static void OnIsHoverEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { // d就是当前绑定的ListViewItem实例 if (d is not ListViewItem item) return; if ((bool)e.NewValue) { // 悬停生效逻辑 } else { // 悬停失效逻辑 } } public static void SetIsHoverEnabled(DependencyObject element, bool value) { element.SetValue(IsHoverEnabledProperty, value); } public static bool GetIsHoverEnabled(DependencyObject element) { return (bool)element.GetValue(IsHoverEnabledProperty); } } // 绑定逻辑调整为 private void ProcessListItems() { foreach (var item in settings.items) { var i = lst.ItemContainerGenerator.ContainerFromItem(item) as ListViewItem; if (i == null) continue; BindingOperations.SetBinding(i, ListViewItemHoverExtensions.IsHoverEnabledProperty, new Binding { Path = new PropertyPath(ListViewItem.IsMouseOverProperty), Source = i }); } }
内容的提问来源于stack exchange,提问作者Boppity Bop
相关产品推荐
相关产品推荐

