• WPF自定义控件创建


    WPF自定义控件创建

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

    首先,我们打开VisualStudio创建一个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这个程序集。如下图:

    然后,在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>】这句话就是我们自定义控件的应用了。

    应用界面如下图所示:

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

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("小时:"+dtHour.Hour+":"+dtHour.Minute + ":" + dtHour.Second);
    }

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

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

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

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

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

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

    注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!
    若您觉得这篇文章还不错,请点击下方的推荐】,非常感谢!

     

  • 相关阅读:
    正则表达式匹配中国区的电话号码
    落户
    存储过程与函数的区别转载
    asp.net页面从初始化到卸载事件顺序转
    .net连接Oracle数据库 常见问题
    sql触发器的类型
    (转) C++中extern “C”含义深层探索
    vmware 收缩越来越大的磁盘文件
    (转)一些常用的网站
    工具:P/Invoke Interop Assistant
  • 原文地址:https://www.cnblogs.com/kiba/p/10307486.html
Copyright © 2020-2023  润新知