嗨,我想做类似的事情SomeCollection.GetChanges(ItemState.Deleted)
,结果应该是所有被删除的项目
你可以用DataTable
. 但是如何在List<T>
or中实现这一点ObservableCollection<T>
?
这个问题已经有解决方案了吗?如果不是,创建这样一个集合是否明智?
任何意见是极大的赞赏
编辑:
到目前为止,这是我的代码,我现在已经测试并修复了它,但我仍然认为可能有更好的解决方案
using System;
using System.Linq;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections;
using System.ComponentModel;
namespace Framework
{
public enum CollStat
{
Unchanged,
Added,
Replacer,
Replaced,
Deleted,
Modified
}
public class NotifyObservableCollection<T> : ObservableCollection<T> where T : Notifyer
{
#region private
private class _ElementKeeper<T>
{
public T Element;
public CollStat Modification;
public _ElementKeeper(T element, CollStat Modifi)
{
Element = element;
Modification = Modifi;
}
}
private int _ChangesIdx = 0;
private bool _Reject = false;
private Dictionary<int, _ElementKeeper<T>> DicOfChanges = new Dictionary<int, _ElementKeeper<T>>();
#endregion //private
#region cTor (3)
public NotifyObservableCollection() : base() { }
public NotifyObservableCollection(List<T> list)
: base(list)
{
Subscribe(list);
}
public NotifyObservableCollection(IEnumerable<T> collection)
: base(collection)
{
Subscribe(collection.ToList());
}
#endregion
#region ObservableCollection override(2)
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (!_Reject)
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (T item in e.NewItems)
{
DicOfChanges.Add(_ChangesIdx, new _ElementKeeper<T>(item, CollStat.Added));
_ChangesIdx++;
}
}
else if (e.Action == NotifyCollectionChangedAction.Replace)
{
foreach (T item in e.OldItems)
{
DicOfChanges.Add(_ChangesIdx, new _ElementKeeper<T>(item, CollStat.Replaced));
_ChangesIdx++;
}
foreach (T item in e.NewItems)
{
DicOfChanges.Add(_ChangesIdx, new _ElementKeeper<T>(item, CollStat.Replacer));
_ChangesIdx++;
}
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
foreach (T item in e.OldItems)
{
DicOfChanges.Add(_ChangesIdx, new _ElementKeeper<T>(item, CollStat.Deleted));
_ChangesIdx++;
}
}
Unsubscribe(e.OldItems);
Subscribe(e.NewItems);
base.OnCollectionChanged(e);
}
protected override void ClearItems()
{
foreach (T element in this)
element.PropertyChanged -= ContainedElementChanged;
base.ClearItems();
}
#region ItemNotification
private void Subscribe(ICollection iList)
{
if (iList != null)
foreach (T element in iList)
element.PropertyChanged += ContainedElementChanged;
}
private void Unsubscribe(ICollection iList)
{
if (iList != null)
foreach (T element in iList)
element.PropertyChanged -= ContainedElementChanged;
}
private void ContainedElementChanged(object sender, PropertyChangedEventArgs e)
{
var item = sender as T;
if (DicOfChanges.Count < 1)
{
DicOfChanges.Add(_ChangesIdx, new _ElementKeeper<T>(item, CollStat.Modified));
_ChangesIdx++;
}
else if (!DicOfChanges.Any(x => (x.Value.Element == item && x.Value.Modification == CollStat.Modified)))
{
DicOfChanges.Add(_ChangesIdx, new _ElementKeeper<T>(item, CollStat.Modified));
_ChangesIdx++;
}
OnPropertyChanged(e);
}
#endregion //ItemNotification
#endregion //ObservableCollection override(2)
/// <summary>
/// Accepts all Changes they are made to this Object
/// </summary>
public void AcceptChanges()
{
DicOfChanges.Clear();
_ChangesIdx = 0;
}
/// <summary>
/// Undoes
/// </summary>
public void RejectChanges()
{
_Reject = true;
for (int i = _ChangesIdx; i >= 0; i--)
{
if (DicOfChanges[i].Modification == CollStat.Added)
this.Items.Remove(DicOfChanges[i].Element);
else if (DicOfChanges[i].Modification == CollStat.Deleted)
this.Items.Add(DicOfChanges[i].Element);
else if (DicOfChanges[i].Modification == CollStat.Replacer)
{
var idx = this.Items.IndexOf(DicOfChanges[i - 1].Element);
this.Items[idx] = DicOfChanges[i].Element;
}
}
_Reject = false;
AcceptChanges();
}
/// <summary>
/// Returns a ObservableCollection with Elements they match the CollStat type
/// </summary>
/// <param name="stat">CollStat of the elements</param>
/// <returns>ObservableCollection with the requested Elements</returns>
public ObservableCollection<T> GetChanges(CollStat stat)
{
ObservableCollection<T> CollOfChanges = new ObservableCollection<T>();
switch (stat)
{
case CollStat.Added:
//Alle hinzugefügten Elemente auswählen
CollOfChanges = CollOfStat(CollStat.Added);
//Alle gelöschten Elemente auswählen
var Deleted = DicOfChanges.Where(x => (x.Value).Modification == CollStat.Deleted);
//Entfernen dieser Elemente sollten sie in CollOfChanges vorhanden sein
foreach (KeyValuePair<int, _ElementKeeper<T>> pair in Deleted)
if (CollOfChanges.Contains(pair.Value.Element))
CollOfChanges.Remove(pair.Value.Element);
break;
case CollStat.Deleted:
CollOfChanges = CollOfStat(CollStat.Deleted);
break;
case CollStat.Modified:
CollOfChanges = CollOfStat(CollStat.Modified);
break;
case CollStat.Replacer:
CollOfChanges = CollOfStat(CollStat.Replacer);
break;
case CollStat.Replaced:
CollOfChanges = CollOfStat(CollStat.Replaced);
break;
case CollStat.Unchanged:
CollOfChanges = new ObservableCollection<T>(this);
var Added = DicOfChanges.Where(x => (x.Value).Modification == CollStat.Added);
foreach (KeyValuePair<int, _ElementKeeper<T>> pair in Added)
CollOfChanges.Remove(pair.Value.Element);
Added = null;
Deleted = DicOfChanges.Where(x => (x.Value).Modification == CollStat.Deleted);
foreach (KeyValuePair<int, _ElementKeeper<T>> pair in Deleted)
CollOfChanges.Remove(pair.Value.Element);
Deleted = null;
var Modified = DicOfChanges.Where(x => (x.Value).Modification == CollStat.Replacer);
foreach (KeyValuePair<int, _ElementKeeper<T>> pair in Modified)
CollOfChanges.Remove(pair.Value.Element);
Modified = null;
break;
default:
break;
}
return CollOfChanges;
}
/// <summary>
/// Creats a ObservableCollection that contains all Elements from the overhanded CollStat Type
/// </summary>
/// <param name="stat">CollStat Type</param>
/// <returns>ObservableCollection</returns>
private ObservableCollection<T> CollOfStat(CollStat stat)
{
var Coll =new ObservableCollection<T>();
var Modified = DicOfChanges.Where(x => (x.Value).Modification == stat);
//Hinzufügen dieser Elemente
foreach (KeyValuePair<int, _ElementKeeper<T>> pair in Modified)
Coll.Add(pair.Value.Element);
return Coll;
}
}
}
我仍然认为 Linq 太多了。任何改善性能的建议将不胜感激
编辑2:
我在这里找到了一个解决方案,它包含了我想要的更多但仍然比我更好的解决方案:D