參考博客下方:http://www.cnblogs.com/wuhuacong/archive/2010/05/31/1748579.html
對於一般常用到的編輯數據、新增數據窗體,分開了兩個不同的窗體進行處理,而且由於BaseForm窗體沒有對通用的函數進行進一步的抽象,因此,編輯及新增窗體多了很多重復累贅的代碼,其實可以把新增、編輯合並一個窗體,然后根據新增、編輯兩種不同的條件進行處理即可。
由於BaseForm一般需要在大多數的窗體中,而新增編輯數據窗體一般較為特殊一點,可以再增加一個基類BaseEditForm,用來做新增編輯窗體的基類,該基類繼承自BaseForm類,工程代碼如下所示。
其中運行例子的效果如下所示:
編輯以及新增我們整合在一個窗體中,先看看該基類的設計視圖,我們在其中添加了3個按鈕(常用的添加、保存、關閉按鈕)。
窗體的代碼我大類采用了可重載的虛函數,留給子類窗體進行實現不同的處理操作,如窗體加載顯示操作、顯示數據到控件的操作、保存、新增等函數都是需要實現的,而調用邏輯以及一些通用的處理,則在基類BaseEditForm中實現,子類不用重復這些代碼,按鈕控件(添加、保存、關閉)的事件處理也已經進行了邏輯封裝,如下所示。
代碼
{
base.FormOnLoad();
if (!this.DesignMode)
{
if (!string.IsNullOrEmpty(ID))
{
this.Text = "編輯 " + this.Text;
this.btnAdd.Visible = false;//如果是編輯,則屏蔽添加按鈕
}
else
{
this.Text = "新建 " + this.Text;
}
DisplayData();
}
}
/// <summary>
/// 顯示數據到控件上
/// </summary>
public virtual void DisplayData()
{
}
/// <summary>
/// 檢查輸入的有效性
/// </summary>
/// <returns>有效</returns>
public virtual bool CheckInput()
{
return true;
}
/// <summary>
/// 清除屏幕
/// </summary>
public virtual void ClearScreen()
{
this.ID = "";////需要設置為空,表示新增
ClearControlValue(this);
this.FormOnLoad();
}
/// <summary>
/// 保存數據(新增和編輯的保存)
/// </summary>
public virtual bool SaveEntity()
{
bool result = false;
if(!string.IsNullOrEmpty(ID))
{
//編輯的保存
result = SaveUpdated();
}
else
{
//新增的保存
result = SaveAddNew();
}
return result;
}
/// <summary>
/// 更新已有的數據
/// </summary>
/// <returns></returns>
public virtual bool SaveUpdated()
{
return true;
}
/// <summary>
/// 保存新增的數據
/// </summary>
/// <returns></returns>
public virtual bool SaveAddNew()
{
return true;
}
/// <summary>
/// 保存
/// </summary>
/// <param name="close">關閉窗體</param>
private void SaveEntity(bool close)
{
// 檢查輸入的有效性
if (this.CheckInput())
{
// 設置鼠標繁忙狀態
this.Cursor = Cursors.WaitCursor;
try
{
if (this.SaveEntity())
{
MessageUtil.ShowTips("保存成功");
if (close)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
else
{
this.ClearScreen();
}
}
}
catch (Exception ex)
{
this.ProcessException(ex);
}
finally
{
// 設置鼠標默認狀態
this.Cursor = Cursors.Default;
}
}
}
private void btnAdd_Click(object sender, EventArgs e)
{
this.SaveEntity(false);
}
private void btnOK_Click(object sender, EventArgs e)
{
this.SaveEntity(true);
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
其中值得介紹的是,窗體的控件數據清空在基類窗體中通過遍歷實現了通用的數據清空操作,該部分代碼引用了“瀟湘隱者的博客(http://www.cnblogs.com/kerrycode/archive/2010/02/05/1664267.html),對此感謝。
另外,基類窗體還實現了Tab鍵的轉換,這個思路來源於即日嘎拉的代碼,但由於是基類實現,有些不同,他的放在每個具體的子類中,因此通用性有些限制。
我們重載了ProcessCmdKey(ref Message msg, Keys keyData) 函數后,就可以實現統一的回車鍵轉換了。

{
if (keyData == Keys.F5)
{
this.FormOnLoad();
}
if ((!(ActiveControl is Button)) &&
(keyData == Keys.Up || keyData == Keys.Down || keyData == Keys.Enter))
{
if (keyData == Keys.Enter)
{
System.Windows.Forms.SendKeys.Send("{TAB}");
return true;
}
if (keyData == Keys.Down)
{
System.Windows.Forms.SendKeys.Send("{TAB}");
}
else
{
SendKeys.Send("+{Tab}");
}
return true;
}
else
{
return base.ProcessCmdKey(ref msg, keyData);
}
}
最后,我們看看具體的子類窗體,看新增編輯界面需要實現的代碼,如下所示,其中大部分是原子級別的操作,邏輯操作已經在基類中實現了哦:
代碼
{
public FrmEditCustomer()
{
InitializeComponent();
}
/// <summary>
/// 實現控件輸入檢查的函數
/// </summary>
/// <returns></returns>
public override bool CheckInput()
{
bool result = true;
#region 輸入驗證
if (this.txtName.Text.Length == 0)
{
MessageUtil.ShowTips("賓客名稱不能為空");
this.txtName.Focus();
result = false;
}
else if (this.txtIDNumber.Text.Length == 0)
{
MessageUtil.ShowTips("證件號碼不能為空");
this.txtIDNumber.Focus();
result = false;
}
#endregion
return result;
}
/// <summary>
/// 編輯或者保存狀態下取值函數
/// </summary>
/// <param name="info"></param>
private void SetInfo(CustomerInfo info)
{
info.Address = txtAddress.Text;
info.CompanyName = txtCompany.Text;
info.IDCarType = cmbIDCarType.Text;
info.Name = txtName.Text;
info.Note = txtNote.Text;
info.IDNumber = txtIDNumber.Text;
info.Telephone = txtTelephone.Text;
info.Source = cmbSource.Text;
info.CustomerType = cmbType.Text;
info.Sex = cmbSex.Text;
}
/// <summary>
/// 數據字典加載
/// </summary>
private void InitDictItem()
{
this.cmbSource.Items.Clear();
this.cmbSource.Items.AddRange(DictItemUtil.GetCustomerSource());
this.cmbType.Items.Clear();
this.cmbType.Items.AddRange(DictItemUtil.GetCustomerType());
this.cmbIDCarType.Items.Clear();
this.cmbIDCarType.Items.AddRange(DictItemUtil.GetIDCarType());
}
/// <summary>
/// 數據顯示的函數
/// </summary>
public override void DisplayData()
{
//數據字典加載(公用)
InitDictItem();
if (!string.IsNullOrEmpty(ID))
{
//編輯狀態下的數據顯示
CustomerInfo info = BLLFactory<Customer>.Instance.FindByID(ID);
if (info != null)
{
#region 顯示客戶信息
txtAddress.Text = info.Address;
txtCompany.Text = info.CompanyName;
txtName.Text = info.Name;
txtNote.Text = info.Note;
txtIDNumber.Text = info.IDNumber;
txtTelephone.Text = info.Telephone;
cmbSource.Text = info.Source;
cmbType.Text = info.CustomerType;
cmbSex.Text = info.Sex;
cmbIDCarType.Text = info.IDCarType;
lblCreateDate.Text = info.RegistrationDate.ToString();
#endregion
}
}
else
{
//新增狀態的數據顯示
lblCreateDate.Text = DateTime.Now.ToString();
}
}
/// <summary>
/// 新增狀態下的數據保存
/// </summary>
/// <returns></returns>
public override bool SaveAddNew()
{
CustomerInfo info = new CustomerInfo();
SetInfo(info);
info.RegistrationDate = DateTime.Now;
bool succeed = BLLFactory<Customer>.Instance.Insert(info);
return succeed;
}
/// <summary>
/// 編輯狀態下的數據保存
/// </summary>
/// <returns></returns>
public override bool SaveUpdated()
{
CustomerInfo info = BLLFactory<Customer>.Instance.FindByID(ID);
if (info != null)
{
SetInfo(info);
bool succeed = BLLFactory<Customer>.Instance.Update(info, info.ID.ToString());
return succeed;
}
return false;
}
}