好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

表格批量编辑与Undo/Redo功能实现

表格批量编辑与Undo/Redo功能实现

利用EAP.Entity提供的可以Undo/Redo的列表绑定数据到DataGridView,让表格批量编辑更方便更高效。

1. 还是利用 AccountGroup表 的结构,然后得到实体AccountGroupModel:

 1       [System.Serializable()]
    2       public   class  AccountGroupModels : System.Collections.Generic.List<AccountGroupModel>
   3       {
    4  
   5           public   AccountGroupModels()
    6           {
    7           }
    8  
   9           public  AccountGroupModels(System.Collections.Generic.IEnumerable<AccountGroupModel>  collection) :
   10               base  (collection)
   11           {
   12           }
   13       }
   14  
  15       ///   <summary> 
  16       ///   <para></para> 
  17       ///   </summary> 
  18       [System.Serializable()]
   19       public   partial   class  AccountGroupModel : EAP.Entity.DataObject<AccountGroupModel>
  20       {
   21           #region  Member Property Region
  22           ///   <summary> 
  23           ///   <para>  主键  </para> 
  24           ///   </summary> 
  25          [EAP.Data.ColumnInfoAttribute(Visible =  false , Queryable =  true , DbColumn =  "  Id  "  )]
   26           public   int   Id
   27           {
   28               get 
  29               {
   30                   return  GetValue< int >( "  Id  "  );
   31               }
   32               set 
  33               {
   34                  SetValue( "  Id  "  , value);
   35               }
   36           }
   37  
  38           ///   <summary> 
  39           ///   <para>  名称  </para> 
  40           ///   </summary> 
  41          [EAP.Data.ColumnInfoAttribute(DbColumn =  "  Name  "  )]
   42           public   string   Name
   43           {
   44               get 
  45               {
   46                   return  GetValue< string >( "  Name  "  );
   47               }
   48               set 
  49               {
   50                  SetValue( "  Name  "  , value);
   51               }
   52           }
   53  
  54           ///   <summary> 
  55           ///   <para>  上级组别  </para> 
  56           ///   </summary> 
  57          [EAP.Data.ColumnInfoAttribute(DbColumn =  "  Parent  "  )]
   58           public   int   Parent
   59           {
   60               get 
  61               {
   62                   return  GetValue< int >( "  Parent  "  );
   63               }
   64               set 
  65               {
   66                  SetValue( "  Parent  "  , value);
   67               }
   68           }
   69  
  70           ///   <summary> 
  71           ///   <para>  可见性  </para> 
  72           ///   </summary> 
  73          [EAP.Data.ColumnInfoAttribute(DbColumn =  "  Visible  "  )]
   74           public   bool   Visible
   75           {
   76               get 
  77               {
   78                   return  GetValue< bool >( "  Visible  "  );
   79               }
   80               set 
  81               {
   82                  SetValue( "  Visible  "  , value);
   83               }
   84           }
   85  
  86           ///   <summary> 
  87           ///   <para>  修改者  </para> 
  88           ///   </summary> 
  89          [EAP.Data.ColumnInfoAttribute(DbColumn =  "  UpdateUser  "  )]
   90           public   string   UpdateUser
   91           {
   92               get 
  93               {
   94                   return  GetValue< string >( "  UpdateUser  "  );
   95               }
   96               set 
  97               {
   98                  SetValue( "  UpdateUser  "  , value);
   99               }
  100           }
  101  
 102           ///   <summary> 
 103           ///   <para>  修改时间  </para> 
 104           ///   </summary> 
 105          [EAP.Data.ColumnInfoAttribute(DbColumn =  "  UpdateDate  "  )]
  106           public   System.DateTime UpdateDate
  107           {
  108               get 
 109               {
  110                   return  GetValue<System.DateTime>( "  UpdateDate  "  );
  111               }
  112               set 
 113               {
  114                  SetValue( "  UpdateDate  "  , value);
  115               }
  116           }
  117           #endregion 
 118      }

2. 定义业务接口:

  1       interface   IAccountGroupManager
   2       {
   3           ///   <summary> 
  4           ///   加载Models
   5           ///   </summary> 
  6           ///   <param name="name"></param> 
  7           ///   <returns></returns> 
  8          AccountGroupModels GetModels( string   name);
   9           ///   <summary> 
 10           ///   保存
  11           ///   </summary> 
 12           ///   <param name="models">  需要保存的列表  </param> 
 13           ///   <param name="user">  更新者  </param> 
 14           void  Save(List<AccountGroupModel> models,  string   user);
  15           ///   <summary> 
 16           ///   加载所有可见的账户组
  17           ///   </summary> 
 18           ///   <returns></returns> 
 19           ValueTextList GetGroupList();
  20      }

 3. GetModels方法的实现 

  1           public  AccountGroupModels GetModels( string   name)
   2           {
   3              AccountGroupTable table =  new   AccountGroupTable();
   4              SelectStatement sql =  DataAccess.DefaultDB
   5                  .Select(table, table.AllColumns()) //  读取所有字段 
  6                  .OrderBy(table.UpdateDate.Desc); //  按修改时间倒序 
  7               if  (!name.IsNullOrEmpty()) //  如果名称不为空,添加模糊查询条件 
  8                  sql.Where(table.Name.Like( "  %  "  + name +  "  %  "  ));
   9               using  (SafeDataReader sdr =  sql.ToSafeDataReader())
  10               {
  11                  AccountGroupModels models =  new   AccountGroupModels();
  12                   while   (sdr.Read())
  13                   {
  14                      AccountGroupModel m =  new   AccountGroupModel();
  15                      m.BeginInit(); //  把model的状态设为Initializing,修改值时不会触发什么事件 
 16                      sdr.Fetch(m, table); //  把数据加载到model 
 17                       m.EndInit();
  18                       models.Add(m);
  19                   }
  20                   return   models;
  21               }
  22          }

2. 定义业务接口:

  1       interface   IAccountGroupManager
   2       {
   3           ///   <summary> 
  4           ///   加载Models
   5           ///   </summary> 
  6           ///   <param name="name"></param> 
  7           ///   <returns></returns> 
  8          AccountGroupModels GetModels( string   name);
   9           ///   <summary> 
 10           ///   保存
  11           ///   </summary> 
 12           ///   <param name="models">  需要保存的列表  </param> 
 13           ///   <param name="user">  更新者  </param> 
 14           void  Save(List<AccountGroupModel> models,  string   user);
  15           ///   <summary> 
 16           ///   加载所有可见的账户组
  17           ///   </summary> 
 18           ///   <returns></returns> 
 19           ValueTextList GetGroupList();
  20      }

 3. GetModels方法的实现 

  1           public  AccountGroupModels GetModels( string   name)
   2           {
   3              AccountGroupTable table =  new   AccountGroupTable();
   4              SelectStatement sql =  DataAccess.DefaultDB
   5                  .Select(table, table.AllColumns()) //  读取所有字段 
  6                  .OrderBy(table.UpdateDate.Desc); //  按修改时间倒序 
  7               if  (!name.IsNullOrEmpty()) //  如果名称不为空,添加模糊查询条件 
  8                  sql.Where(table.Name.Like( "  %  "  + name +  "  %  "  ));
   9               using  (SafeDataReader sdr =  sql.ToSafeDataReader())
  10               {
  11                  AccountGroupModels models =  new   AccountGroupModels();
  12                   while   (sdr.Read())
  13                   {
  14                      AccountGroupModel m =  new   AccountGroupModel();
  15                      m.BeginInit(); //  把model的状态设为Initializing,修改值时不会触发什么事件 
 16                      sdr.Fetch(m, table); //  把数据加载到model 
 17                       m.EndInit();
  18                       models.Add(m);
  19                   }
  20                   return   models;
  21               }
  22          }

 4. Save方法的实现

  1           public   void  Save(List<AccountGroupModel> models,  string   user)
   2           {
   3              Validator v =  new  Validator(); //  构建验证器 
  4               using  (DbTransaction tran = DataAccess.DefaultDB.BeginTransaction()) //  开始事务 
  5               {
   6                   foreach  ( var  m  in   models)
   7                   {
   8                      CheckModel(v, m, tran); //  验证数据 
  9                      m.UpdateUser =  user;
  10                      m.UpdateDate =  System.DateTime.Now;
  11                       if  (m.DataState ==  DataState.Created)
  12                           AddModel(m, tran);
  13                       else   if  (m.DataState ==  DataState.Modified)
  14                           UpdateModel(m, tran);
  15                       else   if  (m.DataState ==  DataState.Deleted)
  16                           DeleteModel(m, tran);
  17                   }
  18                   if  (!v.IsValid) //  验证不通过时抛出异常 
 19                       throw   new   ValidationException(v);
  20                   tran.Commit();
  21               }
  22          }

5. CheckModel方法

  1           protected   bool   Exists(AccountGroupModel model, DbTransaction tran)
   2           {
   3              AccountGroupTable table =  new   AccountGroupTable();
   4              SelectStatement sql =  DataAccess.DefaultDB
   5                  .Select(table, table.AllColumns( false  ).Count())
   6                   .SetTransaction(tran)
   7                  .Where(table.Name ==  model.Name);
   8               if  (model.DataState !=  EAP.Entity.DataState.Created)
   9                  sql.Where(table.Id !=  model.Id);
  10               return  sql.ToScalar< int >() >  0  ;
  11           }
  12  
 13           protected   void   CheckModel(Validator v, AccountGroupModel model, DbTransaction tran)
  14           {
  15               //  名称不能为空,长度不能超过64字符 
 16               if  (v.Require(model.Name,  "  Name  "  , model.DisplayIndex)
  17                  && v.MaxLength(model.Name,  64 ,  "  Name  "  , model.DisplayIndex))
  18               {
  19                   //  名称不能重复 
 20                  v.Assert(!Exists(model, tran),  "  Name  "  , model.DisplayIndex, ErrorText.Exists);
  21               }
  22              v.MaxLength(model.UpdateUser,  32 ,  "  UpdateUser  "  , model.DisplayIndex);
  23          }

 6. 窗口中的代码

 1       public   partial   class   DemoForm : KryptonForm
    2       {
    3           //  业务接口 
   4           IAccountGroupManager manager;
    5           //  实体列表 
   6          DataObjectList<AccountGroupModel> models =  new  DataObjectList<AccountGroupModel> ();
    7  
   8           public   DemoForm()
    9           {
   10               InitializeComponent();
   11               //  创建接口的实现 
  12              manager =  new  RefObjectCreator().Create<IAccountGroupManager> ();
   13               //  把实体绑定到BindingSource 
  14              accountGroupModelBindingSource.DataSource =  models;
   15              models.ListChanged +=  new  EventHandler<ListChangedEventArgs<AccountGroupModel>> (models_ListChanged);
   16               CancelEdit();
   17           }
   18  
  19           void  models_ListChanged( object  sender, ListChangedEventArgs<AccountGroupModel>  e)
   20           {
   21              btnUndo.Enabled =  models.CanUndo;
   22              btnRedo.Enabled =  models.CanRedo;
   23              btnSave.Enabled =  models.HasChanged;
   24           }
   25  
  26           void   LoadData()
   27           {
   28               //  加载上级组别的数据 
  29              ValueTextList parent =  manager.GetGroupList();
   30              parent.Insert( 0 ,  new  ValueTextPair( 0 ,  ""  ));
   31              parentBindingSource.DataSource =  parent;
   32               //  加载实现的数据 
  33              AccountGroupModels source =  manager.GetModels(txtName.Text);
   34               models.Clear();
   35              models.BeginInit(); //  加载时不触发绑定的事件 
  36               models.AddRange(source);
   37               models.EndInit();
   38              accountGroupModelBindingSource.ResetBindings( false  );
   39               CancelEdit();
   40           }
   41  
  42           void   BeginEdit()
   43           {
   44               models.BeginEdit();
   45              grid.ReadOnly =  false  ;
   46              btnNew.Enabled =  true  ;
   47              btnDelete.Enabled =  true  ;
   48              btnEdit.Enabled =  false  ;
   49              btnCancel.Enabled =  true  ;
   50              grid.StateNormal.DataCell.Back.Color1 =  Color.Empty;
   51              idDataGridViewTextBoxColumn.ReadOnly =  true  ;
   52              updateDateDataGridViewTextBoxColumn.ReadOnly =  true  ;
   53              updateUserDataGridViewTextBoxColumn.ReadOnly =  true  ;
   54           }
   55  
  56           void   CancelEdit()
   57           {
   58               models.CancelEdit();
   59              grid.ReadOnly =  true  ;
   60              btnNew.Enabled =  false  ;
   61              btnDelete.Enabled =  false  ;
   62              btnSave.Enabled =  false  ;
   63              btnUndo.Enabled =  false  ;
   64              btnRedo.Enabled =  false  ;
   65              btnEdit.Enabled =  true  ;
   66              btnCancel.Enabled =  false  ;
   67              pnlErrorInfo.Visible =  false  ;
   68              grid.StateNormal.DataCell.Back.Color1 =  SystemColors.Info;
   69              accountGroupModelBindingSource.ResetBindings( false  );
   70           }
   71  
  72           #region  工具条按钮事件
  73  
  74           private   void  btnSearch_Click( object   sender, EventArgs e)
   75           {
   76               LoadData();
   77           }
   78  
  79           private   void  btnClear_Click( object   sender, EventArgs e)
   80           {
   81               txtName.Clear();
   82           }
   83  
  84           private   void  btnEdit_Click( object   sender, EventArgs e)
   85           {
   86               BeginEdit();
   87           }
   88  
  89           private   void  btnCancel_Click( object   sender, EventArgs e)
   90           {
   91               CancelEdit();
   92           }
   93  
  94           private   void  btnSave_Click( object   sender, EventArgs e)
   95           {
   96               try 
  97               {
   98                   grid.EndEdit();
   99                  pnlErrorInfo.Visible =  false ; //  隐藏错误信息 
 100                   foreach  (DataGridViewRow r  in   grid.Rows)
  101                   {
  102                       foreach  (DataGridViewCell c  in   r.Cells)
  103                          c.ErrorText =  ""  ;
  104                   }
  105                   //  获取需要保存的实体列表 
 106                  List<AccountGroupModel> changed =  models.GetChangedItems();
  107                  manager.Save(changed,  "  Demo  "  );
  108                   LoadData();
  109               }
  110               catch   (Exception exc)
  111               {
  112                   if  (exc  is  ValidationException) //  显示验证的异常信息 
 113                   {
  114                      pnlErrorInfo.Visible =  true  ;
  115                      lblErrorInfo.Text =  ""  ;
  116                      ValidationException ve =  (ValidationException)exc;
  117                       foreach  (ErrorInfo error  in   ve.ErrorInfos)
  118                       {
  119                           if  (error.RowNum > - 1  )
  120                           {
  121                               string  text =  error.Errors.ToString();
  122                               grid.Rows[error.RowNum].Cells[FindColumn(grid, error.FiledName).Name]
  123                                  .ErrorText =  text;
  124                              lblErrorInfo.Text +=  "  [Row:  "  + (error.RowNum +  1 ) +  "  ]   " 
 125                                  + error.FiledName +  "  :  "  + text +  "  ;\r\n  "  ;
  126                           }
  127                       }
  128                   }
  129                   else 
 130                      MessageBox.Show(exc.ToString(),  "  Error  "  );
  131               }
  132           }
  133  
 134           private   void  btnNew_Click( object   sender, EventArgs e)
  135           {
  136               accountGroupModelBindingSource.AddNew();
  137           }
  138  
 139           private   void  btnDelete_Click( object   sender, EventArgs e)
  140           {
  141               if  (grid.SelectedRows.Count >  0  )
  142               {
  143                   foreach  (DataGridViewRow row  in   grid.SelectedRows)
  144                       accountGroupModelBindingSource.Remove(row.DataBoundItem);
  145               }
  146               else   if  (accountGroupModelBindingSource.Current !=  null  )
  147                   accountGroupModelBindingSource.Remove(accountGroupModelBindingSource.Current);
  148  
 149           }
  150  
 151           private   void  btnUndo_Click( object   sender, EventArgs e)
  152           {
  153               grid.EndEdit();
  154               if  (models.CanUndo) //  撤销 
 155                   SetFocused(models.Undo());
  156           }
  157  
 158           private   void  btnRedo_Click( object   sender, EventArgs e)
  159           {
  160               grid.EndEdit();
  161               if  (models.CanRedo) //  恢复 
 162                   SetFocused(models.Redo());
  163           }
  164  
 165           #endregion 
 166  
 167           ///   <summary> 
 168           ///   聚焦到发生变化的行或者单元格
  169           ///   </summary> 
 170           ///   <param name="edited"></param> 
 171           void  SetFocused(EditedObject<AccountGroupModel>  edited)
  172           {
  173              accountGroupModelBindingSource.ResetBindings( false  );
  174               grid.ClearSelection();
  175               if  (edited.NewState ==  DataState.Modified)
  176               {
  177                   int  index =  models.IndexOf(edited.DataObject);
  178                  grid.Rows[index].Cells[FindColumn(grid, edited.PropertyName).Name].Selected =  true  ;
  179               }
  180               else 
 181               {
  182                   int  index =  models.IndexOf(edited.DataObject);
  183                   if  (index != - 1  )
  184                      grid.Rows[index].Selected =  true  ;
  185               }
  186           }
  187  
 188           private  DataGridViewColumn FindColumn(DataGridView grid,  string   property)
  189           {
  190               //  根据属性名查找DataGridViewColumn 
 191               foreach  (DataGridViewColumn col  in   grid.Columns)
  192               {
  193                   if  (col.DataPropertyName ==  property)
  194                       return   col;
  195               }
  196               return   null  ;
  197           }
  198  
 199           private   void  grid_DataBindingComplete( object   sender, DataGridViewBindingCompleteEventArgs e)
  200           {
  201               int  index =  1  ;
  202               foreach  (DataGridViewRow r  in  grid.Rows) //  显示表格的行号 
 203                  r.HeaderCell.Value = index++ ;
  204           }
  205      }

7. 运行结果

示例代码下载 EntityDemo.zip

【LeanEAP.NET】精益企业应用平台----系列目录

 

 

标签:  C#

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于表格批量编辑与Undo/Redo功能实现的详细内容...

  阅读:54次