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。 

效果圖:

歡迎大家指正和建議,希望能夠共同進步,謝謝。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM