Как сделать пользовательский компонент источником данных для привязки данных в WinForms? - PullRequest
2 голосов
/ 23 января 2012

Я создал компонент для извлечения данных из веб-службы. Веб-служба возвращает набор данных ADO.NET.

Я хотел бы, чтобы этот компонент был источником данных для связывания с другими элементами управления. Данные для источника будут набором данных.

Итак, я добавил свойство DataSet к компоненту.

private DataSet _dataSet;
public DataSet DataSet
{
    get { return _dataSet; }
    set
    {
        if (_dataSet == value)
            return;
        _dataSet = value;
        OnPropertyChanged (this, new PropertyChangedEventArgs ("DataSet"));
    }
}

Я реализовал IListSource для компонента.

public partial class MyComponent : Component, INotifyPropertyChanged, IListSource
{
    ...

    IList IListSource.GetList()
    {
        return DataSet == null ? null : ((IListSource)DataSet).GetList();
    }

    bool IListSource.ContainsListCollection
    {
        get { return DataSet != null && ((IListSource)DataSet).ContainsListCollection; }
    }

    ...
}

В методе получения данных от веб-службы я делаю следующее:

...

DataSet = response.DataSet;    // Copy dataset from web service to the component.

...

Затем я создал новый проект WinForms с формой. В этой форме я добавил свой компонент и DataGridView. Установите связь между ними.

После запуска приложения вызывается веб-служба и принимается набор данных. Тем не менее, пользовательский интерфейс не показывает данные.

Я даже пытался создать набор данных в конструкторе компонента, и вместо замены набора данных в свойстве DataSet я просто делаю

_dataSet.Reset ();
_dataSet.Merge (value);

По-прежнему не действует.

Есть ли событие или метод, который мне нужно вызвать, чтобы набор данных сообщил, что он обновлен?

Что мне здесь не хватает?

Ответы [ 2 ]

7 голосов
/ 26 января 2012

Да, есть событие, которое вам нужно!DataGridView отвечает, автоматически обновляя свое содержимое в соответствии с событием ListChanged базового источника данных (который можно вызвать с помощью реализации IBindingList ).IList не поддерживает это событие, и без него DataGridView не будет отображать вновь заполненные данные , если вы не переназначаете свойство DataSource объекта DataGridView компоненту-подчиненному компоненту каждый раз, когда он изменяется, чего вы не хотите делатьесли у вас часто будут изменения (это дорого) .

Я должен был выучить этот болезненный урок сам здесь: Обновление DGV IList

Позвольте мнезнаю, если я не в порядке, но это похоже на то, где может быть ваша проблема.

РЕДАКТИРОВАТЬ : пример того, как это может работать -

  private DataSet _dataSet;
  public DataSet DataSet
  {
     get { return _dataSet; }
     set
     {
        if (_dataSet == value)
           return;
        _dataSet = value;
        ListChanged(this, new ListChangedEventArgs(ListChangedType.Reset, 0));
     }
  }

  public event ListChangedEventHandler ListChanged;
1 голос
/ 26 января 2012

Реализация свойства набора данных для создания привязываемого источника данных недостаточна.

Быстрый способ получить что-то похожее на привязываемый источник данных - это использовать уже готовый класс.Вы можете создать класс MyDataSource, который наследуется от класса BindingSource (System.Windows.Forms.BindingSource)

Затем вы можете создать экземпляр MyDataSource, установить MyDataSourceInstance.DataSource в свой набор данных, а затем установить DataGridView..Datasource = MyDataSourceInstance

Теперь: привязка будет работать, и вы сможете перехватывать и в конечном итоге изменять все, что делает привязку данных работающей, вам просто нужно переопределить метод BindingSource в вашей реализации MyDataSource.

(извините за короткий ответ ... У меня немного не хватает времени: -)

...