WPF自定义按钮控件

2 篇文章 0 订阅

WPF自定义按钮控件

在平时的WPF应用中,系统提供的按钮控件确实可以实现正常的逻辑,但是从视觉方面看的话,确实不够美观,而且每个项目的UI设计不尽相同。那么自定义按钮控件就是必须的了,网上查找了很多自定义按钮控件的办法,但每次都是写到一半就报错。在参考了多个技术贴之后,自己写出了第一个自定义的按钮控件,欢迎参考,如有错误,敬请指正。

参考文档

http://t.zoukankan.com/DoNetCoder-p-3732310.html
https://blog.51cto.com/u_15076204/4542004
https://www.cnblogs.com/donetcoder/p/3732310.html?utm_source=tuicool&utm_medium=referral

1.创建自定义控件库

名称自己定,平台根据实际情况选择,这里使用的是.Net Core6.0平台
在这里插入图片描述

2.改名

自定义控件库创建完成后,可以根据实际情况自己修改“CustomControl1.cs”的名称。此处我的命名是“ImageButton.cs”
在这里插入图片描述
打开ImageButton.cs,内容如下(里面只有一个很长的使用说明和构造方法):

namespace CustomControls
{
    /// <summary>
    /// 按照步骤 1a 或 1b 操作,然后执行步骤 2 以在 XAML 文件中使用此自定义控件。
    ///
    /// 步骤 1a) 在当前项目中存在的 XAML 文件中使用该自定义控件。
    /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根 
    /// 元素中: 
    ///
    ///     xmlns:MyNamespace="clr-namespace:ImageButton"
    ///
    ///
    /// 步骤 1b) 在其他项目中存在的 XAML 文件中使用该自定义控件。
    /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根 
    /// 元素中: 
    ///
    ///     xmlns:MyNamespace="clr-namespace:ImageButton;assembly=ImageButton"
    ///
    /// 您还需要添加一个从 XAML 文件所在的项目到此项目的项目引用,
    /// 并重新生成以避免编译错误: 
    ///
    ///     在解决方案资源管理器中右击目标项目,然后依次单击
    ///     “添加引用”->“项目”->[选择此项目]
    ///
    ///
    /// 步骤 2)
    /// 继续操作并在 XAML 文件中使用控件。
    ///
    ///     <MyNamespace:CustomControl1/>
    ///
    /// </summary>

    public class ImageButton : System.Windows.Controls.Button
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        static ImageButton()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
        }

    }
}

3.添加要用的资源

创建资源文件夹并向内拷贝用到的资源文件:有的说需要把拷贝进去的资源属性中的“生成操作”手动改为“资源”或“Resource”,我本人在拷贝后并没有发现需要设置,可能不同的环境,每个人的情况不尽相同,此处需要灵活处理。
在这里插入图片描述

4.编写Themes下Generic.xaml样式文件

其中包含样式设置,及对应的触发器设置,由于想要最大限度的做到通用,所以很多属性都由绑定的形式交给属性绑定类(ImageButton.cs)处理。

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:CustomControls">
    <Style TargetType="{x:Type local:ImageButton}" BasedOn="{StaticResource {x:Type Button}}">
        <Setter Property="Foreground" Value="#F5F7FF"/>
        <!--<Setter Property="Background" Value="#536DE0"/>-->
        <Setter Property="FontSize" Value="13"/>
        <Setter Property="FontWeight" Value="Medium"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ImageButton}">
                    <Border x:Name="Normal" CornerRadius="{Binding CornerRadius,RelativeSource={RelativeSource TemplatedParent}}" MinHeight="{TemplateBinding MinHeight}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                        <Grid >
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="{Binding IconColumnWidth,RelativeSource={RelativeSource TemplatedParent}}"/>
                                <ColumnDefinition Width="{Binding TextColumnWidth,RelativeSource={RelativeSource TemplatedParent}}"/>
                            </Grid.ColumnDefinitions>

                            
                            <Image x:Name="back" Grid.ColumnSpan="2" Margin="{Binding ButtonBackgroundMargin,RelativeSource={RelativeSource TemplatedParent}}"
                                   Source="{Binding NormalButtonBackground,RelativeSource={RelativeSource TemplatedParent}}"
                                   VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Stretch="Fill" />
                            <Image x:Name="IconImg" Grid.Column="0"  Width="14" Height="14"
                                   Source="{Binding NormalIcon,RelativeSource={RelativeSource TemplatedParent}}"
                                   IsEnabled="{TemplateBinding IsEnabled}"
                                   Effect="{x:Null}"
                                   VerticalAlignment="Stretch" HorizontalAlignment="Stretch" 
                                   Stretch="UniformToFill " StretchDirection="Both" Margin="15,2,0,2"/>
                            <TextBlock x:Name="TextBlockInternal" Grid.Column="1" 
                                       Text="{Binding Text,RelativeSource={RelativeSource TemplatedParent}}"
                                       Effect="{TemplateBinding Effect}"
                                       HorizontalAlignment="Stretch" VerticalAlignment="Center" 
                                       TextAlignment="{Binding ButtonTextAlignment,RelativeSource={RelativeSource TemplatedParent}}" Margin="2,0"/>
                        </Grid>
                    </Border>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Foreground" Value="#4D528A"/>
                            <!--<Setter Property="Background" Value="#D0D4EA"/>-->
                            <Setter TargetName="back" 
                                    Property="Source" Value="{Binding HoverButtonBackground,RelativeSource={RelativeSource TemplatedParent}}"/>
                            <Setter TargetName="IconImg" 
                                    Property="Source" Value="{Binding HoverIcon,RelativeSource={RelativeSource TemplatedParent}}"/>
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter Property="Foreground" Value="#CAD3F9"/>
                            <!--<Setter Property="Background" Value="#152B7E" />-->
                            <Setter TargetName="back" 
                                    Property="Source" Value="{Binding PressedButtonBackground,RelativeSource={RelativeSource TemplatedParent}}"/>
                            <Setter TargetName="IconImg" 
                                    Property="Source" Value="{Binding PressedIcon,RelativeSource={RelativeSource TemplatedParent}}"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter Property="Opacity" Value=".6"/>
                            <Setter Property="Effect" Value="{x:Null}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

5.绑定属性类编写

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace CustomControls
{
    /// <summary>
    /// 按照步骤 1a 或 1b 操作,然后执行步骤 2 以在 XAML 文件中使用此自定义控件。
    ///
    /// 步骤 1a) 在当前项目中存在的 XAML 文件中使用该自定义控件。
    /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根 
    /// 元素中: 
    ///
    ///     xmlns:MyNamespace="clr-namespace:ImageButton"
    ///
    ///
    /// 步骤 1b) 在其他项目中存在的 XAML 文件中使用该自定义控件。
    /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根 
    /// 元素中: 
    ///
    ///     xmlns:MyNamespace="clr-namespace:ImageButton;assembly=ImageButton"
    ///
    /// 您还需要添加一个从 XAML 文件所在的项目到此项目的项目引用,
    /// 并重新生成以避免编译错误: 
    ///
    ///     在解决方案资源管理器中右击目标项目,然后依次单击
    ///     “添加引用”->“项目”->[选择此项目]
    ///
    ///
    /// 步骤 2)
    /// 继续操作并在 XAML 文件中使用控件。
    ///
    ///     <MyNamespace:CustomControl1/>
    ///
    /// </summary>

    public class ImageButton : System.Windows.Controls.Button
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        static ImageButton()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
        }

        /// <summary>
        /// 按钮文本属性
        /// </summary>
        public static readonly DependencyProperty TextProperty = DependencyProperty.Register("ButtonText", typeof(string), typeof(FrameworkElement));
        public string Text
        {
            set
            {
                SetValue(TextProperty, value);
            }
            get
            {
                return (string)GetValue(TextProperty);
            }
        }

        /// <summary>
        /// 按钮圆角属性
        /// </summary>
        public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(int), typeof(FrameworkElement));
        public int CornerRadius
        {
            set
            {
                SetValue(CornerRadiusProperty, value);
            }
            get
            {
                return (int)GetValue(CornerRadiusProperty);
            }
        }

        /// <summary>
        /// 按钮图标属性(常规)
        /// </summary>
        public static readonly DependencyProperty NormalIconProperty = DependencyProperty.Register("NormalIcon", typeof(string), typeof(FrameworkElement));
        public string NormalIcon
        {
            set
            {
                SetValue(NormalIconProperty, value);
            }
            get
            {
                return (string)GetValue(NormalIconProperty);
            }
        }

        /// <summary>
        /// 按钮图标属性(鼠标悬停)
        /// </summary>
        public static readonly DependencyProperty HoverIconProperty = DependencyProperty.Register("HoverIcon", typeof(string), typeof(FrameworkElement));
        public string HoverIcon
        {
            set
            {
                SetValue(HoverIconProperty, value);
            }
            get
            {
                return (string)GetValue(HoverIconProperty);
            }
        }

        /// <summary>
        /// 按钮图标属性(点击)
        /// </summary>
        public static readonly DependencyProperty PressedIconProperty = DependencyProperty.Register("PressedIcon", typeof(string), typeof(FrameworkElement));
        public string PressedIcon
        {
            set
            {
                SetValue(PressedIconProperty, value);
            }
            get
            {
                return (string)GetValue(PressedIconProperty);
            }
        }

        /// <summary>
        /// 按钮图标列宽度属性
        /// </summary>
        public static readonly DependencyProperty IconColumnWidthProperty = DependencyProperty.Register("IconColumnWidth", typeof(string), typeof(FrameworkElement));
        public string IconColumnWidth
        {
            set
            {
                SetValue(IconColumnWidthProperty, value);
            }
            get
            {
                return (string)GetValue(IconColumnWidthProperty);
            }
        }

        /// <summary>
        /// 按钮文字列高度属性
        /// </summary>
        public static readonly DependencyProperty TextColumnWidthProperty = DependencyProperty.Register("TextColumnWidth", typeof(string), typeof(FrameworkElement));
        public string TextColumnWidth
        {
            set
            {
                SetValue(TextColumnWidthProperty, value);
            }
            get
            {
                return (string)GetValue(TextColumnWidthProperty);
            }
        }

        /// <summary>
        /// 按钮背景图片属性(常规)
        /// </summary>
        public static readonly DependencyProperty NormalButtonBackgroundProperty = DependencyProperty.Register("NormalButtonBackground", typeof(string), typeof(FrameworkElement));
        public string NormalButtonBackground
        {
            set
            {
                SetValue(NormalButtonBackgroundProperty, value);
            }
            get
            {
                return (string)GetValue(NormalButtonBackgroundProperty);
            }
        }

        /// <summary>
        /// 按钮背景图片属性(鼠标悬停)
        /// </summary>
        public static readonly DependencyProperty HoverButtonBackgroundProperty = DependencyProperty.Register("HoverButtonBackground", typeof(string), typeof(FrameworkElement));
        public string HoverButtonBackground
        {
            set
            {
                SetValue(HoverButtonBackgroundProperty, value);
            }
            get
            {
                return (string)GetValue(HoverButtonBackgroundProperty);
            }
        }

        /// <summary>
        /// 按钮背景图片属性(点击)
        /// </summary>
        public static readonly DependencyProperty PressedButtonBackgroundProperty = DependencyProperty.Register("PressedButtonBackground", typeof(string), typeof(FrameworkElement));
        public string PressedButtonBackground
        {
            set
            {
                SetValue(PressedButtonBackgroundProperty, value);
            }
            get
            {
                return (string)GetValue(PressedButtonBackgroundProperty);
            }
        }

        /// <summary>
        /// 按钮背景图片的Margin属性
        /// </summary>
        public static readonly DependencyProperty ButtonBackgroundMarginProperty = DependencyProperty.Register("ButtonBackgroundMargin", typeof(string), typeof(FrameworkElement));
        public string ButtonBackgroundMargin
        {
            set
            {
                SetValue(ButtonBackgroundMarginProperty, value);
            }
            get
            {
                return (string)GetValue(ButtonBackgroundMarginProperty);
            }
        }

        /// <summary>
        /// 按钮文本TextAlignment属性
        /// </summary>
        public static readonly DependencyProperty ButtonTextAlignmentMarginProperty = DependencyProperty.Register("ButtonTextAlignment", typeof(string), typeof(FrameworkElement));
        public string ButtonTextAlignment
        {
            set
            {
                SetValue(ButtonTextAlignmentMarginProperty, value);
            }
            get
            {
                return (string)GetValue(ButtonTextAlignmentMarginProperty);
            }
        }
    }

}

6.使用

使用时创建WPF应用程序(平台一定要对应,否则工具箱里面不会生成可供拖拽的快捷工具)
在这里插入图片描述
引入命名空间

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

调用

<controls:ImageButton Grid.Row="0" Width="104" Height="32" Margin="20"
                                  IconColumnWidth="0.5*" TextColumnWidth="*" ButtonBackgroundMargin="-10" 
                                  ButtonTextAlignment="Left"
                                  NormalIcon="pack://application:,,,/CustomControls;component/Resourse/Images/3.0-相机@2x.png"
                                  HoverIcon="pack://application:,,,/CustomControls;component/Resourse/Images/3.0-相机@2x(1).png"
                                  PressedIcon="pack://application:,,,/CustomControls;component/Resourse/Images/3.0-相机@2x.png" 
                                  NormalButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/矩形@2x.png"
                                  HoverButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/矩形@2x(1).png"
                                  PressedButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/矩形@2x(2).png"
                                  Text="新增相机" CornerRadius="4"/>

xaml文件整体内容

<Window x:Class="CustomControlDemo.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:local="clr-namespace:CustomControlDemo"
        xmlns:controls="clr-namespace:CustomControls;assembly=CustomControls"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel Orientation="Vertical" Height="800">
            <controls:ImageButton Grid.Row="0" Width="104" Height="32" Margin="20"
                                  IconColumnWidth="0.5*" TextColumnWidth="*" ButtonBackgroundMargin="-10" 
                                  ButtonTextAlignment="Left"
                                  NormalIcon="pack://application:,,,/CustomControls;component/Resourse/Images/3.0-相机@2x.png"
                                  HoverIcon="pack://application:,,,/CustomControls;component/Resourse/Images/3.0-相机@2x(1).png"
                                  PressedIcon="pack://application:,,,/CustomControls;component/Resourse/Images/3.0-相机@2x.png" 
                                  NormalButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/矩形@2x.png"
                                  HoverButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/矩形@2x(1).png"
                                  PressedButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/矩形@2x(2).png"
                                  Text="新增相机" CornerRadius="4"/>
            <controls:ImageButton Grid.Row="1" Width="104" Height="32" Margin="20"
                                  IconColumnWidth="0.5*" TextColumnWidth="*" ButtonBackgroundMargin="-10" 
                                  ButtonTextAlignment="Left"
                                  NormalIcon="pack://application:,,,/CustomControls;component/Resourse/Images/3.0-相机@2x.png"
                                  HoverIcon="pack://application:,,,/CustomControls;component/Resourse/Images/3.0-相机@2x(1).png"
                                  PressedIcon="pack://application:,,,/CustomControls;component/Resourse/Images/3.0-相机@2x.png" 
                                  NormalButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/矩形@2x.png"
                                  HoverButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/矩形@2x(1).png"
                                  PressedButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/矩形@2x(2).png"
                                  Text="新增视频" CornerRadius="4"/>
            <controls:ImageButton Grid.Row="2" Width="50" Height="50" Margin="20" 
                                  IconColumnWidth="10*" TextColumnWidth="0*" ButtonBackgroundMargin="-20"
                                  ButtonTextAlignment="Center"
                                  NormalButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/笔@2x.png"
                                  HoverButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/笔@2x(1).png"
                                  PressedButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/笔@2x(2).png"
                                  Text="编辑" CornerRadius="4"/>
            <controls:ImageButton Grid.Row="2" Width="50" Height="50" Margin="20"
                                  IconColumnWidth="10*" TextColumnWidth="0*" ButtonBackgroundMargin="-20" 
                                  
                                  NormalButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/编组 34@2x.png"
                                  HoverButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/编组 34@2x(1).png"
                                  PressedButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/编组 34@2x(2).png"
                                  Text="删除" CornerRadius="4"/>
            <controls:ImageButton Grid.Row="3" Width="107" Height="50" Margin="20"
                                  IconColumnWidth="0*" TextColumnWidth="*" ButtonBackgroundMargin="-11,-18" 
                                  ButtonTextAlignment="Center"
                                  NormalButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/矩形@2x.png"
                                  HoverButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/矩形@2x(1).png"
                                  PressedButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/矩形@2x(2).png"
                                  Text="申请" CornerRadius="4"/>
            <controls:ImageButton Grid.Row="4" Width="216" Height="84" Margin="20"
                                  IconColumnWidth="0*" TextColumnWidth="*" ButtonBackgroundMargin="-23,-29"
                                  ButtonTextAlignment="Center"
                                  NormalButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/矩形@2x.png"
                                  HoverButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/矩形@2x(1).png"
                                  PressedButtonBackground="pack://application:,,,/CustomControls;component/Resourse/Images/矩形@2x(2).png"
                                  Text="进入" CornerRadius="4"/>
        </StackPanel>
    </Grid>
</Window>

整体效果

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值