Как я могу иметь два редактируемых и обновляемых DataGridView, привязанных к списку и подсписку? - PullRequest
1 голос
/ 15 апреля 2020

У меня есть List<Input> с именем listInput, который содержит свойство типа List<class> с именем 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; }
}

У меня есть два DataGridView элемента управления с именами dgInput и dgFriends.
dgInput привязан к BindingList следующим образом:

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

dgInput может редактироваться и обновляется при запуске. время после того, как пользователь меняет любую ячейку на dgInput.

Вопрос: как я могу связать dgFriends с подсписком friends, чтобы он автоматически обновлялся при изменении строки dgInput curretn Row?
Также важно, чтобы dgFriens можно было обновляется, когда пользователь изменяет любую ячейку на dgFriends (свойства listInput должны сохранять изменения).

1 Ответ

1 голос
/ 15 апреля 2020

Вот простой пример:

  • Первый DataGridView использует определенный BindingSource. Источник данных этого BindingSource установлен в коллекцию List<Input>. Этот DGV может отображать только свойство Name из List<Input>, поскольку вы не можете представить строки, содержащие как отдельные значения, так и наборы значений.
    DataMember BindingSource должен быть пустым (или нулевым): если вы установите Name как DataMember, в результате вы получите массив Char вместо строки.

  • Создается второй BindingSource: его DataSource установлен на существующий BindingSource. В этом случае DataMember явно устанавливается в свойство Friends, которое представляет объекты List<class> (один объект, представляющий коллекцию, которая будет предоставлять данные в строки второго DGV).

Генерирует активное связывание (связь) между двумя объектами BindingSource: при изменении первого объекта BindingSource.Current будет следовать второй объект BindingSource, показывая его Current объект (List<Friend>, связанный с текущим свойством Name).

Все свойства двух классов доступны для редактирования.

Примечание:
Я реализовал интерфейс INotifyPropertyChanged в классе Input для уведомления об изменениях свойства Name: это не обязательно (или вообще не требуется) в этом контексте, но, возможно, вы захотите иметь его там, вам, вероятно, понадобится это позже.

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; }
}

Вот как это работает:

DataGridView Double BindingSource

Пример инициализации объекта, для тестирования:

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"},
        }
    }
});
...