2012-07-27 72 views
1

使用Windows窗體和LINQ to Sql,我將DataGridview綁定到Products Table,我將其添加到Form 1 Textbox中以輸入搜索到的文本。 我想知道如何根據輸入的文本來定位datagridview以查找給定的ProductName。 在這裏,我不想過濾行,我只想重新定位數據網格的每個字符輸入後,所使用的代碼:如何將datagridview定位到搜索到的文本輸入

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是在LIGNE未處理:

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

有什麼想法嗎?

+0

是否有多個項目在與輸入的文本開始的datagridview?這可能會導致例外。另外,'查找'功能只是看看列是否以提供的值開始? – 2012-07-27 16:26:08

+0

在表單加載事件中,datagrid中填充了Products表的全部內容。 – 2012-07-27 16:36:47

+0

正確,但查找是否返回多個結果? – 2012-07-27 18:29:16

回答

2

MSDN documentation for BindingSource有答案:

The Find method can only be used when the underlying list is an IBindingList with searching implemented. This method simply refers the request to the underlying list's IBindingList.Find method. For example, if the underlying data source is a DataSet, DataTable, or DataView, this method converts propertyName to a PropertyDescriptor and calls the IBindingList.Find method. The behavior of Find, such as the value returned if no matching item is found, depends on the implementation of the method in the underlying list.

當調用此方法對BindingSource的,其基本數據源沒有實現IBindingList的,那麼你看到的異常(由IBindingList.FindCore默認實現拋出:

System.NotSupportedException: The specified method is not supported.

您沒有顯示綁定綁定源的內容,但顯然沒有實現此方法。

煩惱的是,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; 
+0

感謝您的回覆,請問是否有任何最簡單的替代方法可以達到相同的目的,或者您可以解釋更多如何使用你的代碼。 – 2012-07-28 18:24:43

+0

這一切都取決於 - 因爲你沒有說你的數據源是什麼,它很難更準確。有些數據源如DataTable會自動支持Find,但如果你不能使用其中的一種(我通常會避免使用它們),最好的辦法就是實現你自己的BindingList。我會在一分鐘內給出一個更完整的例子。另外,如果您直接使用Linq-to-sql來填充網格,將會遇到麻煩,因爲這通常會讓您只讀匿名類型,適合閱讀,非常不利於書寫。 – 2012-07-28 18:47:10

+0

非常感謝您的努力。我的網格目前綁定到BindingSource控件,該控件綁定到由Linq提供給Sql Model的Products類,通常我避免使用Dataset作爲數據源,過去我更喜歡使用Entities Framework,然後我注意到使用Linq to Sql給了我更好的性能和更少的複雜性,所以我在我的項目中採用了Linq to SQL Classes。由於BindingList是我以前從未知道的東西,因此我需要花一些時間閱讀它,然後返回來嘗試您的提議並提供反饋。我再次感謝您的幫助。 – 2012-07-29 01:08:49

相關問題