1

使用 Windows 表单和 linq to Sql,我将一个 datagridview 绑定到 Products Table,我添加到表单 1 Textbox 以输入搜索到的文本。我想知道如何根据输入的文本定位 datagridview 以查找给定的 ProductName。这里我不想过滤行,我只想在输入每个字符后重新定位数据网格,使用的代码:

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        var searchValue = textBox1.Text.Trim().ToUpper();
        var qry = (from p in dc.Products
                   where p.ProductName.ToUpper().StartsWith(searchValue)
                   select p).ToList();
        int itemFound = productBindingSource.Find("ProductName", searchValue);
        productBindingSource.Position = itemFound;
    }

代码的执行给出了下一个错误: System.NotSupportedException 未处理:

int itemFound = productBindingSource.Find("ProductName", searchValue);

请问有什么想法吗?

4

1 回答 1

2

MSDN 文档BindingSource有答案:

Find 方法只能在底层列表是实现了搜索的 IBindingList 时使用。此方法只是将请求引用到基础列表的 IBindingList.Find 方法。例如,如果基础数据源是 DataSet、DataTable 或 DataView,则此方法将 propertyName 转换为 PropertyDescriptor 并调用 IBindingList.Find 方法。Find 的行为,例如没有找到匹配项时返回的值,取决于底层列表中方法的实现。

当您在其基础数据源未实现 IBindingList 的 BindingSource 上调用此方法时,您会看到异常(由IBindingList.FindCore的默认实现抛出:

System.NotSupportedException:不支持指定的方法。

您没有显示将绑定源绑定到的内容,但显然它没有实现此方法。

令人讨厌的是,用于数据源BindingList<T>推荐列表类型不提供FindCore实现。

如果您使用的是 BindingList,则需要创建自己的自定义类型。这是支持查找的 BindingList 的绝对简单实现的代码:

public class FindableBindingList<T> : BindingList<T>
{

    public FindableBindingList()
        : base()
    {
    }

    public FindableBindingList(List<T> list)
        : base(list)
    {
    }

    protected override int FindCore(PropertyDescriptor property, object key)
    {
        for (int i = 0; i < Count; i++)
        {
            T item = this[i];
            if (property.GetValue(item).Equals(key))
            {
                return i;
            }
        }
        return -1; // Not found

    }
}

您可以使用自己的 BindingList 实现做很多事情,例如支持排序。我将我的答案作为支持 find 方法的最低要求。如果您想了解更多信息,请搜索 SortableBindingList。


要使用此类,请执行以下操作:

var qry = (from p in dc.Products
               where p.ProductName.ToUpper().StartsWith(searchValue)
               select p).ToList();    

FindableBindingList<YourType> list = new FindableBindingList<YourType>(qry);

dataGridView1.DataSource = list;
于 2012-07-28T13:52:35.520 回答