查找以 UserControl 作为内容的 ListBoxItem 的实际范围
Finding the actual extents of a ListBoxItem with UserControl as content
我正在尝试查找 ListBox 中 UI 元素的范围。我为此使用 WPF/c#。
代码大致如下:
ObservableCollection<SomeUserControl> TheCollection = new ObservableCollection<SomeUserControl>();
// setup
ListBox lb = new ListBox();
// code omitted here that setup the listbox with 2 columns
lb.ItemsSource = TheCollection;
// code omitted here that populates TheCollection with UI elements
然后我注册了一个鼠标事件,我想知道特定点何时被列表框中的特定元素所包围。为此,我有以下方法可以做到:
UIElement GetObjectHit(Point P) {
if (!lb.IsVisible) return null;
foreach(var i in TheCollection) {
FrameworkElement item = i as FrameworkElement;
if (item == null || !item.IsVisible)
continue;
Point P00 = item.TranslatePoint(new Point(0,0), lb);
Point P11 = item.TranslatePoint(new Point(item.ActualWidth, item.ActualHeight), lb);
if (IsBounded(P, P00, P11)
return item;
}
return null;
}
UIElement GetObjectHit(MouseButtonEventArgs e) {
return GetObjectHit(e.GetPosition(lb));
}
这很好用,但有一个例外...
我拥有的不同用户控件具有不同的大小,然后 ListBox 会将每个项目扩展到列表中当前的最大元素大小,然后将列表中较小的 UserControl 居中。
所以问题是什么?
好吧,当位置在 ListBoxItem 区域内部但 UserControl 区域外部的白色区域时,上面的代码无法找到交集。
所以我的问题如下:
我是否必须首先进行单独的循环以获得每个 UI 元素的最大扩展,或者是否有任何方法可以获取 ListBox 中 ListBoxItem 的当前范围(即使 UserControl 范围较小)?
在极少数情况下,如果有人需要这个问题的答案,我设法让它按如下方式工作:
UIElement GetObjectHit(Point P) {
if (!lb.IsVisible) return null;
foreach(var i in TheCollection) {
var item = i as SomeUserControl;
ListBoxItem lbi = lb.ContainerFromElement(item) as ListBoxItem;
if (lbi == null || !lbi.IsVisible)
continue;
Point P00 = lbi.TranslatePoint(new Point(0,0), lb);
Point P11 = lbi.TranslatePoint(new Point(lbi.ActualWidth, lbi.ActualHeight), lb);
if (IsBounded(P, P00, P11)
return i;
}
return null;
}
我正在尝试查找 ListBox 中 UI 元素的范围。我为此使用 WPF/c#。 代码大致如下:
ObservableCollection<SomeUserControl> TheCollection = new ObservableCollection<SomeUserControl>();
// setup
ListBox lb = new ListBox();
// code omitted here that setup the listbox with 2 columns
lb.ItemsSource = TheCollection;
// code omitted here that populates TheCollection with UI elements
然后我注册了一个鼠标事件,我想知道特定点何时被列表框中的特定元素所包围。为此,我有以下方法可以做到:
UIElement GetObjectHit(Point P) {
if (!lb.IsVisible) return null;
foreach(var i in TheCollection) {
FrameworkElement item = i as FrameworkElement;
if (item == null || !item.IsVisible)
continue;
Point P00 = item.TranslatePoint(new Point(0,0), lb);
Point P11 = item.TranslatePoint(new Point(item.ActualWidth, item.ActualHeight), lb);
if (IsBounded(P, P00, P11)
return item;
}
return null;
}
UIElement GetObjectHit(MouseButtonEventArgs e) {
return GetObjectHit(e.GetPosition(lb));
}
这很好用,但有一个例外... 我拥有的不同用户控件具有不同的大小,然后 ListBox 会将每个项目扩展到列表中当前的最大元素大小,然后将列表中较小的 UserControl 居中。
所以问题是什么? 好吧,当位置在 ListBoxItem 区域内部但 UserControl 区域外部的白色区域时,上面的代码无法找到交集。
所以我的问题如下: 我是否必须首先进行单独的循环以获得每个 UI 元素的最大扩展,或者是否有任何方法可以获取 ListBox 中 ListBoxItem 的当前范围(即使 UserControl 范围较小)?
在极少数情况下,如果有人需要这个问题的答案,我设法让它按如下方式工作:
UIElement GetObjectHit(Point P) {
if (!lb.IsVisible) return null;
foreach(var i in TheCollection) {
var item = i as SomeUserControl;
ListBoxItem lbi = lb.ContainerFromElement(item) as ListBoxItem;
if (lbi == null || !lbi.IsVisible)
continue;
Point P00 = lbi.TranslatePoint(new Point(0,0), lb);
Point P11 = lbi.TranslatePoint(new Point(lbi.ActualWidth, lbi.ActualHeight), lb);
if (IsBounded(P, P00, P11)
return i;
}
return null;
}