首页 > 其他分享 >WPF自定义控件与样式-自定义按钮(Button)

WPF自定义控件与样式-自定义按钮(Button)

时间:2024-07-05 14:55:51浏览次数:26  
标签:控件 DependencyProperty 自定义 Button typeof 按钮 public Brush

一、前言

程序界面上的按钮多种多样,常用的就这几种:普通按钮、图标按钮、文字按钮、图片文字混合按钮。本文章记录了不同样式类型的按钮实现方法。

二、固定样式的按钮

固定样式的按钮一般在临时使用时或程序的样式比较固定时才会使用,按钮整体样式不需要做大的改动。

2.1 普通按钮-扁平化风格

先看效果:

定义Button的样式,详见代码:

复制代码
<Style x:Key="BtnInfoStyle" TargetType="Button">
            <Setter Property="Width" Value="70"/>
            <Setter Property="Height" Value="25"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="Background" Value="#43a9c7"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True">
                            <TextBlock Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter TargetName="border" Property="Background" Value="#2f96b4"/>
                            </Trigger>
                            <Trigger Property="IsPressed" Value="True">
                                <Setter TargetName="border" Property="Background" Value="#2a89a4"/>
                            </Trigger>
                       </ControlTemplate.Triggers>
                 </ControlTemplate>
            </Setter.Value>
     </Setter>
</Style>
复制代码

引用方法:

<Grid Background="White">
        <StackPanel Orientation="Horizontal" Margin="10" VerticalAlignment="Top">
            <Button Style="{StaticResource BtnInfoStyle}" Content="信息" Margin="5 0"/>
</Grid>

上述代码实现了Button按钮的扁平化样式,如果你想调整颜色风格,通过修改Background的值可实现默认颜色,鼠标经过颜色以及鼠标按下颜色。

 2.2 图标按钮

先看效果:

Button样式的代码和扁平化Button差不多,只是把TextBlock控件替换成了Image控件,另外需要设置Button默认的背景色为透明。废话不多说看代码:

复制代码
  <Style x:Key="BtnImageStyle1" TargetType="Button">
         <Setter Property="Cursor" Value="Hand"/>
         <Setter Property="Template">
             <Setter.Value>
                 <ControlTemplate TargetType="Button">
                      <Border Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
                            <Image x:Name="Img" VerticalAlignment="Center" HorizontalAlignment="Center" Source="/Images/button1.png" Stretch="None"/>
                      </Border>
                      <ControlTemplate.Triggers>
                         <Trigger Property="IsMouseOver" Value="True">
                             <Setter TargetName="Img" Property="Source" Value="/Images/button1.png"/>
                         </Trigger>
                         <Trigger Property="IsPressed" Value="True">
                             <Setter TargetName="Img" Property="Source" Value="/Images/button1.png"/>
                         </Trigger>
                      </ControlTemplate.Triggers>
                 </ControlTemplate>
            </Setter.Value>
       </Setter>
 </Style>
复制代码

这里的button1.png需要自己准备图片资源,IsMouseOver和IsPressed的图片资源可自己替换,替换之后能有更丰富的效果呈现。

2.3 图标文字混合按钮

效果:

 

实现代码:

复制代码
 <Style x:Key="BtnImgTxtStyle1" TargetType="Button">
       <Setter Property="Foreground" Value="#555"/>
       <Setter Property="Template">
             <Setter.Value>
                  <ControlTemplate TargetType="Button">
                       <Border>
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                                <Image Source="Images/adshut.png" Stretch="None"/>
                                <TextBlock x:Name="Txt" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                            </StackPanel>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Foreground" Value="#333333" TargetName="Txt"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                 </ControlTemplate>
            </Setter.Value>
       </Setter>
 </Style>
复制代码

2.4 文字按钮和2.3中的图标文字按钮样式差不多,只需要把Image控件去掉就行。

三、复用性高的按钮

  • 要想实现复用性高的按钮,就必须新建自定义控件。下面这个实例通过自定义控件实现上述所有效果,并且可以随意更改风格。
  • 首先在项目中右键-添加-新建项-自定义控件。

新建自定义控件之后,添加依赖属性。代码如下:

复制代码
 public class ButtonEx : Button
    {
        static ButtonEx()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonEx), new FrameworkPropertyMetadata(typeof(ButtonEx)));
        }


        public ButtonType ButtonType
        {
            get { return (ButtonType)GetValue(ButtonTypeProperty); }
            set { SetValue(ButtonTypeProperty, value); }
        }

        public static readonly DependencyProperty ButtonTypeProperty =
            DependencyProperty.Register("ButtonType", typeof(ButtonType), typeof(ButtonEx), new PropertyMetadata(ButtonType.Normal));


        public ImageSource Icon
        {
            get { return (ImageSource)GetValue(IconProperty); }
            set { SetValue(IconProperty, value); }
        }

        public static readonly DependencyProperty IconProperty =
            DependencyProperty.Register("Icon", typeof(ImageSource), typeof(ButtonEx), new PropertyMetadata(null));


        public CornerRadius CornerRadius
        {
            get { return (CornerRadius)GetValue(CornerRadiusProperty); }
            set { SetValue(CornerRadiusProperty, value); }
        }

        public static readonly DependencyProperty CornerRadiusProperty =
            DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(ButtonEx), new PropertyMetadata(new CornerRadius(0)));


        public Brush MouseOverForeground
        {
            get { return (Brush)GetValue(MouseOverForegroundProperty); }
            set { SetValue(MouseOverForegroundProperty, value); }
        }

        public static readonly DependencyProperty MouseOverForegroundProperty =
            DependencyProperty.Register("MouseOverForeground", typeof(Brush), typeof(ButtonEx), new PropertyMetadata());


        public Brush MousePressedForeground
        {
            get { return (Brush)GetValue(MousePressedForegroundProperty); }
            set { SetValue(MousePressedForegroundProperty, value); }
        }

        public static readonly DependencyProperty MousePressedForegroundProperty =
            DependencyProperty.Register("MousePressedForeground", typeof(Brush), typeof(ButtonEx), new PropertyMetadata());


        public Brush MouseOverBorderbrush
        {
            get { return (Brush)GetValue(MouseOverBorderbrushProperty); }
            set { SetValue(MouseOverBorderbrushProperty, value); }
        }

        public static readonly DependencyProperty MouseOverBorderbrushProperty =
            DependencyProperty.Register("MouseOverBorderbrush", typeof(Brush), typeof(ButtonEx), new PropertyMetadata());


        public Brush MouseOverBackground
        {
            get { return (Brush)GetValue(MouseOverBackgroundProperty); }
            set { SetValue(MouseOverBackgroundProperty, value); }
        }

        public static readonly DependencyProperty MouseOverBackgroundProperty =
            DependencyProperty.Register("MouseOverBackground", typeof(Brush), typeof(ButtonEx), new PropertyMetadata());


        public Brush MousePressedBackground
        {
            get { return (Brush)GetValue(MousePressedBackgroundProperty); }
            set { SetValue(MousePressedBackgroundProperty, value); }
        }

        public static readonly DependencyProperty MousePressedBackgroundProperty =
            DependencyProperty.Register("MousePressedBackground", typeof(Brush), typeof(ButtonEx), new PropertyMetadata());
    }

    public enum ButtonType
    {
        Normal,
        Icon,
        Text,
        IconText
    }
复制代码

为不同类型按钮设置样式,代码如下:

复制代码
<Style TargetType="{x:Type local:ButtonEx}">
        <Style.Triggers>
            <Trigger Property="ButtonType" Value="Normal">
                <Setter Property="Background" Value="#43a9c7"/>
                <Setter Property="MouseOverBackground" Value="#2f96b4"/>
                <Setter Property="MousePressedBackground" Value="#2a89a4"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="MouseOverForeground" Value="White"/>
                <Setter Property="MousePressedForeground" Value="White"/>
                <Setter Property="BorderBrush" Value="Transparent"/>
                <Setter Property="BorderThickness" Value="0"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type local:ButtonEx}">
                            <Border x:Name="border" Background="{TemplateBinding Background}" CornerRadius="{TemplateBinding CornerRadius}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" SnapsToDevicePixels="True">
                                <TextBlock x:Name="txt" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter TargetName="border" Property="Background" Value="{Binding MouseOverBackground,RelativeSource={RelativeSource TemplatedParent}}"/>
                                    <Setter TargetName="txt" Property="Foreground" Value="{Binding MouseOverForeground,RelativeSource={RelativeSource TemplatedParent}}"/>
                                    <Setter TargetName="border" Property="BorderBrush" Value="{Binding MouseOverBorderbrush,RelativeSource={RelativeSource TemplatedParent}}"/>
                                </Trigger>
                                <Trigger Property="IsPressed" Value="True">
                                    <Setter TargetName="border" Property="Background" Value="{Binding MousePressedBackground,RelativeSource={RelativeSource TemplatedParent}}"/>
                                    <Setter TargetName="txt" Property="Foreground" Value="{Binding MousePressedForeground,RelativeSource={RelativeSource TemplatedParent}}"/>
                                   
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
            <Trigger Property="ButtonType" Value="Icon">
                <Setter Property="Cursor" Value="Hand"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type local:ButtonEx}">
                            <Border Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
                                <Image x:Name="Img" VerticalAlignment="Center" HorizontalAlignment="Center" Source="{TemplateBinding Icon}" Stretch="None"/>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter Property="Opacity" Value="0.8"/>
                                </Trigger>
                                <Trigger Property="IsPressed" Value="True">
                                    <Setter Property="Opacity" Value="0.9"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
            <Trigger Property="ButtonType" Value="Text">
                <Setter Property="Cursor" Value="Hand"/>
                <Setter Property="Foreground" Value="#002c99"/>
                <Setter Property="MouseOverForeground" Value="#FF2c99"/>
                <Setter Property="MousePressedForeground" Value="#002c99"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type local:ButtonEx}">
                            <TextBlock x:Name="txt" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter Property="Foreground" Value="{Binding MouseOverForeground,RelativeSource={RelativeSource TemplatedParent}}" TargetName="txt"/>
                                </Trigger>
                                <Trigger Property="IsPressed" Value="True">
                                    <Setter Property="Foreground" Value="{Binding MousePressedForeground,RelativeSource={RelativeSource TemplatedParent}}" TargetName="txt"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
            <Trigger Property="ButtonType" Value="IconText">
                <Setter Property="Cursor" Value="Hand"/>
                <Setter Property="Foreground" Value="#555"/>
                <Setter Property="MouseOverForeground" Value="#555"/>
                <Setter Property="MousePressedForeground" Value="#555"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type local:ButtonEx}">
                            <Border>
                                <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                                    <Image Source="{TemplateBinding Icon}" Stretch="None"/>
                                    <TextBlock x:Name="Txt" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                                </StackPanel>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter Property="Foreground" Value="{Binding MouseOverForeground,RelativeSource={RelativeSource TemplatedParent}}" TargetName="Txt"/>
                                </Trigger>
                                <Trigger Property="IsPressed" Value="True">
                                    <Setter Property="Foreground" Value="{Binding MousePressedForeground,RelativeSource={RelativeSource TemplatedParent}}" TargetName="Txt"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
       
    </Style>
复制代码

然后就可以引用该控件了:

复制代码
 <Grid>
        <WrapPanel>
            <local:ButtonEx Content="信息" Width="75" Height="25" Margin="10" ButtonType="Normal"/>
            <local:ButtonEx Icon="/Images/button1.png"  Margin="10" ButtonType="Icon"/>
            <local:ButtonEx Content="文字按钮" Margin="10" ButtonType="Text"/>
            <local:ButtonEx Content="图文按钮" Icon="/Images/adshut.png" Margin="10" ButtonType="IconText"/>
        </WrapPanel>
    </Grid>
复制代码

效果如下:

 

至此已经完成Button控件的扩展功能,如果想要添加动画或者设置图标的位置和边距等,可以自己另外添加依赖属性来扩展。

来源:https://www.cnblogs.com/xiaomingg/p/8699125.html

 

标签:控件,DependencyProperty,自定义,Button,typeof,按钮,public,Brush
From: https://www.cnblogs.com/ywtssydm/p/18285800

相关文章

  • Laravel 宏指令(Macro)动态添加自定义方法到Laravel的核心组件中
    Laravel宏指令(Macro)在Laravel中,宏指令(Macro)是一种灵活的方式,允许您动态添加自定义方法到Laravel的核心组件中,如模型、查询构建器、集合等,以便在不改变核心代码的情况下扩展框架的功能。通过宏指令,您可以向Laravel内置的类添加自定义方法,实现更高级的功能和逻辑。福利彩......
  • iOS开发-UIButton
    UIButton用于创建可交互的按钮。按钮可以响应用户的触摸事件,执行特定的动作或逻辑。创建和配置UIButton创建UIButton的基本步骤://创建UIButton实例,指定按钮类型为系统类型UIButton*button=[UIButtonbuttonWithType:UIButtonTypeSystem];//设置按钮的frame,确定其在父视......
  • ubuntu 自定义开机画面
    1. 修改UEFI固件图片2. 修改GRUB背景图片3. 修改Plymouth启动画面 1. 固件和启动过程UEFI固件加载图片:在系统启动时,UEFI固件首先加载,并显示制造商的Logo(如“LEGION”),这在启动过程中称为“splashscreen”。这张图片是嵌入在UEFI固件中的,用户通常无法直接修改或访问......
  • 学懂C#编程:WPF应用开发系列——WPF之ComboBox控件的详细用法
    WPF(WindowsPresentationFoundation)中的ComboBox控件是一个下拉列表控件,允许用户从一组预定义的选项中选择一个选项。以下是ComboBox控件的详细用法,并附带示例说明。ComboBox的基本用法1.XAML定义:在XAML中定义一个ComboBox控件,并添加一些选项。<Windowx:Class="ComboBox......
  • vue2和vue3自定义指令实现只读模式,禁止用户编辑
    解决代码表单组件大量disable的麻烦,实现只读。只需要在需要的地方加上v-read-only即可达到只读效果,快捷方便。实现思路父元素下添加一个遮罩层元素遮罩层元素的显示隐藏由参数决定要想简单快捷的实现,最好用的就是写一个遮罩层,通过遮罩来隔绝用户的操作。原始代码如下:<temp......
  • 微信小程序-自定义组件数据监听器observers
    一.监测自定义组件data值定义data值,在.js文件里面定义data值data:{num:10,count:100,obj:{name:'tom',age:10},arr:[1,2,3]}只有在data值进行改变后才会触发到数据监听的回调函数,如果数据没有改变回调函数不会被触发ob......
  • python logging 自定义备份的日志文件命名
    importtimeimportloggingfromlogging.handlersimportTimedRotatingFileHandlerdeflog_file_namer(log_file_name):log_file_name_split=log_file_name.split('.')log_suffix=log_file_name_split.pop(1)log_file_name_split.append(l......
  • Delphi 常用控件之TlistView总结
    TlistView组件功能:(1)TListView控件可以用来显示各项带图标的列表,包括大图标和小图标的;也可以用来显示带有子项的列表,Windows操作系统的资源管理器中文件夹窗口就是最好的应用例子,就是我们打开"我的电脑"后能够看到各个盘符的界面(2)TListView控件基本能实现和DBGrid控件一......
  • python教程:自定义函数
    1.多态我们可以看到,Python不用考虑输入的数据类型,而是将其交给具体的代码去判断执行,同样的一个函数(比如这边的相加函数my_sum()),可以同时应用在整型、列表、字符串等等的操作中。在编程语言中,我们把这种行为称为多态。这也是Python和其他语言,比如Java、C等很大的一个不同点......
  • uniapp 开发微信小程序自定义与胶囊平行的导航栏
    1、page.json中使用custom自定义导航栏{ "path":"pages/partners/index", "style":{ "navigationBarTitleText":"", "navigationStyle":"custom"//自定义导航栏样式 } },2、vue文件:<template> ......