简体   繁体   English

数据绑定控件,封装的最佳实践

[英]Databinding controls, best practices for encapsulation

I've recently been using data binding in c#, and while the way I am doing it is straightforward and works, it does not feel like the best way. 我最近一直在c#中使用数据绑定,尽管我做的方式很简单并且可以正常工作,但它感觉并不是最好的方式。

For example, I have a manager class, ie UserManager which has the following interface: 例如,我有一个管理器类,即UserManager,它具有以下接口:

class UserManager
{
  public IList<User> Users { get; ...}
  public AddUser(...)
  public RemoveUser(...)
}

So Adduser and RemoveUser should control the list, with the Users collection as an output. 因此, AdduserRemoveUser应该控制列表,并以Users集合作为输出。 I am using this collection in a binding, ie: 我在绑定中使用此集合,即:

listBindingSource.DataSource = userManager.Users;

I am then manipulating the list via the binding, ie 然后,我通过绑定操作列表,即

listBindingSource.Add(new User(...))

This works, of course, but I am completely bypassing the UserManager and the AddUser / RemoveUser functions in there! 当然可以,但是我完全绕过了其中的UserManagerAddUser / RemoveUser函数! This of course seems very wrong. 当然,这似乎是非常错误的。 What is the correct way to use databinding? 使用数据绑定的正确方法是什么?

UserManager is inside a lib so I do not want to put any binding objects in there, as I feel that should be a gui thing. UserManager在lib内部,所以我不想在其中放置任何绑定对象,因为我认为这应该是gui的事情。 On the other hand, with binding, my gui has taken complete control over my collection. 另一方面,通过绑定,我的GUI完全控制了我的收藏集。

As your code stands now, you can't do what you're after. 就目前的代码而言,您将无法做自己想要做的事情。 At some point, the collection has to support the IBindingList interface (which is what the BindingSource object you have on the form does). 在某个时候,该集合必须支持IBindingList接口(这是您在窗体上具有BindingSource对象的功能)。 If you want to make use of your UserManager class to do the manipulations, for practical purposes you'll have to change the internal data store for the Users property to use a BindingList<User> (you should still be able to return it typed as an IList<User> as you have now, just change the actual concrete implementation to BindingList<User> ). 如果要使用UserManager类进行操作,出于实际目的,您必须将内部数据存储区更改为Users属性,以使用BindingList<User> (您仍应能够返回键入为就像您现在拥有的IList<User>一样,只需将实际的具体实现更改为BindingList<User> )。 Doing this will expose the IBindingList interface to the grid and it will detect changes that are made elsewhere, namely in your UserManager class. 这样做会将IBindingList接口暴露给网格,并且它将检测在其他位置(即在UserManager类中)所做的更改。

This will, however, only cause it to pick up on changes made to the list , not to individual elements contained in the list (in other words, additions and removals will be reflected on the UI, but modifications won't be). 但是,这只会使它接受对列表所做的更改,而不是对列表中包含的单个元素的更改(换句话说,添加和删除将反映在UI上,但不会进行修改)。 In order to accomplish this, you need to implement IPropertyChanged on the User class (assuming it doesn't already). 为了实现此目的,您需要在User类上实现IPropertyChanged (假设它尚未)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM