zoukankan      html  css  js  c++  java
  • WinForm中实体类批量修改、批量提交辅助类

        在WinForm项目开发中习惯于对于集合数据的批量修改,再一次性提交更新同步到数据库。这里我们就必须实现对对象的改变的跟踪记录,我们实现对象的改变跟踪有许多方式,大致我尝试了两种方式:1:对象强制实现接口,State守信和MakeMark行为。2:利用字典序继续改变。虽然1的方式是否更加合理,但是在winform中与BindingSource集合使用简化修增修改的书写,配合的不是很好,供给开发人员使用不是很爽。于是我修改成为第二种方式集合记录更改,在继续在原集合真实修改,触发BindingSource事件和与BindingSource很好的结合。

       我们所要做的是对集合实体的变化做记录,这个在微软类库中的System.Data.DataTable一样,利用一套变化记录机制,我们可以抽象出我们接口:

    public interface IObjectObserveable

    {

    bool IsCanReject

    {

    get;

    }

    void AcceptChanged();

    void RejectChanged();

    event ObjectCollectionChanged objectCollectionChanged;

    IEnumerable<KeyValuePair<object, ObjectObserveChangeState>> GetChangeds();

    IEnumerable<object> GetChangeds(ObjectObserveChangeState changedState);

    }

    public enum ObjectObserveChangeState

    {

    None, Add, Modify, Delete

    }
    接口中: 

    1:包含守信IsCanReject表示是否可以回滚(必须是可序列化的集合者可以回滚,内部利用序列化实现单级撤销)。

    2:AcceptChanged表示接受更改。

    3:RejectChanged拒绝更改回滚。

    4:GetChangeds获取数据集合的更改或者某类型更改的集合。

    数据更改通知事件:

    View Code
    public class ObjectCollectionChangedEventArgs : EventArgs
        { 

            public ObjectObserveChangeState ChangeState
            {
                get;
                private set;
            } 

            public object ItemValue
            {
                get;
                private set;
            } 

            public ObjectCollectionChangedEventArgs(ObjectObserveChangeState changeState, object itemValue)
            {
                this.ChangeState = changeState;
                this.ItemValue = itemValue;
            }
        } 

        public delegate void ObjectCollectionChanged(object sender, ObjectCollectionChangedEventArgs e);

    最后对于List集合的实现如下: 

    View Code
    public class ObjectObserveCollection : IList, IDisposable, IObjectObserveable

    {

    private IList collection;

    private Dictionary<object, ObjectObserveChangeState> itemChangedCollection = new Dictionary<object, ObjectObserveChangeState>();

    public event ObjectCollectionChanged objectCollectionChanged = null;

    private byte[] _seriable;

    public ObjectObserveCollection(IList list)

    {

    collection = list;

    IsCanReject = list.GetType().IsSerializable;

    if (IsCanReject)

    {

    try

    {

    _seriable = UtilsSerializer.BinarySerializer(list);

    }

    catch (Exception ex)

    {

    IsCanReject = false;

    }

    }

    try

    {

    RegisterNotifyPropertyChanged(list.OfType<INotifyPropertyChanged>());

    }

    catch (Exception ex)

    {

    throw new Exception("The collection model must implement the interface of INotifyPropertyChanged;");

    }

    }

    protected void RegisterNotifyPropertyChanged(IEnumerable<INotifyPropertyChanged> notifyCollection)

    {

    notifyCollection.ToList().ForEach(t =>

    {

    t.PropertyChanged += t_PropertyChanged;

    });

    }

    protected void t_PropertyChanged(object sender, PropertyChangedEventArgs e)

    {

    if (!itemChangedCollection.ContainsKey(sender))

    {

    itemChangedCollection.Add(sender, ObjectObserveChangeState.Modify);

    }

    }

    #region IList 成员

    public int Add(object value)

    {

    var index = this.collection.Add(value);

    this.OnObjectCollectionChanged(new ObjectCollectionChangedEventArgs(ObjectObserveChangeState.Add, value));

    return index;

    }

    protected void OnObjectCollectionChanged(ObjectCollectionChangedEventArgs e)

    {

    RecoredChanged(e);

    if (this.objectCollectionChanged != null)

    {

    this.objectCollectionChanged(this, e);

    }

    }

    protected void RecoredChanged(ObjectCollectionChangedEventArgs e)

    {

    switch (e.ChangeState)

    {

    case ObjectObserveChangeState.Add:

    this.itemChangedCollection.Add(e.ItemValue, e.ChangeState);

    RegisterNotifyPropertyChanged(new List<INotifyPropertyChanged>() { e.ItemValue as INotifyPropertyChanged });

    break;

    case ObjectObserveChangeState.Delete:

    if (itemChangedCollection.ContainsKey(e.ItemValue))

    {

    switch (itemChangedCollection[e.ItemValue])

    {

    case ObjectObserveChangeState.Add:

    itemChangedCollection.Remove(e.ItemValue);

    break;

    default:

    itemChangedCollection[e.ItemValue] = ObjectObserveChangeState.Delete;

    break;

    }

    }

    else

    {

    itemChangedCollection.Add(e.ItemValue, ObjectObserveChangeState.Delete);

    }

    (e.ItemValue as INotifyPropertyChanged).PropertyChanged -= t_PropertyChanged;

    break;

    default:

    if (itemChangedCollection.ContainsKey(e.ItemValue))

    {

    itemChangedCollection[e.ItemValue] = ObjectObserveChangeState.Modify;

    }

    else

    {

    itemChangedCollection.Add(e.ItemValue, ObjectObserveChangeState.Modify);

    }

    break;

    }

    }

    public void Clear()

    {

    foreach (var item in this.collection)

    {

    OnObjectCollectionChanged(new ObjectCollectionChangedEventArgs(ObjectObserveChangeState.Delete, item));

    }

    this.collection.Clear();

    }

    public bool Contains(object value)

    {

    return this.collection.Contains(value);

    }

    public int IndexOf(object value)

    {

    return this.collection.IndexOf(value);

    }

    public void Insert(int index, object value)

    {

    this.collection.Insert(index, value);

    this.OnObjectCollectionChanged(new ObjectCollectionChangedEventArgs(ObjectObserveChangeState.Add, value));

    }

    public bool IsFixedSize

    {

    get { return this.collection.IsFixedSize; }

    }

    public bool IsReadOnly

    {

    get { return this.collection.IsReadOnly; }

    }

    public void Remove(object value)

    {

    this.collection.Remove(value);

    this.OnObjectCollectionChanged(new ObjectCollectionChangedEventArgs(ObjectObserveChangeState.Delete, value));

    }

    public void RemoveAt(int index)

    {

    var value = this.collection[index];

    this.collection.RemoveAt(index);

    this.OnObjectCollectionChanged(new ObjectCollectionChangedEventArgs(ObjectObserveChangeState.Delete, value));

    }

    public object this[int index]

    {

    get

    {

    return this.collection[index];

    }

    set

    {

    this.collection[index] = value;

    }

    }

    #endregion

    #region ICollection 成员

    public void CopyTo(Array array, int index)

    {

    this.collection.CopyTo(array, index);

    }

    public int Count

    {

    get { return this.collection.Count; }

    }

    public bool IsSynchronized

    {

    get { return this.collection.IsSynchronized; }

    }

    public object SyncRoot

    {

    get { return this.collection.SyncRoot; }

    }

    #endregion

    #region IEnumerable 成员

    public IEnumerator GetEnumerator()

    {

    return this.collection.GetEnumerator();

    }

    #endregion

    #region IDisposable 成员

    public void Dispose()

    {

    this.itemChangedCollection.Clear();

    this.itemChangedCollection = null;

    }

    #endregion

    #region IObjectObserveable 成员

    public void AcceptChanged()

    {

    this.itemChangedCollection.Clear();

    if (IsCanReject)

    {

    _seriable = UtilsSerializer.BinarySerializer(this.collection);

    }

    }

    public IEnumerable<KeyValuePair<object,ObjectObserveChangeState>> GetChangeds()

    {

    return this.itemChangedCollection.ToDictionary(t => t.Key, t => t.Value);

    }

    public IEnumerable<object> GetChangeds(ObjectObserveChangeState changedState)

    {

    return this.itemChangedCollection.Where(t => t.Value == changedState).Select(t => t.Key);

    }

    public void RejectChanged()

    {

    if (!IsCanReject)

    {

    throw new Exception(" This method required the collection type must be Serializable;");

    }

    this.collection =(IList) UtilsSerializer.BinaryDeserialize(this._seriable);

    }

    public bool IsCanReject

    {

    get;

    private set;

    }

    #endregion

    }

     

    在最后WinForm中测试: 

    View Code
    using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Data;

    using System.Drawing;

    using System.Linq;

    using System.Text;

    using System.Windows.Forms;

    using Green.Utility;

    using Green.Config.FrameWork;

    namespace WindowsFormsApplication1

    {

    public partial class Form3 : Form

    {

    public Form3()

    {

    InitializeComponent();

    }

    ObjectObserveCollection stus;

    int count = 0;

    private void Form3_Load(object sender, EventArgs e)

    {

    var list = new List<Student>();

    list.Add(GeneratorStu());

    stus = new ObjectObserveCollection(list);

    bs = new BindingSource() { DataSource = stus };

    dataGridView1.DataSource = bs;

    }

    BindingSource bs = null;

    public Student GeneratorStu()

    {

    return new Student() { ID = ++count, Name = count.ToString() };

    }

    private void button4_Click(object sender, EventArgs e)

    {

    stus.AcceptChanged();

    }

    private void button1_Click(object sender, EventArgs e)

    {

    var model=bs.AddNew() as Student;

    model.ID = ++count;

    model.Name = count.ToString();

    }

    private void button2_Click(object sender, EventArgs e)

    {

    if (bs.Position != -1)

    {

    bs.RemoveCurrent();

    }

    }

    private void button3_Click(object sender, EventArgs e)

    {

    var add = stus.GetChangeds(ObjectObserveChangeState.Add).ToList();

    var delete = stus.GetChangeds(ObjectObserveChangeState.Delete).ToList();

    var update = stus.GetChangeds(ObjectObserveChangeState.Modify).ToList();

    }

    }

    [Serializable]

    public class Student : INotifyPropertyChanged

    {

    private int _ID;

    public int ID

    {

    get { return _ID; }

    set

    {

    if (_ID != value)

    {

    _ID = value;

    OnPropertyChanged("ID");

    }

    }

    }

    private string _Name;

    public string Name

    {

    get { return _Name; }

    set

    {

    if (_Name != value)

    {

    _Name = value;

    OnPropertyChanged("Name");

    }

    }

    }

    private void OnPropertyChanged(string p)

    {

    if (this.PropertyChanged != null)

    {

    this.PropertyChanged(thisnew PropertyChangedEventArgs(p));

    }

    }

    #region INotifyPropertyChanged 成员

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    }

    }

    对于新增和删除我们只需利用BindingSource的,bs.AddNew() 和bs.RemoveCurrent();感觉使用起来方便了吧。最后获取数据更改利用GetChangeds。对于保存后AcceptChanges。 

    效果图:

    欢迎大家指正和建议,希望能够共同进步,谢谢。

  • 相关阅读:
    python变量和常量
    python运算符
    python 数据类型强制转换
    Python 变量的缓存机制
    Python格式化输出
    Python 自动类型转换
    Python 六大标准基础数据类型
    Python 基础
    pyhton 初识
    计算机基础
  • 原文地址:https://www.cnblogs.com/whitewolf/p/2419289.html
Copyright © 2011-2022 走看看