Wpf 将数据集转换为可观察集合

Wpf 将数据集转换为可观察集合,wpf,mvvm,listbox,dataset,Wpf,Mvvm,Listbox,Dataset,我试图将一个数据集绑定到一个列表框..当然是因为我想在一个数据模板中显示两个表信息..但是这似乎不可能,我必须将其转换为一个可观察的集合。但是我该怎么做呢?我的bl返回数据集对象。我该如何将其转换为可观察的集合。。?有什么方法可以让我在MVVM中处理这种情况吗。。?人们如何在MVVM体系结构中处理数据集?数据集是一组表的.Net表示形式,以及它们之间的关系。它有点像微型数据库的内存中代码可访问表示。只有少数几个控件可以直接绑定到数据集-这些控件被编码为分析数据集和表之间的关系,并以某种层次结构显

我试图将一个数据集绑定到一个列表框..当然是因为我想在一个数据模板中显示两个表信息..但是这似乎不可能,我必须将其转换为一个可观察的集合。但是我该怎么做呢?我的bl返回数据集对象。我该如何将其转换为可观察的集合。。?有什么方法可以让我在MVVM中处理这种情况吗。。?人们如何在MVVM体系结构中处理数据集?

数据集是一组表的.Net表示形式,以及它们之间的关系。它有点像微型数据库的内存中代码可访问表示。只有少数几个控件可以直接绑定到数据集-这些控件被编码为分析数据集和表之间的关系,并以某种层次结构显示(如树状视图或层次结构网格)表示各种表的数据,任何需要简单项目列表的控件,由于每个项的一个或两个属性不能直接绑定到dataste,因此只能绑定到其中一个包含的DataTable


或者,您需要动态构造并填充您自己的datatable,该datatable是从您正在使用的数据集中的各种表构造的,以正确地服务于要将其绑定到的特定控件

以下是如何将数据表转换为可观察的集合:

  • 您需要创建一个包含属性的类。每个属性表示一个列 数据表。因此,您需要将属性类型设置为datatable中的列类型
  • 接下来,在视图模型中创建一个属性,您想用它绑定xaml中的任何控件。此属性应为ObservableCollection类型。可以将此属性绑定到网格。对于Listbox,您可以对字符串进行ObservableCollection并将其绑定到Listbox
  • 您可以使用LINQ在Observable集合中直接从DB填充结果,或者您也可以从datatable在Observable集合中手动添加项

  • 没有内置函数或强制转换可以将datatable转换为observablecollection

    以下是@Hasan Fahim建议的从datatable到observablecollection的代码

            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"])
      }));
    
    DataTable dtValues=newdatatable();
    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”]=“naeem”;
    dtValues.Rows.Add(dr);
    ObservableCollection值=新的ObservableCollection
    (dtValues.AsEnumerable().Select(i=>newMyClass
    {
    Value1=Convert.ToString(i[“Value1”]),
    Value2=Convert.ToString(i[“Value2”]),
    Value3=Convert.ToString(i[“Value3”]),
    Value4=Convert.ToString(i[“Value4”])
    }));
    
    我还在努力,但是像这样的东西怎么样:

    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);
        }
    }
    
    public类cDTObservable:observeCollection
    其中DTType:DataTable
    其中RowType:DataRow
    {
    私有DTType_dt;
    公共cDTObservable(DTType dt)
    :base(dt.Rows.OfType())
    {
    _dt=dt;
    }
    受保护的覆盖无效ClearItems()
    {
    _dt.Clear();
    base.ClearItems();
    }
    受保护的重写void插入项(int索引,行类型项)
    {
    如果(index>\u dt.Rows.Count)抛出新的ArgumentOutOfRangeException(“参数超出范围”);
    如果(索引==_dt.Rows.Count)
    _dt.行。添加(项目);
    其他的
    _dt.行.插入(项目,索引);
    基本插入项(索引,项目);
    }
    受保护的覆盖无效移动项(int-oldIndex、int-newIndex)
    {
    if(oldIndex>=_dt.Rows.Count | | newIndex>=_dt.Rows.Count)
    抛出新ArgumentOutOfRangeException(“参数超出范围”);
    int MyNewIndex=newIndex;//这样我就不会覆盖任何指向base.MoveItem的内容
    如果(旧索引<新索引)
    我的新索引--;
    RowType dr=(RowType)_dt.Rows[oldIndex];
    _dt.Rows.RemoveAt(旧索引);
    if(MyNewIndex==\u dt.Rows.Count)
    _dt.Rows.Add(dr);
    其他的
    _dt.Rows.InsertAt(dr,MyNewIndex);
    dr=null;
    base.MoveItem(旧索引、新索引);
    }
    受保护的覆盖void removietem(int索引)
    {
    如果(index>=\u dt.Rows.Count)抛出新的ArgumentOutOfRangeException(“参数超出范围”);
    _dt.Rows[index].Delete();//或者,如果不需要数据在数据存储中持久化,只需_dt.Rows.RemoveAt(index);
    基本删除项(索引);
    }
    受保护的覆盖无效集合项(整数索引,行类型项)
    {
    如果(index>=\u dt.Rows.Count)抛出新的ArgumentOutOfRangeException(“参数超出范围”);
    _dt.Rows.RemoveAt(索引);
    如果(索引>\u dt.Rows.Count-1)
    _dt.行。添加(项目);
    其他的
    _dt.行.插入(项目,索引);
    base.SetItem(索引,项);
    }
    }
    
    其思想是,您继承自ObservableCollection,而不是操作数据的副本,您只需操作对数据的引用。这样,当您的行在datatable中更新时,它也将在ObservableCollection中更新(尽管不会触发ObservableCollection事件)

    由于有泛型,这也适用于类型化的DataTables,并提供对DataRow属性(包括DataColumns)的访问

    理论上,这也应该允许您使用ObservableCollection作为DataTable的代理来添加/删除/修改内容

    显然,由于我仍在为我的项目进行此项工作,因此完全有可能我遗漏了一些重要的内容,但就目前而言,我不明白为什么这样做不起作用(因为我非常确定Rows[Index].Delete()设置了DataRowState属性,而不是实际删除DataRo