前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >WPF自定义控件创建

WPF自定义控件创建

作者头像
Kiba518
发布于 2019-01-28 08:35:25
发布于 2019-01-28 08:35:25
2.1K00
代码可运行
举报
文章被收录于专栏:Kiba518Kiba518
运行总次数:0
代码可运行

WPF自定义控件创建

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

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

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

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

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

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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文件,看到样式代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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代码如下,我们进行了一些简单宽高和间距设置。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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这个程序集。如下图:

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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>】这句话就是我们自定义控件的应用了。

应用界面如下图所示:

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private void Button_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show("小时:"+dtHour.Hour+":"+dtHour.Minute + ":" + dtHour.Second);
}

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

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

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

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

Github地址:https://github.com/kiba518/KibaWpfCustomControl

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-01-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
[WPF自定义控件]从ContentControl开始入门自定义控件
我去年写过一个在UWP自定义控件的系列博客,大部分的经验都可以用在WPF中(只有一点小区别)。这篇文章的目的是快速入门自定义控件的开发,所以尽量精简了篇幅,更深入的概念在以后介绍各控件的文章中实际运用到才介绍。
dino.c
2019/05/17
4.1K0
WPF实现列表分页控件的示例代码分享
[TemplatePart(Name = CountPerPageTextBoxTemplateName, Type = typeof(TextBox))]
用户7718188
2022/11/06
1.4K0
WPF --- 非Button自定义控件实现点击功能
今天在做一个设置文件夹路径的功能,就是一个文本框,加个按钮,点击按钮,弹出 FolderBrowserDialog 再选择文件夹路径,简单做法,可以直接 StackPanel 横向放置一个 TextBox 和一个 Image Button,然后点击按钮在 后台代码中给 ViewModel 的 FilePath赋值。但是这样属实不够优雅,UI 不够优雅,代码实现也可谓是强耦合,那接下来我分享一下我的实现方案。
Niuery Diary
2023/10/22
4010
WPF --- 非Button自定义控件实现点击功能
WPF 日期选择器和时间选择器
格式有要求,必须是yyyy-MM-dd hh:mm:ss或者yyyy/MM/dd hh:mm:ss
码客说
2023/02/10
6.2K0
WPF下可编辑Header的Tab控件实现
介绍 有这样一个需求,当用户双击Tab控件Header区域时, 希望可以直接编辑。对于WPF控件,提供一个ControlTemplate在加上一些Trigger就可以实现。效果如下: 代码 首先,我们需要给Tab Header设计一个ControlTemplate。类似一个TextBlock,双击进入编辑状态。 所以Xaml如下: <Setter Property="Template"> <Setter.Value> <ControlT
葡萄城控件
2018/01/10
1.1K0
WPF桌面端开发-数据绑定(Binding)
此模式允许将给定的 ControlTemplate 属性绑定到应用 ControlTemplate 的控件的属性。为了更好地理解这里的问题,下面是一个示例
码客说
2023/07/11
3340
WPF中Button空白区域无法点击的解决方法
就是在Button内部渲染区域的外层添加了一个Grid,并且设置背景色为Transparent。
码客说
2023/04/12
1.6K0
如何优雅的为文本框添加清除按钮
答:一般情况都会选择自定义控件,这样的话不清真,所以我们通过附加属性,可以让你的文本框变得更简洁。
独立观察员
2024/11/23
2290
如何优雅的为文本框添加清除按钮
WPF:无法对元素“XXX”设置 Name 特性值“YYY”。“XXX”在元素“ZZZ”的范围内,在另一范围内定义它时,已注册了名称。
2020-04-03 06:44
walterlv
2020/04/08
3.3K0
WPF依赖属性(wpf 依赖属性)
依赖属性就是一种自己可以没有值,并且可以通过绑定从其他数据源获取值。依赖属性可支持WPF中的样式设置、数据绑定、继承、动画及默认值。
全栈程序员站长
2022/07/28
2.2K0
WPF依赖属性(wpf 依赖属性)
C#-ListBox多选绑定
ListBox有一个依赖属性SelectedItems,但是这个属性是只读的,所以无法适用绑定,来自动获取多选项,如何通过绑定获取多选项,我们可以使用附加属性来实现。
kdyonly
2024/12/19
1370
[WPF自定义控件库] 自定义控件的代码如何与ControlTemplate交互
WPF有一个灵活的UI框架,用户可以轻松地使用代码控制控件的外观。例设我需要一个控件在鼠标进入的时候背景变成蓝色,我可以用下面这段代码实现:
dino.c
2019/05/23
2K0
[WPF自定义控件库] 自定义控件的代码如何与ControlTemplate交互
[WPF 自定义控件]创建包含CheckBox的ListBoxItem
不过它用起来不怎么样,与其这样还不如参考UWP的ListView实现,而且动画效果也很好看:
dino.c
2020/02/21
3K0
[WPF 自定义控件]创建包含CheckBox的ListBoxItem
WPF --- TextBox的输入校验
之前在做一些参数配置功能时,最是头疼各种参数校验,查阅一些资料后,我总结了数据校验方式有两种:
Niuery Diary
2023/11/17
7770
WPF --- TextBox的输入校验
Silverlight项目中"自定义控件开发/Style"学习笔记
本文不涉及高深的设计模式(比如mvc,mvvm之类),也没有太多的编程技巧,只是记录自己做为asp.net开发者学习silverlight中自定义控件开发的一些过程,高手请绕过。  先推荐一篇不错的文章http://www.cnblogs.com/carysun/articles/1259025.html 写得很全面,只不过图片讲解不够丰富,初学者可能有些感到跳跃性大了一些。  正文开始:  做过asp.net网站开发的都知道用户控件是一个很方便的功能,通常我们会把一些模块化的功能封装成用户控件,用的时候直
菩提树下的杨过
2018/01/23
1K0
Silverlight项目中"自定义控件开发/Style"学习笔记
WPF --- TextBox的输入校验
之前在做一些参数配置功能时,最是头疼各种参数校验,查阅一些资料后,我总结了数据校验方式有两种:
Niuery Diary
2023/11/20
5490
WPF --- TextBox的输入校验
WPF 应用完全模拟 UWP 的标题栏按钮
发布于 2018-08-04 09:35 更新于 2018-08-05 02:21
walterlv
2018/09/18
2.3K0
WPF 应用完全模拟 UWP 的标题栏按钮
Silverlight button 图片切换样式
之前一直做WPF现在开始接触Slilverlight感触很多。 今天做一个Button要求 有两个图片,button默认有一个图片,鼠标over时用另一个图片, 用wpf做的时候写一个template很简单,但silverlight和wpf写起来不一样 记录一下。大概思路是两个image鼠标MouseOver的时候一个Visible一个Collapsed 写的是一个自定义控件,代码和皮肤分离,很简单的一个demo 代码下载:ImageButtonTest.rar 先写一个继承自button的imagebut
lpxxn
2018/01/31
2.2K0
WPF 制作 Windows 屏保
[1]GitHub: https://github.com/yanjinhuagood/ScreenSaver
独立观察员
2022/12/06
9680
WPF 制作 Windows 屏保
Drawer 抽屉控件的实现
定义了一个名为 Drawer 的自定义控件,继承自 HeaderedContentControl,允许用户在应用程序中创建可展开和收起的抽屉。抽屉的显示和隐藏动画通过 Storyboard 实现,支持从不同方向(左、上、右、下)展开和收起。
郑子铭
2024/12/09
1110
Drawer 抽屉控件的实现
相关推荐
[WPF自定义控件]从ContentControl开始入门自定义控件
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档