如何仅通过其数据绑定 class 从 ListBoxItem 访问按钮/标签?

How I can get access to a button / label from a ListBoxItem with just its databinding class?

我目前有一个绑定到列表框项的 class 对象。在我以前通过单击按钮并访问其父项来获取 ListBoxItem 中的其他对象之前,但现在我需要在不单击按钮或标签的情况下收集对象,只需通过其 class.

我试图收集 ListBoxItem 及其索引和 class 绑定,但它们都给了我一个 null 值:

ObservableCollection<ClassBinding> classList = new ObservableCollection<ClassBinding>();
... adding items here to the collection;
listBox.ItemsSource = classList;
ListBoxItem lbi = (ListBoxItem)listBox.ItemContainerGenerator.ContainerFromIndex(index);

是否有另一种方法来访问列表框项,以便稍后使用函数 FindName(...) 收集其他对象?

调试:

TextBlock delay = lbi.FindName("lblDelay") as TextBlock;

错误:

Output: Exception thrown: 'System.InvalidOperationException' in WindowsBase.dll

一个ListBox是默认虚拟化的,见Displaying large data sets

Typically, you do not have to display all the items at the same time; instead you display a subset, and the user scrolls through the list. In this case, it makes sense to use UI virtualization, which means the item container generation and associated layout computation for an item is deferred until the item is visible.

换句话说,你得到 null,因为有问题的 ListBoxItem 尚未可见和实现。解决这个问题的唯一可靠方法是禁用虚拟化以强制实例化所有项目。尽管您随后可以访问每个项目,但这可能会导致大型集合的性能不佳,因为在加载 ListBox 时会加载所有项目,并且所有项目都保存在内存中,这会增加内存占用。

<ListBox x:Name="listBox" VirtualizingStackPanel.IsVirtualizing="False">

访问子控件,例如在数据模板中按名称 FindName(...)ItemsControl 中不起作用,例如 ListBox。您必须遍历可视化树才能获得控件,请参阅:

  • How can I find WPF controls by name or type?.

一般来说,直接在项目控件中处理控件并不是一个好主意。使用数据绑定要容易得多,因为您不直接访问容器和虚拟化,因此不会有任何问题。此外,您的代码将得到简化,您无需假设一个可视化结构。

更多关于该主题的信息和示例,您可以参考:

为了为此找到另一个 solution/idea,我想到了可以添加到 类 中的 INotifyPropertyChanged,因此无需从列表框中删除 ItemsSource,只需挂钩程序加载时的项目源,然后您可以更改集合中的数据。

我使用了这里的代码:INotifyPropertyChanged and ObservableCollection WPF

我不需要访问文本块,只是将一些绑定挂钩到对象,并且能够通过更改 类.[=11 的值来进行 UI 更改=]