微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何仅使用数据绑定类从 ListBoxItem 访问按钮/标签?

如何解决如何仅使用数据绑定类从 ListBoxItem 访问按钮/标签?

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

我试图用它的索引和它的类绑定来收集 ListBoxItem,但它们都给了我一个 null 值:

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

是否有另一种方法可以访问 listBoxitem 以便稍后使用函数 FindName(...) 收集其他对象?

调试:

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

错误

Output: Exception thrown: 'system.invalidOperationException' in WindowsBase.dll

解决方法

默认情况下,ListBox 是虚拟化的,请参阅 Displaying large data sets

通常,您不必同时显示所有项目;相反,您显示一个子集,然后用户滚动列表。在这种情况下,使用 UI 虚拟化是有意义的,这意味着项目容器的生成和关联的项目布局计算被推迟到项目可见。

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

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

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


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

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

,

为了找到另一个解决方案/想法,我想出了可以添加到类中的 INotifyPropertyChanged,因此无需从列表框中删除 ItemsSource,只需在加载时挂钩项目源程序,然后你可以改变集合内的数据。

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

我不需要访问文本块,只需将一些绑定挂钩到对象,并且能够通过更改类的值来更改 UI。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。