2010-01-07 110 views
2

我試圖將數據集綁定到列表框......當然,因爲我想在數據模板中顯示幾個表信息..但這似乎不可能,我將不得不將它轉換爲可觀察的collection.But我怎麼能做到這一點。我BL返回數據集objects.How我可以將其轉換爲observablecollection ..?有什麼辦法,以便我可以在MVVM中處理這種情況..?人們如何處理MVVM架構中的數據集..?將數據集轉換爲可觀察集合

回答

2

DataSet是一組表格的.Net表示,以及它們之間的關係。它就像一個小型數據庫的內存代碼可訪問表示。只有少數控件可以直接綁定到數據集 - 這些編碼是爲了分析數據集表之間的關係,並在某種類型的分層顯示中表示各種表的數據(如樹視圖或分層網格)。任何需要簡單的項目列表,每個項目的一個或兩個屬性不能直接綁定到dataste,它只能綁定到其中一個包含的數據表。

或者,您需要動態構建並填充您自己的數據表(可從您使用的數據集中的各個表構建而成),以正確地服務要綁定到的特定控件。

+0

或者您可以繼承自ObservableCollection 並在虛擬ObservableCollection 方法中管理CRUD操作,其中T:DataRow。 – William 2013-01-18 22:21:42

2

這裏是你如何轉換數據表到可觀察集合:

  1. 您需要創建一個包含屬性的類。每個屬性代表數據表中的一列 。因此,您需要將屬性的類型設置爲數據表中列的類型。
  2. 接下來,您將在您的視圖模型中創建一個屬性,並使用該屬性來綁定xaml中的任何控件。該屬性的類型爲ObservableCollection。您可以將此屬性綁定到網格。在Listbox的情況下,您可以創建一個ObservableCollection字符串並將其綁定到一個列表框。
  3. 您可以使用LINQ直接從數據庫中的Observable集合中填充結果,或者您也可以從DataTable手動添加ObservableCollection中的項目。

沒有內置函數或投用,你可以一個DataTable轉換爲一個ObservableCollection

1

下面是從DataTable中的代碼ObservabaleColleaction作爲@Hasan法希姆建議...

 DataTable dtValues = new DataTable(); 
     dtValues.Columns.Add("Value1"); 
     dtValues.Columns.Add("Value2"); 
     dtValues.Columns.Add("Value3"); 
     dtValues.Columns.Add("Value4"); 

     DataRow dr = dtValues.NewRow(); 
     dr["Value1"] = "asad"; 
     dr["Value2"] = "naeeem"; 
     dtValues.Rows.Add(dr);   


ObservableCollection Values = new ObservableCollection<MyClass> 

(dtValues.AsEnumerable().Select(i => new MyClass 
     { 

     Value1 = Convert.ToString(i["Value1"]), 
     Value2 = Convert.ToString(i["Value2"]), 
     Value3 = Convert.ToString(i["Value3"]), 
     Value4 = Convert.ToString(i["Value4"]) 
    })); 
0

我還在工作就可以了,但如何對這樣的事情:

public class cDTObservable<DTType, RowType> : ObservableCollection<RowType> 
    where DTType : DataTable 
    where RowType : DataRow 
{ 
    private DTType _dt; 

    public cDTObservable(DTType dt) 
     : base(dt.Rows.OfType<RowType>()) 
    { 
     _dt = dt; 
    } 

    protected override void ClearItems() 
    { 
     _dt.Clear(); 
     base.ClearItems(); 
    } 

    protected override void InsertItem(int index, RowType item) 
    { 
     if (index > _dt.Rows.Count) throw new ArgumentOutOfRangeException("Argument is out of range"); 
     if (index == _dt.Rows.Count) 
      _dt.Rows.Add(item); 
     else 
      _dt.Rows.InsertAt(item, index); 
     base.InsertItem(index, item); 
    } 

    protected override void MoveItem(int oldIndex, int newIndex) 
    { 
     if (oldIndex >= _dt.Rows.Count || newIndex >= _dt.Rows.Count) 
      throw new ArgumentOutOfRangeException("Argument is out of range"); 
     int MyNewIndex = newIndex; //so that I don't override anything that goes to base.MoveItem 
     if (oldIndex < newIndex) 
      MyNewIndex--; 
     RowType dr = (RowType)_dt.Rows[oldIndex]; 
     _dt.Rows.RemoveAt(oldIndex); 
     if (MyNewIndex == _dt.Rows.Count) 
      _dt.Rows.Add(dr); 
     else 
      _dt.Rows.InsertAt(dr, MyNewIndex); 
     dr = null; 
     base.MoveItem(oldIndex, newIndex); 
    } 

    protected override void RemoveItem(int index) 
    { 
     if (index >= _dt.Rows.Count) throw new ArgumentOutOfRangeException("Argument is out of range"); 
     _dt.Rows[index].Delete(); //Or if you do not need the data to persist in your data store, simply _dt.Rows.RemoveAt(index); 
     base.RemoveItem(index); 
    } 

    protected override void SetItem(int index, RowType item) 
    { 
     if (index >= _dt.Rows.Count) throw new ArgumentOutOfRangeException("Argument is out of range"); 
     _dt.Rows.RemoveAt(index); 
     if (index > _dt.Rows.Count - 1) 
      _dt.Rows.Add(item); 
     else 
      _dt.Rows.InsertAt(item, index); 
     base.SetItem(index, item); 
    } 
} 

的想法是,你inher它來自ObservableCollection,而不是操縱數據的副本,而只是簡單地操作對數據的引用。這樣,當數據表中的行更新時,它也會在ObservableCollection中更新(儘管沒有ObservableCollection事件會被觸發)。

由於泛型,這也應該適用於Typed DataTables併爲您提供對DataRow屬性(包括DataColumns)的訪問權限。

這在理論上也應該允許您使用ObservableCollection作爲DataTable的代理來添加/刪除/修改東西。很顯然,因爲我仍然在爲我的項目工作,所以我可能錯過了一些很大的東西,但是就目前而言,我不明白爲什麼這樣做不起作用(因爲我' m很確定行[Index]。Delete()設置DataRowState屬性而不是實際刪除DataRow對象)。