上图中红色框区域是一个自定义的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);