2012-07-30 58 views
4

使用绑定到绑定到LINQ to SQL类的BindingSource控件的datagridview,我想知道如何将bindingSource定位到特定记录,也就是说,当我在文本框中键入产品名称时,bindingsource应该转移到该特定产品。这里是我的代码:如何通过代码将BindingSource移动到特定记录

在我的形式FrmFind:

NorthwindDataContext dc; 
    private void FrmFind_Load(object sender, EventArgs e) 
    { 
     dc = new NorthwindDataContext(); 

     var qry = (from p in dc.Products 
        select p).ToList(); 

     FindAbleBindingList<Product> list = new FindAbleBindingList<Product>(qry); 

     productBindingSource.DataSource = list.OrderBy(o => o.ProductName); 
    } 

    private void textBox1_TextChanged(object sender, EventArgs e) 
    { 
     TextBox tb = sender as TextBox; 

     int index = productBindingSource.Find("ProductName", tb.Text); 

     if (index >= 0) 
     { 
      productBindingSource.Position = index; 
     } 
    } 

在节目类:

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)) 
       if (property.GetValue(item).ToString().StartsWith(key.ToString())) 
       { 
        return i; 
       } 
      } 
      return -1; // Not found 
     } 
    } 

我如何能实现find方法,使其工作?

+0

设置Position属性。 http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.position.aspx – 2012-07-30 00:13:35

+0

我已经检查过该链接,它不回答我的问题。 – 2012-07-30 00:18:41

+0

也许这会更有帮助http://msdn.microsoft.com/en-us/library/ms158165.aspx – 2012-07-30 00:22:31

回答

10

您可以将BindingSource.Find()方法与Position属性结合使用。

举例来说,如果你有这样的事情在你的文本框更改的事件处理程序:

private void textBox1_TextChanged(object sender, EventArgs e) 
{ 
    TextBox tb = sender as TextBox; 
    int index = bs.Find("Product", tb.Text); 

    if (index >= 0) 
    { 
     bs.Position = index; 
    } 
} 

当然这将取决于很多事情,如特定实现查找方法,为数据源绑定源有。

在你刚才问过的一个问题中,我给了你一个关于完全匹配的Find的实现。下面是一个稍微不同的实现,将着眼于物业开始被检查:

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

请注意,上面的方法是区分大小写的 - 你可以改变StartsWith是情况下,如果你需要不敏感。需要注意的.Net的工作方式


一个关键的一点是,一个对象的实际类型是不够的所有的时间 - 声明的类型是什么耗时代码知道。

这就是为什么在调用Find方法时出现NotSupported异常,即使BindingList实现具有Find方法 - 接收此绑定列表的代码不知道Find。

其原因是在这些行的代码:

dc = new NorthwindDataContext(); 

var qry = (from p in dc.Products 
      select p).ToList(); 

FindAbleBindingList<Product> list = new FindAbleBindingList<Product>(qry); 

productBindingSource.DataSource = list.OrderBy(o => o.ProductName); 

当设置为您包括扩展方法OrderBy绑定源数据源 - 检查,这表明它返回IOrderedEnumerable,和接口描述here在MSDN上。请注意,此接口没有Find方法,因此即使底层FindableBindingList<T>支持查找绑定源不知道它。

有几种解决方案(最好是在我看来,延长您FindableBindingList也支持分类和排序列表),但最快的为您当前的代码是较早像这样排序:

dc = new NorthwindDataContext(); 

var qry = (from p in dc.Products 
      select p).OrderBy(p => p.ProductName).ToList(); 

FindAbleBindingList<Product> list = new FindAbleBindingList<Product>(qry); 

productBindingSource.DataSource = list; 

在WinForms中,对于您正在尝试执行的操作,没有完全开箱即用的解决方案 - 它们都需要一些自定义代码,您需要将它们放在一起才能符合您自己的要求。

+0

我已经在我的项目中实现了BindingList,正如之前所建议的,现在我在查询查找之前将列表传递给bindingsource控件。当我运行上面的代码时,我又遇到了异常:System.NotSupportedException未处理 Source = System StackTrace: at System.ComponentModel.BindingList'1.FindCore(PropertyDescriptor prop,Object key) at System.ComponentModel.BindingList '1.System.ComponentModel.IBindingList.Find(PropertyDescriptor prop,Object key),有什么想法吗? – 2012-07-30 23:31:35

+0

所以你得到相同的异常 - 你还没有实现find方法。在这一点上,帮助你变得非常困难,你似乎在做很多你没有告诉我们的事情,然后发布与你得到的错误无关的问题。它有一个支持查找的绑定列表,然后您可以查找并索引并设置该索引的位置。 – 2012-07-31 06:33:37

+0

我将回顾一下BindingList的实现。大卫,也许正如你所说的那样,我在这里没有提到的东西,使得这个错误出现。我第一次在Filter方法上发布了一个问题,并且第二次在Find方法上发布了一个问题,我认为这没有什么坏处。我不会隐藏自己的喜悦在这个主题中找到你,因为感谢你,我学到了有趣的东西。当你确定你说了什么,然后我请你耐心等待一会儿。从我的角度来看,我相信在你的协助下我们可以澄清这个问题。 – 2012-07-31 13:14:49

1

我采取了不同的方法。我想通过编程,必须检查每个记录,直到找到匹配项,所以我只是使用MoveNext方法进行迭代,直到找到匹配项为止。不确定起始位置是否是第一条记录,所以我使用MoveFirst方法确保是。

有一个假设,那就是您正在搜索的内容在该列中是唯一的。在我的情况下,我正在寻找匹配一个身份整数。

int seekID;   
this.EntityTableBindingSource.MoveFirst(); 
if (seekID > 0) 
{ 
    foreach (EntityTable sd in EntityTableBindingSource) 
    { 
     if (sd.ID != seekID) 
     { 
      this.t_EntityTableBindingSource.MoveNext(); 
     } 
     else 
     { 
      break; 
     } 
     } 
} 
相关问题