我想在一个ListBox中找到一个UI元素的extents。我使用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会将每个项目扩展到当前列表中的最大元素尺寸,然后将列表中较小的UserControls居中。
那么问题出在哪里呢?嗯,当位置在白色区域内,也就是ListBoxItem区域内,但在UserControl区域外时,上面的代码无法找到交集。
所以我的问题如下:我是否必须先做一个单独的循环来获取每个UI元素的最大extends,或者有什么方法可以获取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;
}