2010-01-07 108 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对象)。