Подтвердить что ты не робот

Обновление BindingSource в WinForms не обновляет сборку данных

Я хочу показать пользовательскую коллекцию в DataGridView в приложении Windows Forms. Эта пользовательская коллекция реализует ICollection и IEnumerable. Я установил BindingSource, используя коллекцию как свойство .DataSource. DataGridView установлен для использования моего BindingSource в качестве источника данных. Когда я добавляю новый элемент в коллекцию с помощью метода BindingSource.Add(), DataGridView корректно обновляется с новым элементом. С другой стороны, источник данных BindingSource не имеет значения:

MyCustomCollection myCollection = new MyCustomCollection();

myCollection.Add(myCustomObject1);
myCollection.Add(myCustomObject2);

myBindingSource.DataSource(myCollection);
myBindingSource.Add(myCustomObject3);

В приведенном выше коде внутренний список myBindingSource содержит правильное количество записей (3), а DataGridView также содержит три записи, но myCollection содержит только две записи. Я знаю, что изменение базового myCollection НЕ обновит BindingSource или DataGridView, так как это не BindingList<T>, но я был под впечатлением, что обновление BindingSource напрямую обеспечило бы, чтобы myCollection был обновлен на то же время.

Есть ли способ использовать коллекцию, которая не является BindingList<T>, и обновлять ее при непосредственном взаимодействии с BindingSource?

Обновить. Один из способов, которым я обновил данные во всех частях (Collection, BindingSource, DataGridView), выглядит следующим образом:

myCollection.Add(myCustomObject3);
myBindingSource.DataSource = null;
myBindingSource.DataSource = myCollection;

Я уверен, что есть лучший способ атаковать эту проблему, но это единственный метод, который породил результаты, которые я ожидал.

4b9b3361

Ответ 1

Проблема заключается в Fill Adapter. Когда вы загружаете форму, Заполнить выполняется для вас. Просто убедитесь, что вы сделали Refill, а затем следите за Reset привязками, размещайте любые изменения данных, и Grid будет обновляться.

Пример:

WorkTableAdapter.Insert(objData.XAttribute, "",
  objData.YAttribute,objLoanData.Amount_IsValid, DateTime.Now, DateTime.Now);
this.WorkTableAdapter.Fill(this.POCDataSet.Work);
this.WorkBindingSource.ResetBindings(false);

Ответ 2

Вам придется вручную вызвать ResetBindings() после изменения источника данных, если вы используете контейнер, который не может сделать это от вашего имени.

http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.resetbindings.aspx

Вызывает управление, привязанное к BindingSource, чтобы перечитать все элементы в списке и обновить отображаемые значения.

Ответ 3

Сброс отдельного элемента работает!

Мне не повезло с .ResetBindings(false) и повторным назначением datsource, вызвавшим мерцание с накладными расходами potentiail, если только один элемент изменяется часто.

Я попробовал встроенный механизм с помощью PropertyChanged, но ничего не обновлялся.

Сброс отдельного элемента с использованием ResetItem()!

        for (int i = 0; i < bindingSource1.Count; i++)
        {
            bindingSource1.ResetItem(i);   
        }

И даже лучше - если у вас есть событие обновления, связанное с каждым элементом данных в источнике bindningsource, вы можете найти объект в источнике привязки и использовать индекс объекта для вызова ResetItem (idx)

В этом случае мои пользовательские аргументы событий содержат ключ словаря к объекту данных, содержащемуся в отдельной коллекции. После того, как объект находится в использовании bindningsource.IndexOf(), он обновляется отдельно.

    void Value_PropertyChanged(object sender, RegisterEventArgs e)
    {

        var idx = bindingSource1.IndexOf(registers_ref[e.registerID]);
        if (idx>=0)
        {
            bindingSource1.ResetItem(idx);                
        }

    }

Ответ 4

Я полагаю, что некоторое время назад я столкнулся с этой проблемой - я нашел в файлах свой код, и я думаю, что это решение, которое сработало для меня.

        // Applies pending changes to the underlying data source.
        this.bindingSource1.EndEdit();

Это было в контексте обработчика кликов для кнопки сохранения.