Wpf 将数据集转换为可观察集合
我试图将一个数据集绑定到一个列表框..当然是因为我想在一个数据模板中显示两个表信息..但是这似乎不可能,我必须将其转换为一个可观察的集合。但是我该怎么做呢?我的bl返回数据集对象。我该如何将其转换为可观察的集合。。?有什么方法可以让我在MVVM中处理这种情况吗。。?人们如何在MVVM体系结构中处理数据集?数据集是一组表的.Net表示形式,以及它们之间的关系。它有点像微型数据库的内存中代码可访问表示。只有少数几个控件可以直接绑定到数据集-这些控件被编码为分析数据集和表之间的关系,并以某种层次结构显示(如树状视图或层次结构网格)表示各种表的数据,任何需要简单项目列表的控件,由于每个项的一个或两个属性不能直接绑定到dataste,因此只能绑定到其中一个包含的DataTableWpf 将数据集转换为可观察集合,wpf,mvvm,listbox,dataset,Wpf,Mvvm,Listbox,Dataset,我试图将一个数据集绑定到一个列表框..当然是因为我想在一个数据模板中显示两个表信息..但是这似乎不可能,我必须将其转换为一个可观察的集合。但是我该怎么做呢?我的bl返回数据集对象。我该如何将其转换为可观察的集合。。?有什么方法可以让我在MVVM中处理这种情况吗。。?人们如何在MVVM体系结构中处理数据集?数据集是一组表的.Net表示形式,以及它们之间的关系。它有点像微型数据库的内存中代码可访问表示。只有少数几个控件可以直接绑定到数据集-这些控件被编码为分析数据集和表之间的关系,并以某种层次结构显
或者,您需要动态构造并填充您自己的datatable,该datatable是从您正在使用的数据集中的各种表构造的,以正确地服务于要将其绑定到的特定控件 以下是如何将数据表转换为可观察的集合:
没有内置函数或强制转换可以将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