玩轉控制元件:封裝Dev的SearchLookupEdit
鳴謝
隨著前面幾個章節對控制元件封裝與擴充套件的分享,不少小夥伴兒們在作者公眾號上反饋,並聯系作者,表示通過這些系列和原始碼能學到不少細節上的東西,並運用到了自己的實際專案當中,也有不少夥伴兒反饋更好更優的處理方式。作者在此感謝大家的陪伴與探討,希望能與大家一起學習,一起進步。
工欲善其事必先利其器
公眾號反饋最多的是《玩轉控制元件:封裝Dev的LabelControl和TextEdit》,表示運用到自己實際專案後,確實大大減少了自己的工作量,並希望能有更多這種型別的博文。為了滿足小夥伴兒的心願,作者後續會分享更多自己實際專案運用到的小技巧,希望能對更多小夥伴兒有更多的幫助和啟發。最後,也希望小夥伴兒們能從作者分享對不同型別控制元件的封裝中舉一反三,擴充套件滿足自己實際業務的外掛。有好的想法,別忘記分享給作者哦,三人行,必有我師嘛~
Talk is Cheap
廢話不多說,今天作者要分享的也是作者實際專案中遇到的問題——有資料來源的下拉搜尋框。不少大的企業反饋,公司職員比較多,資料量比較大,滑鼠下拉尋找太過繁瑣和耗時,能不能提供個更優的處理方式。經過作者一番思索,以迅雷不及掩耳盜鈴響叮噹之勢就找到了符合客戶的處理方式——就是Dev的SearchLookupEdit。
大家也可以直接用Dev的SearchLookupEdit控制元件,效果還不錯,當然為了方便起見,減少自己的操作量,也可以模仿《玩轉控制元件:封裝Dev的LabelControl和TextEdit》一樣,自己根據實際情況做個封裝,來吧!作者陪大家一起重溫下封裝的樂趣。
Show me the Code
和往常一樣,新建一個類用來封裝和擴充套件自己實際要用到的屬性和事件:
public partial class KzxSearchComboboxEdit : KzxBaseControl
初始化的時候,就可以封裝好自己要用到的事件:
public KzxSearchComboboxEdit() { InitializeComponent(); this.ValueControl.QueryPopUp += new CancelEventHandler(lookUpEdit_QueryPopUp); this.ValueControl.Closed += new ClosedEventHandler(lookUpEdit_Closed); this.CaptionControl.AutoSizeMode = LabelAutoSizeMode.Vertical; this.CaptionControl.SizeChanged += new EventHandler(SetSize); this.ValueControl.Enter -= new EventHandler(ValueControl_Enter); this.ValueControl.Enter += new EventHandler(ValueControl_Enter); this._SearchLookUpEditView.FocusRectStyle = DevExpress.XtraGrid.Views.Grid.DrawFocusRectStyle.RowFocus; this._SearchLookUpEditView.Name = "gridLookUpEdit1View"; this._SearchLookUpEditView.OptionsSelection.EnableAppearanceFocusedCell = false; this._SearchLookUpEditView.OptionsView.ShowGroupPanel = false; this.ValueControl.Properties.PopupFormSize = new System.Drawing.Size((int)(this.ValueControl.Width * 2), (int)(this.ValueControl.Width * 1.5)); if (this.DesignMode == true) { this.Size = new Size(284, 21); } }
把自己實際需要用到的屬性做好封裝,舉個栗子:
private int _ItemIndex = -1; /// <summary> /// 選中項的下標 /// </summary> [Category("自定義"), Description("ItemIndex,選中項的下標"), Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [McDisplayName("ItemIndex")] public int ItemIndex { get { return this._ItemIndex; } protected set { this._ItemIndex = value; } } private DataRow _CurrentItem = null; /// <summary> /// 選中項的DataRow物件 /// </summary> [Category("自定義"), Description("CurrentItem,選中項的DataRow物件"), Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [McDisplayName("CurrentItem")] public DataRow CurrentItem { get { return this._CurrentItem; } protected set { this._CurrentItem = value; } } private DataSet _BillDataSet = new DataSet(); /// <summary> /// 單據的資料來源 /// </summary> [Category("自定義"), Description("BillDataSet,單據的資料來源"), Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [McDisplayName("BillDataSet")] public DataSet BillDataSet { get { return this._BillDataSet; } set { this._BillDataSet = value; } } /// <summary> /// 沒有多語言的情況下的預設顯示標題 /// </summary> [Category("多語言"), Description("DesigeCaption,沒有多語言的情況下的預設顯示標題"), Browsable(true)] [McDisplayName("DesigeCaption")] public override string DesigeCaption { get { return this.CaptionControl.Text.Trim(); } set { this.CaptionControl.Text = value; } }
也可以根據自己喜好(當然是符合客戶習慣的),畫蛇添足:
private bool _IsNull = true; /// <summary> /// 可空性 /// </summary> [Category("驗證"), Description("IsNull,可空性"), Browsable(true)] [McDisplayName("IsNull")] public override bool IsNull { get { SetBackColor(); return this._IsNull; } set { this._IsNull = value; SetBackColor(); } } ... /// <summary> /// 設定背景色 /// </summary> private void SetBackColor() { if (this.ValueControl.Properties.ReadOnly == true) { this.ValueControl.BackColor = Color.FromArgb(242, 242, 243); } else { if (this._IsNull.Equals(true) == false) { this.ValueControl.BackColor = Color.Yellow; } else { this.ValueControl.BackColor = this._TextBackColor; } } }
當設定控制元件必填的時候,設定控制元件的背景色用於區分,具體效果如圖:
封裝好控制元件取值,填充值的方法,以及控制元件資料來源繫結的方法(具體根據自己實際專案應用為準,此處只是舉個栗子)
/// <summary> /// 取控制元件的值 /// </summary> /// <return>Object</return> public override object GetValue() { DataRowView rowview = null; BindingSource bs = null; object v = null; v = this.ValueControl.EditValue == null || this.ValueControl.EditValue == DBNull.Value ? string.Empty : this.ValueControl.EditValue.ToString(); return v; } /// <summary> /// 設定控制元件的值 /// </summary> /// <param name="value">控制元件的值</param> /// <return>int</return> public override int SetValue(object value) { this.ValueControl.EditValue = value == null || value == DBNull.Value ? string.Empty : value; return 1; } /// <summary> /// 設定資料繫結 /// </summary> /// <param name="binding">資料繫結物件</param> /// <return>int</return> public override int SetDataBinding(object binding) { this.BindingObject = this.ValueControl.DataBindings.Add("EditValue", binding, this.Field, true, DataSourceUpdateMode.OnValidation, string.Empty, this.FormatString); SetColumnDisplayFormat(); if (binding is BindingSource) { int maxlength = 0; if (((BindingSource)binding).DataSource is DataView) { if (((DataView)(((BindingSource)binding).DataSource)).Table.Columns[this.Field].DataType == typeof(string)) { maxlength = ((DataView)(((BindingSource)binding).DataSource)).Table.Columns[this.Field].MaxLength; if (maxlength >= 0) { this.MaxLength = maxlength; } } } else if (((BindingSource)binding).DataSource is DataTable) { if (((DataTable)(((BindingSource)binding).DataSource)).Columns[this.Field].DataType == typeof(string)) { maxlength = ((DataTable)(((BindingSource)binding).DataSource)).Columns[this.Field].MaxLength; if (maxlength >= 0) { this.MaxLength = maxlength; } } } } return 1; } /// <summary> /// 設定下拉框的資料來源 /// </summary> /// <param name="binding">下拉框的資料來源</param> /// <param name="displayMember">顯示值欄位名</param> /// <param name="valueMember">實際值欄位名</param> /// <returns>int</returns> public override int SetSourceTableBinding(object binding, string displayMember, string valueMember) { this.DisplayMemberPath = displayMember; this.SelectedValuePath = valueMember; this.ValueControl.Properties.DataSource = binding; this._ResourceDataSource = binding; return 1; }
完成!為測試效果,在窗體Load事件中造個測試資料,看看效果:
DataTable dataTable = new DataTable("Student"); dataTable.Columns.Add("編號", typeof(String)); dataTable.Columns.Add("暱稱", typeof(String)); dataTable.Columns.Add("名稱", typeof(String)); dataTable.Rows.Add(new String[] { "1", "James", "張三" }); dataTable.Rows.Add(new String[] { "2", "Mary", "李四" }); dataTable.Rows.Add(new String[] { "3", "Jack", "王五" }); dataTable.Rows.Add(new String[] { "4", "joy", "趙六" }); dataTable.Rows.Add(new String[] { "5", "jay", "錢七"}); dataTable.Rows.Add(new String[] { "6", "stephen", "康忠鑫"}); kzxSearchCbbeSupperStar.SetSourceTableBinding(dataTable, "名稱", "暱稱");
和原始Dev控制元件一樣,支援篩選功能,媽媽再也不用擔心客戶反饋因資料量大的問題查詢不便了!
結束語
由於後續所有重寫/重繪控制元件都在同一個專案使用,而且Dev系統引用檔案較多,壓縮後原始碼檔案仍然很大,如果有需要原始碼的朋友,可以微信公眾號聯絡博主,原始碼可以免費贈予~!有疑問的也可以CALL我一起探討。
最後,感謝您的耐心陪伴!如果覺得本篇博文對您或者身邊朋友有幫助的,麻煩點個關注!贈人玫瑰,手留餘香,您的支援就是我寫作最大的動力,感謝您的關注,期待和您一起探討!再