i am currently working on POS & Inventory Application , i am loading the products and stocks available data from the databse to dataset then dataset to obseravable collection . finally obseravable collection is binded to UI Controls like Data grid and List view.
Now , i want to update the changes made in observable collection by the user using UI Controls to data set and then to database file (SDF) ... please , show the possible coding to update the dataset from observable collection as observable collection changes
One of our friend in this forum gave a example to convert dataset to obseravable collection . i tried that and worked well .
code goes like this 1. Person class to hold My Person dat开发者_如何学JAVAa:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
Then used LINQ to populate My ObservableCollection:
var people = new ObservableCollection<Person>(
dataset.Tables["Person"].AsEnumerable().Select(p => new Person
{
Id = p.Field<int>("Id"),
Name = p.Field<string>("Name"),
Age = p.Field<int>("Age")
}));
its working well, now, moving further i want to update back dataset from obseravable collection as ObseravableCollection changes in UI Datagrid entries changes
please explain me about possible coding to achieve this task.
I see two options
first you can subscribe to PropertyChanged event of every object in ObservableCollection, and to CollectionChanged event of ObservableCollection to keep this 2 data structures in synch
and second, which is more easy to implement I think, is to create property with unchanged,added, modified,deleted enum vales in your class, set this property depending user actions, and convert this to DataSet when saving
EDIT
Here is a simple implementation for second method
create enum like this
public enum DataObjectState
{
Unchanged,
Added,
Modified,
Deleted
}
Than add property to your class like this
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public DataObjectState ObjectState{get;set;}
}
after which you can create ObservableCollection form dataset like you show
dataset.Tables["Person"].AsEnumerable().Select(p => new Person
{
Id = p.Field<int>("Id"),
Name = p.Field<string>("Name"),
Age = p.Field<int>("Age"),
ObjectState = ConvertRowStateToObjectState(p.RowState)
}));
and can convert from observablecollection to dataset by using opposite query
EDIT
private DataObjectState ConvertRowStateToObjectState(DataRowState dataRowState)
{
return (DataObjectState)Enum.Parse(typeof(DataObjectState), dataRowState.ToString());
}
I doesn't find a way to create dataset with Linq too, but here is a bit hack method to do what you want
DataTable personsTable = new DataTable("Person");
personsTable.Columns.Add("Id", typeof(int));
personsTable.Columns.Add("Name", typeof(string));
personsTable.Columns.Add("Age", typeof(int));
foreach (var item in collection)
{
DataRow row = personsTable.NewRow();
row["Id"] = item.Id;
row["Name"] = item.Name;
row["Age"] = item.Age;
personsTable.Rows.Add(row);
if (item.ObjectState == DataObjectState.Added)
{
continue;
}
row.AcceptChanges();
if (item.ObjectState == DataObjectState.Deleted)
{
row.Delete();
}
else if (item.ObjectState == DataObjectState.Modified)
{
row.BeginEdit();
row.EndEdit();
}
}
Beside @ArsenMkrt-s solution you can also think of using a strong typed dataset that will have a PersonTable-class instead of the observable Collection and a PersonRow-class instead of your current Person-Class.
These can be bound to a datagrid, too.
The benefit: no conversion-code required.
you can use a filtered collectionviewsource for 2 good thinks : 1-it's not a new collection (less memory need). 2-it's like collection of pointers upon your Table with 2 ways databinding capability.
精彩评论