2012-07-30 61 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; 
     } 
     } 
} 
相關問題