Reputation: 18040
I was trying to bind a dataset to a listbox..certainly because i want to display a couple of tables information in a datatemplate..But this seems not possible and i will have to convert it to an observable collection.But how can i do it.My bl returns dataset objects.How can i convert this to observablecollection..? Is there any way so that i can handle this situation in MVVM..? How do people handle datasets in MVVM architecture..?
Upvotes: 2
Views: 13492
Reputation: 636
Here is the code from Datatable to ObservabaleColleaction as @Hasan Fahim suggested...
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"])
}));
Upvotes: 1
Reputation: 591
I'm still working on it, but how about something like this:
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);
}
}
The idea is that you inherit from ObservableCollection and rather than manipulating copies of the data you simply manipulate the references to your data. This way, when your Row is updated in the datatable it will be updated in your ObservableCollection as well (though no ObservableCollection events will be fired).
Because of the generics, this also should work for Typed DataTables and provide you access to the DataRow's properties (including DataColumns).
This should also, in theory, allow you to use the ObservableCollection as a proxy to your DataTable for Add/Delete/Modify stuff.
Obviously, since I am still working on this for my project, it is entirely possible that I may have missed something big, but as of this moment, I don't see why this wouldn't work (as I'm pretty sure that Rows[Index].Delete() set the DataRowState property instead of actually Deleting the DataRow object).
Upvotes: 0
Reputation: 3885
Here is how you convert a datatable to an observable collection:
There is no built-in function or cast with which you can convert a datatable to an observablecollection
Upvotes: 2
Reputation: 146603
A DataSet is a .Net representation of a set of tables, and the relationahips between them. It is kind of like an in-memory code-accessible representation of a mini-database. Only a few controls can bind directly to a dataset - those that are coded to analyze the relationships between the datasets tables and represent the various tables' data in some kind of hiearchical display, (like a treeview or a hiearchical grid) Anything that requires a simple list of items, with one or two properties for each item can not be bound directly to a dataste, it can only be bound to one of the contained datatables.
Alternatively, you need to dynamically construct and populate a datatable of your own, constructed from the various tables in the dataset you are using, to properly service the specific control you want to bind it to.
Upvotes: 2