欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

WPF自定义控件创建

程序员文章站 2022-12-16 14:36:59
WPF自定义控件创建 本文简单的介绍一下WPF自定义控件的开发。 首先,我们打开VisualStudio创建一个WPF自定义控件库,如下图: 然后,我们可以看到创建的解决方案如下: 在解决方案中,我们看到了一个Themes文件夹和一个CS文件。 其中CS文件,就是我们需要编写的自定义控件,里面的类继 ......

wpf自定义控件创建

本文简单的介绍一下wpf自定义控件的开发。

首先,我们打开visualstudio创建一个wpf自定义控件库,如下图:

WPF自定义控件创建

然后,我们可以看到创建的解决方案如下:

WPF自定义控件创建

在解决方案中,我们看到了一个themes文件夹和一个cs文件。

其中cs文件,就是我们需要编写的自定义控件,里面的类继承了control类;而themes则存放该控件的样式。即,wpf自定义控件,是通过样式给我们的编辑的控件类披上外衣而形成的。

下面,我们来编写一个简单的时间控件。

我们先将customcontrol1文件改名为kibadatetime,然后打开kibadatetime.cs文件,看到了一些控件应用提示,这些提示写的是自定义控件的应用方式,我们先不看这些提示,因为他写的不是很好理解。

接下来我们开始编写时间控件,修改kibadatetime类如下:

public class kibadatetime : textbox
    {
        private static regex regex = new regex("[0-9]+");
        #region 小时
        public static readonly dependencyproperty hourproperty = dependencyproperty.register(
             "hour", typeof(int), typeof(kibadatetime), new frameworkpropertymetadata(00));
       
        public int hour
        {
            get
            {
                return (int)getvalue(hourproperty);
            }
            set
            {
                setvalue(hourproperty, value);
            }
        } 
        #endregion
        #region 分钟
        public static readonly dependencyproperty minuteproperty = dependencyproperty.register(
             "minute", typeof(int), typeof(kibadatetime), new frameworkpropertymetadata(00));
        
        public int minute
        {
            get
            {
                return (int)getvalue(minuteproperty);
            }
            set
            {
                setvalue(minuteproperty, value);
            }
        }
        #endregion
        #region 秒
        public static readonly dependencyproperty secondproperty = dependencyproperty.register(
             "second", typeof(int), typeof(kibadatetime), new frameworkpropertymetadata(00)); 
        public int second
        {
            get
            {
                return (int)getvalue(secondproperty);
            }
            set
            {
                setvalue(secondproperty, value);
            }
        }
        #endregion
        static kibadatetime()
        {
            //当此依赖项属性位于指定类型的实例上时为其指定替换元数据,以在该依赖项属性继承自基类型时重写该属性已存在的元数据。
            defaultstylekeyproperty.overridemetadata(typeof(kibadatetime), new frameworkpropertymetadata(typeof(kibadatetime))); 
        }
    }

如上述代码所示,我们修改了kibadatetime继承的类;将control改为了textbox。

这样,我们就可以在kibadatetime控件的样式中,用使用textbox的属性,进行绑定了。

然后,我们在控件类里定义三个依赖属性,小时、分钟、秒;之后,我们会把这个三个属性,绑定到样式中。

现在我们打开theme文件下的generic.xaml文件,看到样式代码如下:

<resourcedictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:kibacustomcontrol">
    <style targettype="{x:type local:kibadatetime}">
        <setter property="template">
            <setter.value>
                <controltemplate targettype="{x:type local:kibadatetime}">
                    <border background="{templatebinding background}"
                            borderbrush="{templatebinding borderbrush}"
                            borderthickness="{templatebinding borderthickness}">
                        
                    </border>
                </controltemplate>
            </setter.value>
        </setter>
    </style> 
</resourcedictionary>

从代码中可以看到,系统已经为我们定义好了kibadatetime控件的外壳样式。

我们需要做的就是将样式内容添加进去。

我们在border中,添加textbox,然后进行小时、分钟、秒的绑定,这里要用binding来绑定。

添加的textbox代码如下,我们进行了一些简单宽高和间距设置。

<textbox text="{binding hour,mode=twoway,relativesource={relativesource templatedparent},updatesourcetrigger=propertychanged}" width="24" height="24" padding="2,3,0,0" fontsize="12" ></textbox>
<textbox text="{binding minute,mode=twoway,relativesource={relativesource templatedparent},updatesourcetrigger=propertychanged}" width="24" height="24" padding="2,3,0,0" fontsize="12" ></textbox>
<textbox text="{binding second,mode=twoway,relativesource={relativesource templatedparent},updatesourcetrigger=propertychanged}" width="24" height="24" padding="2,3,0,0" fontsize="12" ></textbox>

上述代码使用了【relativesource={relativesource templatedparent}】来寻找绑定源,注意,这里一定要用templatedparent,不然无法绑定到我们控件类。

自定义控件到此为止,就已经定义好了。然后我们使用下刚刚定义好的控件。

wpf自定义控件应用

首先创建一个wpf项目,然后引用kibacustomcontrol这个程序集。如下图:

WPF自定义控件创建

然后,在mainwindow.xaml页面中,使用该控件。

修改mainwindow.xaml页面代码如下:

<window x:class="kibatestcontrol.mainwindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:c="clr-namespace:kibacustomcontrol;assembly=kibacustomcontrol"
        xmlns:local="clr-namespace:kibatestcontrol"
        mc:ignorable="d"
        title="mainwindow" height="450" width="800">
    <dockpanel>
        <stackpanel verticalalignment="top" margin="10" orientation="horizontal">
            <c:kibadatetime name="dthour"></c:kibadatetime> 
            <button content="查看时间" click="button_click" width="75"/>
        </stackpanel>
    </dockpanel>
</window>

其中【xmlns:c="clr-namespace:kibacustomcontrol;assembly=kibacustomcontrol"】这句话是将我们自定义的程序集内的控件,引入到当前页。

【<c:kibadatetime text="00" ></c:kibadatetime>】这句话就是我们自定义控件的应用了。

应用界面如下图所示:

WPF自定义控件创建

其中查看时间的事件代码如下:

private void button_click(object sender, routedeventargs e)
{
    messagebox.show("小时:"+dthour.hour+":"+dthour.minute + ":" + dthour.second);
}

修改时间,点击查看时间,得到结果如下:

WPF自定义控件创建

到此,这个简单的wpf控件,就开发完了。

----------------------------------------------------------------------------------------------------

代码已经传到github上了,欢迎大家下载。

github地址:https://github.com/kiba518/kibawpfcustomcontrol

----------------------------------------------------------------------------------------------------

注:此文章为原创,欢迎转载,请在文章页面明显位置给出此文链接!
若您觉得这篇文章还不错,请点击下右下角的推荐】,非常感谢!