Я все еще работаю над этим, но как насчет этого:
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);
}
}
Идея состоит в том, что вы наследуете от ObservableCollection и вместо того, чтобы манипулировать копиями данных, вы просто манипулируете ссылками на ваши данные. Таким образом, когда ваша строка обновляется в таблице данных, она будет обновляться и в вашей ObservableCollection (хотя события ObservableCollection не будут запускаться).
Из-за обобщений это также должно работать для Typed DataTables и предоставлять вам доступ к свойствам DataRow (включая DataColumns).
Теоретически это также должно позволить вам использовать ObservableCollection в качестве прокси для вашей таблицы данных для добавления / удаления / изменения содержимого.
Очевидно, так как я все еще работаю над этим для своего проекта, вполне возможно, что я, возможно, пропустил что-то большое, но на данный момент я не понимаю, почему это не сработает (так как я почти уверен, что Rows [Index] .Delete () устанавливает свойство DataRowState вместо фактического удаления объекта DataRow).