應用程序界面開發 - 自定義用戶控件&佈局控件的使用

在很多時候,我們做一些非常規化的界面的時候,往往需要創建一些用戶控件,在其中繪製好一些基礎的界面塊,作爲後續重複使用的一個單元,用戶控件同時也可以封裝處理一些簡單的邏輯。在開發Winform各種類型項目,我都時不時需要定製一些特殊的用戶控件,以方便在界面模塊中反覆使用。我們一般是在自定義的用戶控件裏面,添加各種各樣的界面控件元素,或者封裝一些特殊的函數處理共外部調用等。本篇隨筆主要介紹基於DevExpressWinform開發經驗,介紹一個類似看板信息的用戶控件,並在TabelLayout和StackLayout佈局控件中進行展示。

一、用戶控件界面的處理

在偶爾的一個場合下,看到一個牙醫管家的軟件界面做的非常不錯,其中有一個預約列表的界面感覺非常好,如下界面所示。

Winform界面開發教程 - 自定義用戶控件&佈局控件的使用圖集1

其中它的每個用戶信息列表裏面,都是一個綜合信息的展示,非常直觀,估計應該是用戶自定義控件做的。

在其中裏面,有不同的字體,各式圖標,以及內容的信息展示, 這個我在DevExpress的列表控件裏面,沒有看到可以如此定義列表內容的,在DevExpress的GridView裏面有一個看板模板的定義有點接近,但是試了一下,可調性不好,於是放棄尋求其他接近方案,玩遍DevExpress的控件後,發現最好的方式應該是自定義用戶控件的方式來解決這個界面問題。

花了一點時間,製作了一個用戶控件,在其中添加一個LayoutControl方便控制佈局,添加一些標籤以及設置了一些圖標,得到下圖所示。

Winform界面開發教程 - 自定義用戶控件&佈局控件的使用圖集2

左側的顏色條由於使用Group控件,因此寬度暫時無法調整,如果介意大小,我們可以在其中在創建一個LayoutControl,然後在其中方式內容即可。

我們改變佈局,然後添加一個顏色塊,得到類似界面如下所示。

Winform界面開發教程 - 自定義用戶控件&佈局控件的使用圖集3

我們來定義一下用戶控件的源碼部分,修改其中源碼,增加對應的屬性,方便動態設置用戶控件的相關屬性,如顏色塊,項目背景色,以及綁定的對象信息等內容。

Winform界面開發教程 - 自定義用戶控件&佈局控件的使用圖集4

然後在界面加載完畢後,設置對應的信息和顏色信息,如下代碼所示。

 

/// <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;
}
}

 

但我們鼠標浮動在項目上或者離開的時候,或者單擊某項的時候,我們變換下顏色,方便區分顯示。

 

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);
}

 

完成這些後,我們需要在窗體上對內容進行初始化。

最後我們看看界面的效果如下所示:

Winform界面開發教程 - 自定義用戶控件&佈局控件的使用圖集5

或者下面這樣的界面佈局。

Winform界面開發教程 - 自定義用戶控件&佈局控件的使用圖集6

如果嫌棄邊框紅色不好看,我們 可以修改邊框爲灰色調一點的,這樣總體看起來效果如下所示。

Winform界面開發教程 - 自定義用戶控件&佈局控件的使用圖集7

得到和我們最終需要的界面很接近了。

一般除了懸浮鼠標顏色變化外,控件單擊後,我們會設置不同的背景色,以示區分。

 

/// <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界面開發教程 - 自定義用戶控件&佈局控件的使用圖集8

二、TabelLayout和StackLayout佈局控件的介紹和使用

我們在做Winform開發的時候,一般知道,微軟傳統Winform的佈局提供兩個控件,FlowLayoutPanel和TableLayoutPanel,一個是流式佈局,一個是表格佈局,各有各的用處。流式佈局主要就是按照順序挨個放置控件,表格佈局主要按照表格的定義的行列單元格,嚴格放置控件,表格單元格控制強度更大,而且控件具有拉伸效果。

對於DevExpress,我們一般還是傾向於採用它提供給的控件來做界面,可以很好融合它的皮膚效果,相對於Winform傳統兩個佈局控件,DevExpress提供了兩個封裝效果相當的控件佈局StackPanel和 TablePanel,他們的效果實現大同效果,不過調用的接口不同。

Winform界面開發教程 - 自定義用戶控件&佈局控件的使用圖集9

對於兩個控件,我們希望裏面的內容自動出現滾動條,那麼設置屬性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展現出來的效果。

Winform界面開發教程 - 自定義用戶控件&佈局控件的使用圖集10

以上就是界面如何在DevExpress開發中使用各種用戶控件進行用戶控件的創建、以及實現鼠標進入、移出、單擊的不同效果,以及實現鍵盤上下箭頭按鍵的事件選中效果,並介紹DevExpress中兩個佈局控件TabelPanel和StackPanel的正常使用,達到展示控件信息的作用。

DevExpress WinForm界面控件| 下載試用

DevExpress WinForm擁有180+組件和UI庫,能爲Windows Forms平臺創建具有影響力的業務解決方案。DevExpress WinForms能完美構建流暢、美觀且易於使用的應用程序,無論是Office風格的界面,還是分析處理大批量的業務數據,它都能輕鬆勝任!

本文轉載自:博客園 - 伍華聰


DevExpress技術交流羣4:715863792      歡迎一起進羣討論

更多DevExpress線上公開課、中文教程資訊請上中文網獲取

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章