为什么绑定到结构不起作用?
我最近遇到一个问题,我有一个 ObservableCollection 绑定到 ListView。人是我写的一个结构。只要我在绑定之前设置 People 对象的值,一切似乎都可以正常工作。但是,当我尝试在运行时从 GUI 设置值时,底层对象似乎没有反映更改。
我最终通过简单地将 People 从结构体更改为类来解决了这个问题。无需进行其他更改。
有人可以向我解释这是为什么吗?
I've recently encountered an issue where I have an ObservableCollection bound to a ListView. People is a structure which I have written. So long as I set the value(s) of the People objects prior to binding, everything seems to work OK. However, when I try to set the values from the GUI at runtime, the underlying objects do not seem to reflect the change.
I finally overcame this problem by simply changing People from a structure to a class. No other changes were necessary.
Can someone please explain to me why this is?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您的绑定会获取结构的副本,因为结构是按值传递给方法的。如果绑定更新了某些内容;内存中某处的副本正在被修改,因此您的原始对象不会更新。
Your binding gets a copy of struct since structs are passed by value to methods. If the binding updates something; a copy in memory somewhere is being modified and hence the original object of yours is not updated.
由于该结构按值传递给控件,因此当您在 UI 中进行更改时,WPF 会将更改写回
People
的不同实例。把它改成一个类就可以了。
除非您完全理解 struct 的用途,否则我建议不要使用它。
Because the struct is passed by value to the control, therefore when you make changes in the UI, WPF writes the changes back to a different instance of
People
.Change it to a class and it'll work.
Unless you fully understand the purpose of the
struct
I suggest not using it.ListView 是一个 ItemsControl,可以在直接模式下工作,在直接模式下通过在 XAML 中声明多个 ListViewItem 对象来填充它的项目,也可以在 ItemsSource 模式下工作,在 ItemsSource 属性上设置 Binding
请参阅 WPF 博士的这篇文章,了解更多信息解释。
无论哪种方式,ListView.Items 都是一个 ItemCollection,它是一个 CollectionView,即 Items 不是您提供给 ItemsSource 属性的实际集合,而是您提供的集合的规范化副本,它允许框架通过索引访问基础 IEnumerable即使 IEnumerable 本身不提供索引器。
由于 ListView 使用副本,因此当它使用 Class 实例的集合时,它可以复制引用,两个引用都指向内存中的同一对象,因此更改其中一个引用中的值的效果可以通过另一个引用看到,但是当它使用值类型的结构集合时,它必须复制值,而不是拥有两个指向同一对象的引用,然后您将拥有两个不同的值类型对象。
The ListView is an ItemsControl and works either in direct mode where you populate it's Items by declaring severl ListViewItem objects in XAML or in ItemsSource mode where you set a Binding on the ItemsSource property
See this Dr. WPF article for a good explanation.
Either way, the ListView.Items is an ItemCollection which is a CollectionView, i.e. Items is not the actual collection you supply to the ItemsSource property but a normalized copy of the collection you supplied which allows the framework to for example access an underlying IEnumerable by index even though IEnumerable doesn't provide an indexer itself.
Since the ListView uses a copy, when it is using a collection of Class instances it can make copies of the references, both references point to the same object in memory so the effects of changing values in one of the references is visible through the other reference, but when it is using a collection of structs which are value types it has to make copies of the values, rather than having two references which point to the same object, you then have two distinct value type objects.
对于所有对此主题感兴趣的人:
我使用 Combobox 和 Objectdataprovider 运行了它。
“ItemsSource”是结构,但“SelectedItem”写在其他地方。
这是:
结构如下所示:
For all interested in this topic:
I got it running, with a Combobox and Objectdataprovider.
The "ItemsSource" is the struct, but the "SelectedItem" is written somewhere else.
Here it is:
And this is how the struct looks like: