WPF中获取指定坐标依赖对象数据项

上图中红色框区域是一个自定义的ListBox控件,需要实现的功能是,点击红框区域中某项时,获取当前选中项的数据项

控件的MouseDown事件部分代码为:

 1 var x = TreeHelper.FindPointProperty<ListBoxItem>(this, scrollStartPoint);
 2  if (x != null)
 3 {
 4      x.IsSelected = true;
 5      ItemsControl tiles = ItemsControl.ItemsControlFromItemContainer(x);
 6      var data = tiles.ItemContainerGenerator.ItemFromContainer(x);
 7      if (data != null && data is DummyTileData)
 8      {
 9          tile = (DummyTileData)data;
10      }
11 }

TreeHelper部分代码:对树结构进行操作,获取指定类型(ListBoxItem)元素

 1 /// <summary>
 2 /// 找到一个父一个给定的项目视觉上的树。
 3 /// </summary>
 4 /// <typeparam name="T"></typeparam>
 5 /// <param name="child"></param>
 6 /// <returns></returns>
 7 public static T TryFindParent<T>(this DependencyObject child) where T : DependencyObject
 8 {
 9 
10    DependencyObject parentObject = GetParentObject(child);
11    if (parentObject == null) return null;
12    T parent = parentObject as T;
13    if (parent != null)
14    {
15         return parent;
16    }
17    else
18    {
19         return TryFindParent<T>(parentObject);
20    }
21 }
22 
23 public static DependencyObject GetParentObject(this DependencyObject child)
24 {
25     if (child == null) return null;
26 
27     //判断child为ContentElement
28     ContentElement contentElement = child as ContentElement;
29     if (contentElement != null)
30     {
31         DependencyObject parent = ContentOperations.GetParent(contentElement);
32         if (parent != null) return parent;
33 
34         FrameworkContentElement fce = contentElement as FrameworkContentElement;
35         return fce != null ? fce.Parent : null;
36     }
37 
38     //也尝试寻找父框架元素(如DockPanel中,等)
39    FrameworkElement frameworkElement = child as FrameworkElement;
40     if (frameworkElement != null)
41     {
42         DependencyObject parent = frameworkElement.Parent;
43         if (parent != null) return parent;
44     }
45 
46     //如果child不是一个ContentElement/ FrameworkElement,运行VisualTreeHelper
47     return VisualTreeHelper.GetParent(child);
48 }
49 
50 public static T FindPointProperty<T>(UIElement reference, Point point) where T : DependencyObject
51 {
52     DependencyObject element = reference.InputHitTest(point) as DependencyObject;
53 
54     if (element == null) return null;
55     else if (element is T) return (T)element;
56     else return TryFindParent<T>(element);
57 }

reference.InputHitTest(point) 返回指定坐标上的当前元素中的输入元素(相对于当前元素的源)。下图为点击ListBox控件时,鼠标点击坐标的获取到一个的输出元素 当前获取到的是Border元素

通过获取到的元素,依次查找类型为ListBoxItem 我们需要的对象

TreeHelper.FindPointProperty<ListBoxItem>(this, scrollStartPoint); 这段代码是发现对象当前坐标的ListBoxItem项

接下来有两个属性:

//返回拥有指定容器元素的 System.Windows.Controls.ItemsControl。参数:container:要为其返回 System.Windows.Controls.ItemsControl 的容器元素。返回: 拥有指定容器元素的 System.Windows.Controls.ItemsControl。

public static ItemsControl ItemsControlFromItemContainer(DependencyObject container);

ItemContainerGenerator类下面的:返回对应于指定生成的 System.Windows.UIElement 的项。参数: container:对应于要返回的项的 System.Windows.DependencyObject。

public object ItemFromContainer(DependencyObject container);

原文地址:https://www.cnblogs.com/raohuagang/p/3213471.html