无法绑定到实现ICollection的对象的属性<t>

时间:2015-12-17 10:00:39

标签: c# winforms data-binding

为了解释我的情况,让我们考虑一个这样的简单对象:

public class FixedSeries : Series
{
    int val1, val2;
    public FixedSeries(int val1, int val2) { this.val1 = val1; this.val2 = val2; }
    public int Diff
    {
        get { return val2 - val1; }
        set { val2 = val1 + value; }
    }
}

然后,如果在我的表单中我想将Diff绑定到控件的值,我可以这样做:

BindingSource source;
FixedSeries fixedSeries;
public Form1()
{
    InitializeComponent();

    fixedSeries = new FixedSeries(2, 5);    
    source = new BindingSource();
    source.DataSource = fixedSeries;

    numericUpDown1.DataBindings.Add(new System.Windows.Forms.Binding("Value", source, "Diff", false, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
}

但是,如果我的FixedSeries派生于一个更通用的Series(见下文),它实现了ICollection<int>接口,我得到一个ArgumentException“无法绑定到该属性或DataSource上的Diff列。

public class FixedSeries : Series
{
    public FixedSeries(int val1, int val2)
    {
        base.Add(val1);
        base.Add(val2);
    }
    public int Diff
    {
        get { return base[1] - base[0]; }
        set { base[1] = base[0] + value; }
    }
}

public interface ISeries : ICollection<int>
{
    int this[int index] { get; }
}
public class Series : ISeries
{
    List<int> vals = new List<int>();
    public int this[int index] 
    { 
        get { return vals[index]; } 
        internal set { vals[index] = value; } 
    }
    public void Add(int item) { vals.Add(item); }
    public void Clear() { vals.Clear(); }
    public bool Contains(int item) { return vals.Contains(item); }
    public void CopyTo(int[] array, int arrayIndex) { vals.CopyTo(array, arrayIndex); }
    public int Count { get { return vals.Count; } }
    public bool IsReadOnly { get { return false; } }
    public bool Remove(int item) { return vals.Remove(item); }
    public IEnumerator<int> GetEnumerator() { return vals.GetEnumerator(); }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return vals.GetEnumerator(); }
}

我想这与ICollection<T>接口有关,也许与.NET希望绑定到内部的项目有关。如何在不删除绑定到系列中项目的可能性的情况下绑定到此方案中的Diff属性?

1 个答案:

答案 0 :(得分:1)

  

我想这与ICollection&lt; T&gt;有关。接口,也许还有.NET希望绑定到内部的项目。

正确。更确切地说,IEnumerable<T>继承了ICollection<T>

  

如何在不删除绑定到系列内部项目的可能性的情况下绑定到此场景中的Diff属性?

以下是一些选项

(A)不要使用BindingSource,直接绑定到数据源对象

numericUpDown1.DataBindings.Add("Value", fixedSeries, "Diff", false, DataSourceUpdateMode.OnPropertyChanged);

(B)将数据源对象包装到单个项目数组/列表中,并将其用作BindingSource.DataSource

source.DataSource = new[] { fixedSeries };

(C)与(B)类似,但使用BindingSource.Add方法(根本不提供DataSource属性)

source.Add(fixedSeries);