「博客搬家」 原地址: CSDN 原發表時間: 2016-10-12html
本文主要總結使用 C# 及 .NET 在 WPF 框架下,自定義控件的繪製以及窗體中控件的自適應。c#
WPF 下,爲快速地爲應用定製一個零部件,須要的是 UserControl , 爲了讓你打造的控件更標準化,更靈活以及更具備廣泛意義,須要用到的 CustomControl 。要在 WPF 中自定義一個控件,使用 UserControl 與 CustomControl 都是不錯的選擇,他們的區別在於:框架
UserControl , 其更像 WinForm 中自定義控件的開發風格,在開發上更簡單快速,幾乎能夠簡單地理解爲:利用設計器來將多個已有控件做爲子元素來拼湊成一個 UserControl 並修改其外觀,而後後臺邏輯代碼直接訪問這些子元素。其最大的弊端在於: 其對模板樣式等支持度很差,其重複使用的範圍有限。ui
CustomControl , 其開發出來的控件才真正具備 WPF 風格,其對模板樣式有着很好的支持,這是由於打造 CustomControl 時作到了邏輯代碼與外觀相分離,即便換上一套徹底不一樣的視覺樹其一樣能很好的工做,就像 WPF 內置的控件同樣。spa
在使用 Visual Studio 打造控件時 , UserControl 與 CustomControl 的差異就更加明顯,在項目中添加一個 UserControl 時,咱們會發現設計器爲咱們添加了一個 XAML 文件以及一個對應的 .CS 文件「或 .VB 等」,而後你就能夠像設計普通窗體同樣設計該 UserControl ; 若是咱們是在項目中添加一個 CustomControl , 狀況卻不是這樣,設計器會爲咱們生成一個 .CS 文件「或 .VB 等」,該文件用於編寫控件的後臺邏輯,而控件的外觀卻定義在了軟件的應用主題「Theme」中了「若是你沒有爲軟件定義通用主題,其會自動生成一個通用主題 themes\generic.xaml
, 而後主題中會自動爲你的控件生成一個 Style 」,並將通用主題與該控件關聯了起來。這也就是 CustomControl 對樣式的支持度比 UserControl 好的緣由。.net
這裏爲了簡便起見,使用 UserControl 建立自定義控件。設計
對項目點擊右鍵,選擇「添加」->「新建項」,選擇 「用戶控件『WPF』」", 便可成功添加自定義控件。3d
對該控件進行設計,拖入幾個系統控件,並修改其參數便可。下圖展現的是我使用 Microsoft Blend 設計對控件進行設計:code
控件設計完畢後,右鍵單擊控件編輯窗口,選擇「查看代碼」,或直接按「F7」鍵,便可編輯該控件類的源代碼。我主要添加了該控件的初始化,改變控件的背景顏色,以及動態設定控件顯示的值等代碼功能,具體以下:orm
/// <summary>
/// _bitkyPoleControl.xaml 的交互邏輯
/// </summary>
public partial class BitkyPoleControl : UserControl
{
private readonly Color _colorBlue = Color.FromRgb(0, 255, 200);
//改變顏色
private readonly Color _colorRed = Color.FromRgb(255, 0, 0);
public BitkyPoleControl()
{
InitializeComponent();
}
public int _id { get; private set; } = -1;
/// <summary>
/// 根據參數初始化該控件
/// </summary>
/// <param name="id">輸入的參數</param>
public void setContent(int id)
{
Name = "bitkyPoleControl" + id;
labelPoleId.Content = id;
_id = id;
}
public void SetValue(int num)
{
labelNum.Content = num;
}
/// <summary>
/// 設置背景顏色,0:綠 1:紅
/// </summary>
/// <param name="i"></param>
public void setColor(int i)
{
if (i == 0)
Background = new SolidColorBrush(_colorBlue);
if (i == 1)
Background = new SolidColorBrush(_colorRed);
}
}
複製代碼
我在主窗體中添加了一個 Grid , 並將該 Grid 平均分紅了八行八列,以下圖所示:
設置方法以下:以下圖所示,經過對 Grid 的屬性進行以下設置:
在「1」處,可添加 ColumnDefinitions 和 RowDefinitions 。
在「2」處,可設置 Grid 中單元格的最小尺寸,在 width 處,有三個選項:「Auto」,「Pixel」,「Star」。
在此,爲了平均分配 Grid 的空間,且可根據窗口大小自適應,故將全部行和列的該項設定爲「Star」,值設爲「1」,便可出現上圖的效果。
在主窗體類中使用以下代碼便可在 Grid 中動態添加控件 :
/// <summary>
/// 初始化信息顯示標籤界面
/// </summary>
private void InitBitkyPoleShow()
{
var controls = new List<BitkyPoleControl>();
var id = 0;
for (var i = 0; i < 8; i++)
{
for (var j = 0; j < 8; j++)
{
var bitkyPoleControl = new BitkyPoleControl();
//在 Grid 中動態添加控件
GridPoleStatusShow.Children.Add(bitkyPoleControl);
//設定控件在 Grid 中的位置
Grid.SetRow(bitkyPoleControl, i);
Grid.SetColumn(bitkyPoleControl, j);
//將控件添加到集合中,方便下一步的使用
controls.Add(bitkyPoleControl);
//對控件使用自定義方法進行初始化
bitkyPoleControl.setContent(id);
id++;
}
}
}
複製代碼
運行程序,效果以下圖所示:
觀察圖片可知,空間排布較爲美觀,如若想要子控件徹底填充 Grid 中的單元格,需對子控件的屬性進行配置。
如圖所示,將控件的寬度和高度設爲「Auto」,將 HorizontalAlignment 和 VerticalAlignment 設爲「Stretch」 , Margin 設爲合適的值 , 則此時, Grid 中的子控件的便可動態自適應父控件。