现在的位置: 首页 > 综合 > 正文

【LeanEAP.NET】精益企业应用平台实战—-表格批量编辑与Undo/Redo功能实现

2013年02月27日 ⁄ 综合 ⁄ 共 9071字 ⁄ 字号 评论关闭

 

 

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

 

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

View Code

  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         }

 

 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. 窗口中的代码

View Code

  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】精益企业应用平台----系列目录

 

抱歉!评论已关闭.