查找以 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;
}