如何封装属于自己的WPF控件库

在网上找了一下,发现这方面的资料并不多。做传统桌面的本来就不多了吧,更别说WPF了。我可能也要另寻出路了,不过我还是觉得做桌面挺有意思的。

言归正传

首先,新建一个WPF自定义控件库项目

这里我们封装一个支持自己绘制形状的图片按钮,且支持图片和文字。

运行效果如下:(形状是我随便绘的)

将默认的CustomControl1.cs改成ImageButton.cs

这个图片按钮的实现主要是用WPF的依赖属性来实现,有疑问的,可以先了解下依赖属性

https://docs.microsoft.com/zh-cn/dotnet/framework/wpf/advanced/dependency-properties-overview

ImageButton.cs代码如下:

1 public class ImageButton : System.Windows.Controls.Button

2 {

3 static ImageButton()

4 {

5 DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));

6 }

7

8 public static readonly DependencyProperty TextProperty = DependencyProperty.Register("ButtonImage", typeof(string), typeof(FrameworkElement));

9

10 public string Text

11 {

12 set

13 {

14 SetValue(TextProperty, value);

15 }

16 get

17 {

18 return (string)GetValue(TextProperty);

19 }

20 }

21 }

这里我们只加了一个文字属性,图像的显示我们借助于Button控件本身结构来实现

Button控件的默认控件模版如下

https://docs.microsoft.com/en-us/previous-versions/windows/silverlight/dotnet-windows-silverlight/ms609804%28v%3dvs.95%29(ContentPresenter)

如果要实现图片+文字,自己加一个Image控件就行了

1

2

3

然后我们在Themes/Generic.xaml中定义ImageButton的样式

样式如下:

1

编译生成dll

接下来就可以使用了

新建一个WPF工程,先引用 刚才生成的dll,再引入xaml前缀,就可以使用了

xmlns:controls="clr-namespace:ImageButton;assembly=ImageButton"

1

2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

6 xmlns:local="clr-namespace:ImageButtonDemo"

7 mc:Ignorable="d"

8 xmlns:controls="clr-namespace:ImageButton;assembly=ImageButton"

9 Title="MainWindow" Height="350" Width="525">

10

11

12

13

14

15

16

17

18

19

20

21

22

23

示例代码

https://files.cnblogs.com/files/zhaotianff/ImageButtonDemo.zip

2020.07.06新增:

可以通过重写OnApplyTemplate方法,以便在完整生成模板并将其附加到逻辑树后执行指定的操作。

如:为控件中的按钮添加单击事件。

1 public override void OnApplyTemplate()

2 {

3 base.OnApplyTemplate();

4

5 close = Template.FindName("PART_Close", this) as System.Windows.Controls.Button;

6 if (close != null)

7 {

8 close.Click += CloseClick;

9 }

10 }

Template(System.Windows.Controls.ControlTemplate)属性代表当前自定义控件的模板