2010-01-26 79 views
2

我想将数据绑定到收集属性,如Count。WinForms数据绑定到收集属性(如计数)

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

例如,我有一个自定义对象的列表。我在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)

回答

0

我不认为有,你不能绑定任何理由,比如说,一个文本框myObjectList.Count,但 myobjectList将需要实现IBindingList<T>无论其自身,如果它是一个自定义集合与额外的验证或凭借类型BindingList<T>IBingingList<T>包含在集合中添加,删除或更改对象时触发的事件。

请参阅BindingListIBindingList上的MSDN Docs。你可能会想使用前者,因为后者有很多成员实施。

+0

@Josh Kodroff,其实myobjectList是一个BindingList。我可以绑定到集合中项目的属性,但不绑定到实际列表的属性(如Count)。对于TextBox,我可以指定集合中项目的属性,并将TextBox绑定到集合中的第一个项目。当我尝试绑定到List属性时,我得到一个异常。 – Sumrak 2010-01-26 21:12:55

+0

你可以添加你的帖子的例外吗? – 2010-01-27 14:26:05

+0

@Jesh Kodroff:增加了异常文本 – Sumrak 2010-02-08 17:38:37

0

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

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

这是诀窍。 – henginy 2012-07-10 08:37:21

+1

这不会绑定'myObjectList.Count'属性。而是绑定'Count'属性的整数值。这意味着绑定不会再更新。它是一个静态绑定。 – 2015-02-20 09:37:52

0

如果数据源正在实施IList接口,如BindingList呢,绑定是试图绑定到列表中的元素的属性。

想象一下,您有一个string项目的列表,那么对于单个元素没有名为Count的属性。

包装你列表一类是delegatingt的Count财产,但没有实施IList接口和一个触发事件PropertyChangedBindingList触发一个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); 
    } 
}