WinForms数据绑定到集合属性(如计数)

时间:2010-01-26 19:40:54

标签: .net winforms data-binding

我想数据绑定到集合属性,例如Count。

一般来说,当我数据绑定时,我为集合中的对象属性指定数据成员,而不是实际的属性集合本身公开。

例如,我有一个自定义对象列表。我在datagridview中显示它们。但我也想用一个单独的标签来显示他们的总数。有没有办法通过数据绑定来做到这一点?

我想我不得不强制使用PropertyManager而不是CurrentyManager?

我收到以下异常。请注意,DataSource是集合并具有TotalValue属性。

System.ArgumentException: Cannot bind to the property or column TotalValue on the DataSource.
Parameter name: dataMember
   at System.Windows.Forms.BindToObject.CheckBinding()
   at System.Windows.Forms.Binding.SetListManager(BindingManagerBase bindingManagerBase)
   at System.Windows.Forms.ListManagerBindingsCollection.AddCore(Binding dataBinding)
   at System.Windows.Forms.BindingsCollection.Add(Binding binding)
   at System.Windows.Forms.BindingContext.UpdateBinding(BindingContext newBindingContext, Binding binding)
   at System.Windows.Forms.Binding.SetBindableComponent(IBindableComponent value)
   at System.Windows.Forms.ControlBindingsCollection.AddCore(Binding dataBinding)
   at System.Windows.Forms.BindingsCollection.Add(Binding binding)

3 个答案:

答案 0 :(得分:0)

我认为没有任何理由你不能将TextBox绑定到myObjectList.Count,但是 myobjectList需要自行实施IBindingList<T>,如果它是带有附加验证的自定义集合,或者是BindingList<T>类型。 IBingingList<T>包含在集合中添加,删除或更改对象时触发的事件。

请参阅BindingListIBindingList上的MSDN文档。你可能想要使用前者,因为后者有很多成员要实现。

答案 1 :(得分:0)

您可以通过将collection.Count指定为DataBindings.Add方法中的dataSource来绑定到集合的Count。 dataMember参数将是一个空字符串。

myLabel.DataBindings.Add("Text", myObjectList.Count, string.Empty);

答案 2 :(得分:0)

如果您的数据源正在实现IList接口,就像BindingList那样,绑定就会尝试绑定到列表中元素的属性。

假设您有一个string项列表,那么单个元素没有名为Count的属性。

将您的列表包装到一个授权Count属性但没有实现IList界面的类,并在PropertyChanged触发BindingList时触发ListChanged事件事件。

class CountWrapper : INotifyPropertyChanged
{
    private readonly IBindingList bindingList;

    public CountWrapper(IBindingList bindingList)
    {
        this.bindingList = bindingList;

        bindingList.ListChanged += BindingList_ListChanged;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public int Count
    {
        get { return bindingList.Count; }
    }

    private void BindingList_ListChanged(object sender, ListChangedEventArgs e)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(string.Empty));
    }
}

现在您可以像这样绑定Count属性:

myLabel.DataBindings.Add("Text", new CountWrapper(myObjectList), "Count");

这也适用于其他属性,只需使用特定类的特定包装器即可。如果您的类为其自己的属性实现INotifyPropertyChanged,您只需要监听该事件并将其转发。

class MyListWrapper : INotifyPropertyChanged
{
    private readonly MyList bindingList;

    public CountWrapper(MyList bindingList)
    {
        this.bindingList = bindingList;

        bindingList.ListChanged += BindingList_ListChanged;
        bindingList.PropertyChanged+= BindingList_PropertyChanged;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public int Count
    {
        get { return bindingList.Count; }
    }

    public int TotalCount
    {
        get { return bindingList.TotalCount; }
    }

    public string ReadWriteProperty
    {
        get { return bindingList.ReadWriteProperty; }
        set { bindingList.ReadWriteProperty = value; }
    }


    private void OnPropertyChanged(PropertyChangedEventArgs ea)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, ea);
    }

    private void BindingList_ListChanged(object sender, ListChangedEventArgs e)
    {
        OnPropertyChanged(new PropertyChangedEventArgs(string.Empty));
    }

    private void BindingList_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        OnPropertyChanged(e);
    }
}