在不少時候,咱們作一些很是規化的界面的時候,每每須要建立一些用戶控件,在其中繪製好一些基礎的界面塊,做爲後續重複使用的一個單元,用戶控件同時也能夠封裝處理一些簡單的邏輯。在開發Winform各類類型項目,我都時不時須要定製一些特殊的用戶控件,以方便在界面模塊中反覆使用。咱們通常是在自定義的用戶控件裏面,添加各類各樣的界面控件元素,或者封裝一些特殊的函數處理共外部調用等。本篇隨筆主要介紹基於DevExpress的Winform開發經驗,介紹一個相似看板信息的用戶控件,並在TabelLayout和StackLayout佈局控件中進行展現。函數
在偶爾的一個場合下,看到一個牙醫管家的軟件界面作的很是不錯,其中有一個預定列表的界面感受很是好,以下界面所示。佈局
其中它的每一個用戶信息列表裏面,都是一個綜合信息的展現,很是直觀,估計應該是用戶自定義控件作的。測試
在其中裏面,有不一樣的字體,各式圖標,以及內容的信息展現, 這個我在DevExpress的列表控件裏面,沒有看到能夠如此定義列表內容的,在DevExpress的GridView裏面有一個看板模板的定義有點接近,可是試了一下,可調性很差,因而放棄尋求其餘接近方案,玩遍DevExpress的控件後,發現最好的方式應該是自定義用戶控件的方式來解決這個界面問題。字體
花了一點時間,製做了一個用戶控件,在其中添加一個LayoutControl方便控制佈局,添加一些標籤以及設置了一些圖標,獲得下圖所示。this
左側的顏色條因爲使用Group控件,所以寬度暫時沒法調整,若是介意大小,咱們能夠在其中在建立一個LayoutControl,而後在其中方式內容便可。spa
咱們改變佈局,而後添加一個顏色塊,獲得相似界面以下所示。code
咱們來定義一下用戶控件的源碼部分,修改其中源碼,增長對應的屬性,方便動態設置用戶控件的相關屬性,如顏色塊,項目背景色,以及綁定的對象信息等內容。orm
而後在界面加載完畢後,設置對應的信息和顏色信息,以下代碼所示。對象
/// <summary> /// 窗口加載事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void UserItemControl_Load(object sender, EventArgs e) { BindData(); RefreshColor(); } /// <summary> /// 根據用戶定義信息,顯示不一樣的內容 /// </summary> private void BindData() { if(this.UserItemInfo != null) { var info = this.UserItemInfo; this.lblCustomerName.Text = info.CustomerName; this.lblMobile.Text = info.Mobile; this.lblReceiver.Text = info.Receiver; this.lblRecordDate.Text = info.RecordDate; this.lblRecordNo.Text = info.RecordNo; this.lblDealType.Text = ""; this.lblStar.ImageOptions.ImageIndex = GetStarImageIndex(info.Stars); if (!info.IsVip) { this.lblVip.Visibility = LayoutVisibility.Never; } } } /// <summary> /// 刷新背景色 /// </summary> private void RefreshColor() { if (ItemBlockColor != Color.Empty) { this.itemColor.AppearanceItemCaption.BackColor = ItemBlockColor; } if (ItemBackColor != Color.Empty) { layoutControl1.BackColor = ItemBackColor; } }
但咱們鼠標浮動在項目上或者離開的時候,或者單擊某項的時候,咱們變換下顏色,方便區分顯示。blog
private void layoutControl1_MouseLeave(object sender, EventArgs e) { if (!this.IsSelected) { this.layoutControl1.ResetBackColor(); } } private void layoutControl1_MouseEnter(object sender, EventArgs e) { if (!this.IsSelected) this.layoutControl1.BackColor = Color.FromArgb(192, 255, 192); } private void layoutControl1_Click(object sender, EventArgs e) { this.IsSelected = true; OnItemClick?.Invoke(this, e); }
完成這些後,咱們須要在窗體上對內容進行初始化。
最後咱們看看界面的效果以下所示
或者下面這樣的界面佈局。
若是嫌棄邊框紅色很差看,咱們 能夠修改邊框爲灰色調一點的,這樣整體看起來效果以下所示。
獲得和咱們最終須要的界面很接近了。
通常除了懸浮鼠標顏色變化外,控件單擊後,咱們會設置不一樣的背景色,以示區分。
/// <summary> /// 是否選中節點 /// </summary> public bool IsSelected { get { return m_IsSelected; } set { m_IsSelected = value; this.ItemBackColor = value ? Color.FromArgb(255, 255, 192) : Color.Transparent; this.RefreshColor(); } }
通常列表界面中,咱們除了支持鼠標移動、單擊變色的效果外,咱們還但願支持經過鍵盤箭頭上下鍵進行上下瀏覽項目。咱們若是須要使用鍵盤的按鍵,須要設置窗體的KeyPreview屬性爲True,
而後跟蹤按鍵的事件便可,以下所示。
this.KeyPreview = true; this.KeyUp += FrmKanBan_KeyUp;
按鍵事件捕捉處理以下所示,主要就是判斷選中的用戶控件,並對面板的子控件的選中效果進行處理。
private void FrmKanBan_KeyUp(object sender, KeyEventArgs e) { //單擊鼠標或者切換按鍵,會觸發用戶控件得到selectItem對象,能夠進行箭頭上下移動 if (selectItem != null) { var panel = selectItem.Parent; if (panel != null) { //獲取操做項的索引值 int oldIndex = panel.Controls.IndexOf(selectItem); if (e.KeyCode == Keys.Up) { if (oldIndex > 0) { //經過序號得到新的控件,並單擊它觸發選擇事件 var newCtrl = panel.Controls[oldIndex - 1]; Item_OnItemClick(newCtrl, new EventArgs()); } } else if (e.KeyCode == Keys.Down) { if (oldIndex < (panel.Controls.Count - 1)) { //經過序號得到新的控件,並單擊它觸發選擇事件 var newCtrl = panel.Controls[oldIndex + 1]; Item_OnItemClick(newCtrl, new EventArgs()); } } } } }
界面中用戶控件的切換選中效果,須要先清空以前全部的選擇,而後在設置新的選中控件,因此還須要對控件觸發單擊事件進行處理,以下所示。
/// <summary> /// 選中的用戶控件對象實例 /// </summary> UserItemControl selectItem = null; /// <summary> /// 單擊用戶控件,觸發清除全部標記後,再次設置選中的項目標記 /// </summary> private void Item_OnItemClick(object sender, EventArgs e) { //清空全部控件的選中標記 var panel = (PanelControl)((Control)sender).Parent; foreach (Control ctrl in panel.Controls) { var item = ctrl as UserItemControl; if(item != null) { item.IsSelected = false; } } //設置選中控件 selectItem = ((UserItemControl)sender); selectItem.IsSelected = true; this.Text = selectItem.UserItemInfo.CustomerName + "-選中"; //若是在面板中遮擋,移動滾動條,能夠查看到完整用戶控件界面 panel.ScrollControlIntoView(selectItem); }
以下效果所示。
咱們在作Winform開發的時候,通常知道,微軟傳統Winform的佈局提供兩個控件,FlowLayoutPanel和TableLayoutPanel,一個是流式佈局,一個是表格佈局,各有各的用處。流式佈局主要就是按照順序挨個放置控件,表格佈局主要按照表格的定義的行列單元格,嚴格放置控件,表格單元格控制強度更大,並且控件具備拉伸效果。
對於DevExpress,咱們通常仍是傾向於採用它提供給的控件來作界面,能夠很好融合它的皮膚效果,相對於Winform傳統兩個佈局控件,DevExpress提供了兩個封裝效果至關的控件佈局StackPanel和 TablePanel,他們的效果實現大同效果,不過調用的接口不一樣。
對於兩個控件,咱們但願裏面的內容自動出現滾動條,那麼設置屬性AutoScroll 爲True便可,以下代碼所示。
panel.AutoScroll = true;
而StackPanel另外須要LayoutDirection,也就是控件順序展示的方式,以下代碼所示。
panel.LayoutDirection = StackPanelLayoutDirection.TopDown;
使用StackPanel面板來測試展現用戶控件列表的界面代碼以下所示。
/// <summary> /// 使用StackPanel對用戶控件佈局進行處理 /// </summary> private void InitPanel(StackPanel panel) { panel.AutoScroll = true;//面板自動出現滾動條 panel.LayoutDirection = StackPanelLayoutDirection.TopDown;//從上往下展現 panel.Controls.Clear();//清空界面 var list = GetInfoList(); //獲取用戶控件綁定的對象信息列表 for (int i = 0; i < list.Count; i++) { //定義用戶控件實例 var item = new UserItemControl(); item.UserItemInfo = list[i];//綁定對象信息 item.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; item.ItemBlockColor = colors[i %10]; //變化顏色 item.OnItemClick += Item_OnItemClick;//觸發選中事件 panel.Controls.Add(item); } }
對於表格佈局TablePanel控件來講,使用初始化控件的方式也差很少,不過有個別地方注意便可。
/// <summary> /// 使用TablePanel對用戶控件佈局進行處理 /// </summary> private void InitPanel(TablePanel panel) { panel.AutoScroll = true;//面板自動出現滾動條 panel.Controls.Clear();//清空界面 panel.Rows.Clear();//清空行 panel.Columns.Clear();//清空列 //添加列定義(增長一個列便可) panel.Columns.Add(new TablePanelColumn(TablePanelEntityStyle.Relative, 55F)); var list = GetInfoList(); //獲取用戶控件綁定的對象信息列表 for (int i = 0; i < list.Count; i++) { //定義行信息 panel.Rows.Add(new TablePanelRow(TablePanelEntityStyle.AutoSize, 100F)); //定義用戶控件實例 var item = new UserItemControl(); item.UserItemInfo = list[i]; //定義拉伸效果 item.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; item.ItemBlockColor = colors[i % 10]; //變化顏色 item.OnItemClick += Item_OnItemClick;//觸發選中事件 //先添加控件到面板集合中 panel.Controls.Add(item); //設置控件的單元格位置 panel.SetCell(item, i, 0); } //添加多一行,確保佈局 panel.Rows.Add(new TablePanelRow(TablePanelEntityStyle.AutoSize, 100F)); }
添加控件的時候,須要注意下面的代碼,才能正常展現控件信息,不然沒法看到用戶控件。
//先添加控件到面板集合中 panel.Controls.Add(item); //設置控件的單元格位置 panel.SetCell(item, i, 0);
最後對比下效果,左邊是TablePanel,右邊是StackPanel展示出來的效果。
以上就是界面如何在DevExpress開發中使用各類用戶控件進行用戶控件的建立、以及實現鼠標進入、移出、單擊的不一樣效果,以及實現鍵盤上下箭頭按鍵的事件選中效果,並介紹DevExpress中兩個佈局控件TabelPanel和StackPanel的正常使用,達到展現控件信息的做用。