如何将两个可编辑和可更新的DataGridView绑定到一个列表和子列表? [英] How can I have two editable and updatable DataGridViews bounded to a list and sub-list?

查看:42
本文介绍了如何将两个可编辑和可更新的DataGridView绑定到一个列表和子列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 listInput List< Input> ,其中包含类型为 List< class> 的属性,名称为 friends :

  List< Input>listInput =新列表< Input>();BindingList< Input>blInput;BindingSource bsInput;公共类输入{公共字符串名称{get;放;}公开列表<朋友>朋友{得到;放;}}公开课的朋友{公共字符串FirstName {get;放;}公共字符串LastName {get;放;}} 

我有两个 DataGridView 控件,分别名为 dgInput dgFriends .
dgInput 这样绑定到 BindingList :

  blInput = new BindingList< Input>(listInput);bsInput =新的BindingSource(blInput,null);dgInput.DataSource = bsInput; 

用户更改 dgInput 上的任何单元格后,

dgInput 可以在运行时可编辑可更新.

问题是:如何将 dgFriends 绑定到子列表 friends ,以便在 dgInput curretn Row更改时它会自动更新?
同样重要的是,当用户更改 dgFriends 上的任何单元格时, dgFriens 可以进行更新( listInput 的属性必须保留所做的更改).

解决方案

下面是一个简单的示例:

  • 第一个DataGridView使用您定义的BindingSource.此BindingSource的DataSource设置为 List< Input> 集合.此DGV只能显示 List< Input> 中的 Name 属性,因为您不能显示同时包含单个值和值集合的行.BindingSource的 DataMember 必须为空(或为null):如果将 Name 设置为 DataMember ,则会得到一个数组> Char 作为结果,而不是字符串.

  • 创建第二个BindingSource:其DataSource设置为现有的BindingSource.在这种情况下, DataMember 被显式设置为 Friends 属性,该属性表示 List< class> 对象(单个对象代表一个将数据提供给第二个DGV的行的集合).

这将在两个BindingSource对象之间生成活动绑定(关系):当第一个

样本对象初始化,用于测试:

  listInput.AddRange(new [] {新的Input(){名字=名字一",朋友=新列表<朋友>(){new Friend(){FirstName ="First",LastName =一个人的朋友"},new Friend(){FirstName ="Second",LastName =一个人的朋友"},new Friend(){FirstName ="Third",LastName =一个人的朋友"},}},新的Input(){名称=名称二",朋友=新列表<朋友>(){new Friend(){FirstName ="First",LastName ="Two of Friends"},new Friend(){FirstName ="Second",LastName ="Two of Friends"},new Friend(){FirstName ="Third",LastName ="Two of Friends"},}},新的Input(){名称=名称三",朋友=新列表<朋友>(){new Friend(){FirstName ="First",LastName =三个朋友"},new Friend(){FirstName ="Second",LastName =三个朋友"},new Friend(){FirstName ="Third",LastName =三个朋友"},}}}); 

I have a List<Input> named listInput that contains property of type a List<class> named friends:

List<Input> listInput=new List<Input>();
BindingList<Input> blInput;
BindingSource bsInput;

public class Input
{
    public string Name { get; set; }
    public List<Friend> friends{ get; set; }
}

public class Friend
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

I have two DataGridView controls, named dgInputand dgFriends.
dgInput is bound to a BindingList like this:

blInput = new BindingList<Input>(listInput);
bsInput = new BindingSource(blInput, null);
dgInput.DataSource = bsInput;

dgInput is editable and updatable at run-time after user changes any cell on dgInput.

The question is: how can I bind dgFriends to sublist friends, so that it will automatically update when the dgInput curretn Row changes?
It's also important that dgFriens can be updated when an User changes any cell on dgFriends (the properties of listInput must preserve the changes).

解决方案

Here's a simple example:

  • The first DataGridView uses the BindingSource you defined. The DataSource of this BindingSource is set to the List<Input> collection. This DGV can only show the Name property from the List<Input>, since you cannot present Rows containing both single values and collections of values.
    The DataMember of the BindingSource must be empty (or null): if you set Name as DataMember, you'll get an array of Char as a result instead of a string.

  • A second BindingSource is created: its DataSource is set to the existing BindingSource. In this case, the DataMember is set explicitly to the Friends property, which represents a List<class> objects (a single object that represents a collection that will provide the data to the Rows of the second DGV).

This generates an active binding (a relationship) between the two BindingSource objects: when the first BindingSource.Current object changes, the second BindingSource will follow, showing its Current object (the List<Friend> linked to the current Name property).

All properties of the two classes are editable.

Note:
I've implemented the INotifyPropertyChanged interface in the Input class to notify changes of the Name property: it's not strictly required (or, it' not required at all) in this context, but you may want to have it there, you'll quite probably need it later.

List<Input> listInput = new List<Input>();
BindingSource bsInput = null;

public SomeForm()
{
    InitializeComponent();

    bsInput = new BindingSource(listInput, "");
    var bsFriends = new BindingSource(bsInput, "Friends");
    dataGridView1.DataSource = bsInput;
    dataGridView2.DataSource = bsFriends;
}

public class Input : INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged;
    private string m_Name = string.Empty;

    public string Name {
        get => m_Name;
        set { m_Name = value;
            NotifyPropertyChanged(nameof(this.Name));
        }
    }
    public List<Friend> Friends { get; set; } = new List<Friend>();

    private void NotifyPropertyChanged(string propertyName) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

public class Friend {
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

This is how it works:

Sample object initialization, for testing:

listInput.AddRange(new[] {
    new Input() {
        Name = "Name One", Friends = new List<Friend>() {
            new Friend () { FirstName = "First", LastName = "Friend of One"},
            new Friend () { FirstName = "Second", LastName = "Friend of One"},
            new Friend () { FirstName = "Third", LastName = "Friend of One"},
        }
    },
    new Input() {
        Name = "Name Two", Friends = new List<Friend>() {
            new Friend () { FirstName = "First", LastName = "Friend of Two"},
            new Friend () { FirstName = "Second", LastName = "Friend of Two"},
            new Friend () { FirstName = "Third", LastName = "Friend of Two"},
        }
    },
    new Input() {
        Name = "Name Three", Friends = new List<Friend>() {
            new Friend () { FirstName = "First", LastName = "Friend of Three"},
            new Friend () { FirstName = "Second", LastName = "Friend of Three"},
            new Friend () { FirstName = "Third", LastName = "Friend of Three"},
        }
    }
});

这篇关于如何将两个可编辑和可更新的DataGridView绑定到一个列表和子列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆