BindingSource.Find抛出NotSupportedException(DataSource是BindingList <t>)</t>

时间:2012-06-13 14:12:48

标签: c# .net winforms data-binding bindingsource

我有BindingSource附加BindingList<Foo>作为数据源。我想使用BindingSource的{​​{3}}来查找元素。但是,当我执行以下操作时会抛出NotSupportedException,即使我的数据源确实实现了IBindingList(并且MSDN中没有记录此类异常):

int pos = bindingSource1.Find("Bar", 5);

我在下面添加了一个简短示例(ListBoxButtonBindingSource)。任何人都可以帮我调用Find吗?

public partial class Form1 : Form
{
    public Form1() { InitializeComponent(); }

    private void Form1_Load(object sender, EventArgs e)
    {
        var src = new BindingList<Foo>();
        for(int i = 0; i < 10; i++)
        {
            src.Add(new Foo(i));
        }

        bindingSource1.DataSource = src;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        int pos = bindingSource1.Find("Bar", 5);
    }
}

public sealed class Foo
{
    public Foo(int bar)
    {
        this.Bar = bar;
    }

    public int Bar { get; private set; }

    public override string ToString()
    {
        return this.Bar.ToString();
    }
}

3 个答案:

答案 0 :(得分:15)

我能够使用

解决我的类似问题
var obj = bindingSource1.List.OfType<Foo>().ToList().Find(f=> f.Bar == 5);
var pos = bindingSource1.IndexOf(obj);
bindingSource1.Position = pos;

这有利于查看位置以及找到对象

答案 1 :(得分:0)

BindingList<T>不支持搜索。实际上bindingSource1.SupportsSearching返回false。 Find函数适用于其他想要实现支持搜索的IBindingList接口的类。

要获得值,您应该bindingSource1.ToList().Find("Bar",5);

答案 2 :(得分:0)

已接受的答案提示了此问题的答案。在IBindingList上未实现查找。您需要在自己的类中继承IBindingList并实现find。您还需要使用和重写SupportsSearchingCore来表示支持查找。这是问题的实际答案,例如如何使Find在BindingList上工作。

public class EfBindingList<T> : BindingList<T>
    where T : class
{
    public EfBindingList(IList<T> lst) : base(lst)
    {
    }

    protected override bool SupportsSearchingCore
    {
        get { return true; }
    }

    protected override int FindCore(PropertyDescriptor prop, object key)
    {
        var foundItem = Items.FirstOrDefault(x => prop.GetValue(x) == key);
        // Ignore the prop value and search by family name.
        for (int i = 0; i < Count; ++i)
        {
            var item = Items[i];
            if (prop.GetValue(item).ToString() == key.ToString()) return i;
        }
        return -1;
    }
}

实现此类后,以下工作

bsOrder.DataSource = new EfBindingList<OrderDto>(lstOrder);
var oldIndex = bsOrder.Find(keyName, id);