以UserControl为内容,查找ListBoxItem的实际外延。

问题描述 投票:0回答:1

我想在一个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的范围更小)?

c# wpf listbox
1个回答
0
投票

如果有人需要答案的话,我设法让这个工作如下。

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.