DevExpress使用教程:常用Winform界面封裝
我們在開發(fā)Winform程序的時候,需要經(jīng)常性的對界面的一些控件進行初始化,或者經(jīng)常簡單的封裝,以方便我們在界面設計過程中反復使用。本文主要介紹在我的一些項目中常用的界面處理操作和代碼,以便為大家開發(fā)的時候提供必要的參考。
【DXperience Universal Suite安裝包下載】
1、選擇用戶的控件封裝操作
在一些系統(tǒng)模塊里面,我們需要選擇系統(tǒng)人員作為經(jīng)辦人員的操作,如下面幾個界面場景所示。
我們注意到,一般在我們選擇的時候,界面會彈出一個新的層給我們選擇,里面通過列表詳細展示相關的信息,還可以支持搜索,非常方便。
當我們完成選擇的時候,我們看到界面會只有一個人員名稱的顯示,不占用額外的地方顯示。
這種界面效果是如何實現(xiàn)的呢?下面進行詳細的介紹。
1)首先我們定義一個自定義控件,讓其繼承自XtraUserControl 即可。
/// <summary> /// 經(jīng)辦人員、操作人員的選擇控件封裝 /// </summary> public partial class OperatorSelectControl : XtraUserControl {
2)然后在DevExpress的界面工具箱上拖動一個SearchLookUpEdit 控件到我們新的用戶控件OperatorSelectControl 上。
調(diào)整好用戶界面控件的排版相關屬性,就會得到下面的界面所示。
3)在設計視圖里面,我們?yōu)檫@個SearchLookUpEdit控件的GridView設置它的顯示字段,如下所示,每個字段主要綁定FieldName(屬性或者字段)和Caption(顯示名稱)。
這些必備的處理操作完成后,我們可以通過代碼或者設計器把這個控件的顯示內(nèi)容和存儲內(nèi)容進行設定,并綁定它的數(shù)據(jù)源即可(根據(jù)需要調(diào)用自己的函數(shù)),如下所示。
private void OperatorSelectControl_Load(object sender, EventArgs e) { if (!this.DesignMode) { txtOperator.Properties.ValueMember = "ID"; txtOperator.Properties.DisplayMember = "FullName"; txtOperator.Properties.DataSource = SecurityHelper.GetSimpleUsers(); } }
4)我們?yōu)榱朔奖?,還可以進一步處理控件的顯示內(nèi)容和返回的值內(nèi)容,我們希望綁定值或者獲取值的時候,使用Text屬性就可以了,那么我們重載一下這個自定義控件的Text屬性即可。
public override string Text { get { string result = ""; if (this.txtOperator.EditValue != null) { result = this.txtOperator.EditValue.ToString(); } return result; } set { this.txtOperator.EditValue = value; } }
5)這樣控件的操作就完成了,編譯代碼后,我們在工具箱上就可以看到最新的控件圖標了。
接著我們把相關的控件拖動到需要的地方(如果是界面和控件在相同的工程里面,注意需要移除重復的工程引用),重新編譯系統(tǒng)代碼,那么本文開始的界面效果就可以出現(xiàn)了
2、會員卡級別選擇操作
剛才說了,人員選擇可以使用這種彈出列表選擇的方式,其實很多地方可以用這個方式來進行選擇,如一些相對比較少記錄的信息就很適合這種顯示方式,比如在會員管理里面的,會員卡級別的選擇,也可以采用這種方式。
這個模塊的做法也和第一種很類似,有點不同的是,我需要選擇后把會員卡的折扣也關聯(lián)顯示出來,那我們應該如何處理呢?
1)定義控件和事件處理
為了方便在控件選擇后進行事件的觸發(fā)處理,我在這里定義了一個事件處理器SelectedValueChanged。
/// <summary> /// 卡級選擇控件 /// </summary> public partial class CardGradeSelectControl : XtraUserControl { /// <summary> /// 選擇項發(fā)生變化的事件處理 /// </summary> public event EventHandler SelectedValueChanged;
然后在內(nèi)部控件的EditValue改變的時候,在其中的事件里面觸發(fā)我們自定義的事件即可, 如下所示。
private void txtCardGrade_EditValueChanged(object sender, EventArgs e) { if (SelectedValueChanged != null) { SelectedValueChanged(sender, e); } }
2)在窗體界面中自定義控件的事件調(diào)用
在會員編輯界面里面,我們對這個卡級別的選擇控件的自定義事件進行處理即可。
處理事件里面,我們獲取對應卡級別的優(yōu)惠折扣(GetDiscountByGradeNo),然后綁定到界面的控件顯示即可,這樣就實現(xiàn)了聯(lián)動效果了。
public partial class FrmEditMember : BaseEditForm { /// <summary> /// 創(chuàng)建一個臨時對象,方便在附件管理中獲取存在的GUID /// </summary> private MemberInfo tempInfo = new MemberInfo(); public FrmEditMember() { InitializeComponent(); this.txtCardGrade.SelectedValueChanged += new EventHandler(txtCardGrade_SelectedValueChanged); } void txtCardGrade_SelectedValueChanged(object sender, EventArgs e) { string gradeNo = txtCardGrade.Text; if (!string.IsNullOrEmpty(gradeNo)) { this.txtDiscount.Value = BLLFactory<CardGrade>.Instance.GetDiscountByGradeNo(gradeNo); } }
3、創(chuàng)建人員和創(chuàng)建時間的顯示處理
在我們窗體數(shù)據(jù)的編輯界面里面,為了友好顯示,我們可能需要顯示數(shù)據(jù)的創(chuàng)建人和創(chuàng)建時間。這種效果是如何實現(xiàn)的,我們來看看。
1)數(shù)據(jù)顯示時候處理
數(shù)據(jù)顯示的時候,可能是新增界面的顯示,也可以是現(xiàn)有記錄的顯示,我們需要區(qū)分對待。
如果是已有數(shù)據(jù),我們需要解析創(chuàng)建人員的ID,顯示已有時間即可;如果是新增界面,那么我們把當前登陸用戶的名稱顯示出來,及顯示當前時間即可。
在設計模式里面,把控件設置為ReadOnly=true,不用編輯修改控件的值即可。
/// <summary> /// 數(shù)據(jù)顯示的函數(shù) /// </summary> public override void DisplayData() { InitDictItem();//數(shù)據(jù)字典加載(公用) if (!string.IsNullOrEmpty(ID)) { #region 顯示信息 MemberInfo info = BLLFactory<WHC.Member.BLL.Member>.Instance.FindByID(ID); if (info != null) { tempInfo = info;//重新給臨時對象賦值,使之指向存在的記錄對象 txtHandNo.Text = info.HandNo; txtCardNo.Text = info.CardNo; txtCardCode.Text = info.CardCode; txtCardStatus.SetComboBoxItem(info.CardStatus.ToString()); txtOpenUser.Text = info.OpenUser; .............. txtCreator.Text = SecurityHelper.GetFullNameByID(info.Creator); txtCreateTime.SetDateTime(info.CreateTime); } #endregion } else {this.txtOpenDate.DateTime = DateTime.Now; this.txtHandNo.Text = IDUtils.NewId(); this.txtCreateTime.DateTime = DateTime.Now; this.txtCreator.Text = LoginUserInfo.FullName;//默認為當前登錄用戶 } this.portraitControl1.MemberID = tempInfo.ID; this.portraitControl1.BindPicture(tempInfo.ID); //tempInfo在對象存在則為指定對象,新建則是全新的對象,但有一些初始化的GUID用于附件上傳 SetAttachInfo(tempInfo); }
但用戶保存操作的時候,如果是新增數(shù)據(jù),我們需要把當前時間和當前用戶的信息記錄到數(shù)據(jù)庫里面,因此需要增加一些代碼進行數(shù)據(jù)的關聯(lián)處理。
/// <summary> /// 新增狀態(tài)下的數(shù)據(jù)保存 /// </summary> /// <returns></returns> public override bool SaveAddNew() { MemberInfo info = tempInfo;//必須使用存在的局部變量,因為部分信息可能被附件使用 SetInfo(info); info.Creator = LoginUserInfo.ID.ToString(); info.CreateTime = DateTime.Now; info.Dept_ID = LoginUserInfo.DeptId; info.Company_ID = LoginUserInfo.CompanyId; try { #region 新增數(shù)據(jù) //檢查是否還有其他相同關鍵字的記錄 bool exist = BLLFactory<WHC.Member.BLL.Member>.Instance.IsExistKey("CardNo", info.CardNo); if (exist) { MessageDxUtil.ShowTips("指定的【會員卡號】已經(jīng)存在,不能重復添加,請修改"); return false; } bool succeed = BLLFactory<WHC.Member.BLL.Member>.Instance.Insert(info); if (succeed) { //可添加其他關聯(lián)操作 return true; } #endregion } catch (Exception ex) { LogTextHelper.Error(ex); MessageDxUtil.ShowError(ex.Message); } return false; }
我們?yōu)榱朔奖?,一般是在?shù)據(jù)庫存儲人員的ID,但是列表顯示的時候,我們也就需要把對應的人員ID轉換為人員名稱了。
this.winGridViewPager1.gridView1.CustomColumnDisplayText += new DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventHandler(gridView1_CustomColumnDisplayText);
void gridView1_CustomColumnDisplayText(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs e) { if (e.Column.FieldName == "Operator" || e.Column.FieldName == "Editor" || e.Column.FieldName == "Creator") { if (e.Value != null) { e.DisplayText = SecurityHelper.GetFullNameByID(e.Value.ToString()); } } }
出處:伍華聰
慧都學院2017全新DevExpress線下研修班火熱報名中!
- WinForms控件學習+實踐的不二之選——DevExpress WinForm提升班
- 高效的MVVM開發(fā)模式,WPF開發(fā)首選培訓平臺——DevExpress WPF提升班
- 手把手將您快速開發(fā)出完美、強大的ASP應用程序——DevExpress ASP.NET提升班