.net 如何让用户组件成为WinForms中数据绑定的数据源?

.net 如何让用户组件成为WinForms中数据绑定的数据源?,.net,winforms,data-binding,components,.net,Winforms,Data Binding,Components,我创建了一个组件,用于从web服务获取数据。web服务返回ADO.NET数据集 我希望此组件成为与其他控件绑定的数据源。源的数据将是数据集 因此,我向组件添加了一个属性数据集 private DataSet _dataSet; public DataSet DataSet { get { return _dataSet; } set { if (_dataSet == value) return; _dataSet

我创建了一个组件,用于从web服务获取数据。web服务返回ADO.NET数据集

我希望此组件成为与其他控件绑定的数据源。源的数据将是数据集

因此,我向组件添加了一个属性数据集

private DataSet _dataSet;
public DataSet DataSet
{
    get { return _dataSet; }
    set
    {
        if (_dataSet == value)
            return;
        _dataSet = value;
        OnPropertyChanged (this, new PropertyChangedEventArgs ("DataSet"));
    }
}
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; }
    }

    ...
}
我为组件实现了IListSource

private DataSet _dataSet;
public DataSet DataSet
{
    get { return _dataSet; }
    set
    {
        if (_dataSet == value)
            return;
        _dataSet = value;
        OnPropertyChanged (this, new PropertyChangedEventArgs ("DataSet"));
    }
}
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; }
    }

    ...
}
在从web服务接收数据的方法中,我执行以下操作:

...

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

...
然后我用一个表单创建了一个新的WinForms项目。在这个表单上,我添加了我的组件和DataGridView。设置它们之间的绑定

在运行应用程序时,调用web服务并接收数据集。但是,UI不显示数据

我甚至尝试在组件的构造函数中创建一个数据集,而不是在dataset属性中替换数据集,我只是这样做

_dataSet.Reset ();
_dataSet.Merge (value);
仍然没有效果

我是否需要调用某个事件或方法来让数据集通知它是否已更新


我错过了什么?

是的,你需要一个活动!DataGridView通过针对底层数据源的ListChanged事件(您可以通过实现来引发)自动更新其内容来响应。IList不支持此事件,如果没有它,DataGridView将不会显示新填充的数据,除非每次更改时都将DataGridView的DataSource属性重新分配给underyling组件(如果经常更改,则不希望这样做)(代价很高)

在这里,我不得不自己吸取这个痛苦的教训:

让我知道,如果我在这里的方式偏离基地,但这感觉像你的问题可能在哪里

编辑:这可能如何工作的示例-

  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;
实现“dataset”属性来创建可绑定的数据源是不够的

获取可绑定数据源之类的东西的一种快速方法是使用已经准备好的类。 您可以创建从BindingSource类(System.Windows.Forms.BindingSource)继承的类MyDataSource

然后可以创建MyDataSource的实例,将MyDataSourceInstance.DataSource设置为您的数据集,然后可以设置DataGridView.DataSource=MyDataSourceInstance

现在:绑定将起作用,您将能够拦截并最终修改使数据绑定工作的所有内容,您只需在MyDataSource实现中重写BindingSource方法


(很抱歉回答得这么短……我的时间有点短:-)

您看到“添加项目数据源”选项了吗?只要组件是公共的并且具有公共get/set属性,就可以将其添加为项目数据源,然后将其分配给bindingsource。在设计器中执行此操作时,将其指定为类型。可以在运行时分配实例。我从来没有在组件上尝试过。是的,我看到过这个选项,但我一直在寻找一种更“集成”的方式,让组件直接成为绑定的数据源。不幸的是,除了添加项目数据源或在运行时将其连接起来,我不知道有什么方法可以做到这一点。嗯,好的,我想我知道你要做什么了。但是,我的组件不知道DataGridView(我不希望它知道),因此我无法重新分配DataSource属性。@Stécy您的组件不需要知道DGV。DGV将了解您的组件(因为您将DGV的DataSource属性设置为您的组件)。我不是建议您每次都重新分配数据源-我是说,如果您实现IBindingList,DGV将自动连接到ListChanged事件。我之前已经尝试在我的组件上实现IBindingList,但结果相同(没有)。当时,我只将IBindingList的所有属性/方法委托给数据集。也许这是一个错误的方式。但是,我不知道下一步如何进行。@您是否在DataSet的属性访问器中引发了ListChanged事件?这将导致组件抛出ListChanged事件,DataGridView应该侦听该事件。如果不引发事件,DGV将不知道数据已更改!不幸的是,无法引发此事件,因为C#编译器不允许我(抱怨ListChanged只能与-=或+=赋值一起使用)。有趣的是,我必须测试此问题。BindingSource不可重写。BindingSource它是一个类,所以它是可继承的。方法和属性是可重写的,而不是类。因此,我认为应该从BindingSource继承,然后在继承的类中,可以重写BindingSource方法/属性,或者添加自己的方法/属性。DataSource属性不可重写,但您可以挂接到DataSourceChanged事件以拦截DataSource更改。问题是,BindingSource方法在MyDataSource实现中不可重写,正如您在回答中所建议的。您尝试重写哪种方法?