【问题标题】:BindingSource.Find throws NotSupportedException (DataSource is BindingList<T>)BindingSource.Find 抛出 NotSupportedException(数据源是 BindingList<T>)
【发布时间】:2012-06-13 14:12:48
【问题描述】:

我有一个BindingSource 附加一个BindingList&lt;Foo&gt; 作为数据源。我想使用BindingSourceFind method 来查找元素。但是,当我执行以下操作时,会抛出 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();
    }
}

【问题讨论】:

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


    【解决方案1】:

    我能够使用

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

    这样做的好处是可以看到位置以及找到对象

    【讨论】:

      【解决方案2】:

      BindingList&lt;T&gt; 不支持搜索。事实上bindingSource1.SupportsSearching 返回错误。 Find 函数用于其他想要实现支持搜索的IBindingList 接口的类。

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

      【讨论】:

      • 好的,SupportsSearchingfalse,谢谢。但是,我重新构建了我的代码,但代码略有不同:bindingSource1.List.OfType&lt;Foo&gt;().First(f =&gt; f.Bar == 5); 确实正确返回了对象,这也很好。
      • 我想使用上述的 find 方法,但是当我尝试它时,我得到以下错误 'System.Windows.Forms.BindingSource' does not contain a definition for 'ToList'
      • @kirsteng 我认为您确实使用了 .NET 2.0 或在代码文件的开头没有 using System.Linq。后者使 LINQ 扩展方法 在代码中可用。
      • 为什么要对此投反对票,这实际上是正确的,并且有部分帮助
      【解决方案3】:

      接受的答案暗示了这个问题的答案。未在 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);
      

      【讨论】:

        猜你喜欢
        • 2011-04-16
        • 2011-07-17
        • 2011-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-09
        • 2011-02-17
        相关资源
        最近更新 更多