WPF 自定义按钮样式(添加依赖属性、圆角)

前言

在 WPF 应用程序中,自定义控件样式是提升用户界面美观性和用户体验的重要手段。本文将详细介绍如何在 WPF 中自定义按钮样式,包括添加依赖属性和实现圆角效果。通过这些步骤,可以创建出既美观又功能强大的自定义按钮,满足各种应用场景的需求。

WPF 中,依赖属性(Dependency Property)是实现控件自定义的关键机制。通过定义和使用依赖属性,你可以轻松地扩展控件的功能,例如添加新的属性或行为。

代码示例

1、自定义CustomButton按钮继承Button
csharp 复制代码
namespace WpfStudy.Buttons
{
    public class CustomButton : Button
    {
        public CornerRadius CornerRadius
        {
            get { return (CornerRadius)GetValue(CornerRadiusProperty); }
            set { SetValue(CornerRadiusProperty, value); }
        }
​
        public static readonly DependencyProperty CornerRadiusProperty =
            DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(CustomButton));
​
        public Brush BackgroundOfMouseHover
        {
            get { return (Brush)GetValue(BackgroundOfMouseHoverProperty); }
            set { SetValue(BackgroundOfMouseHoverProperty, value); }
        }
        public static readonly DependencyProperty BackgroundOfMouseHoverProperty =
            DependencyProperty.Register("BackgroundOfMouseHover", typeof(Brush), typeof(CustomButton));
​
    }
}
2、创建资源字典
ini 复制代码
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:btns="clr-namespace:WpfStudy.Buttons"
                    >
    <Style TargetType="{x:Type btns:CustomButton}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type btns:CustomButton}">
                    <Border x:Name="border" Background="{TemplateBinding Background}" 
                        CornerRadius="{TemplateBinding CornerRadius}"
                        VerticalAlignment="{TemplateBinding VerticalAlignment}"
                        HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                        Width="{TemplateBinding Width}"
                        Height="{TemplateBinding Height}"
                        >
                        <TextBlock Text="{TemplateBinding Content}"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                TextAlignment="Center"
                                x:Name="textBlock"
                                />
                    </Border>
​
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="border" Property="Background" Value="{Binding BackgroundOfMouseHover,RelativeSource={RelativeSource TemplatedParent}}"/>
                            <Setter TargetName="textBlock" Property="Foreground" Value="Black"/>
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter TargetName="border" Property="Background" Value="Red"/>
                            <Setter TargetName="textBlock" Property="Foreground" Value="#fff"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
3、App.xaml中在全局引入资源字典
ini 复制代码
<Application x:Class="WpfStudy.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfStudy"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/Style/CustomButtonStyle.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

4、使用自定义按钮

ini 复制代码
<Window x:Class="WpfStudy.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:WpfStudy"
        xmlns:btns="clr-namespace:WpfStudy.Buttons"
        mc:Ignorable="d"
        WindowStartupLocation="CenterScreen"
        Title="MainWindow" d:DesignHeight="119.5" d:DesignWidth="248.5">
    <Grid>
        <btns:CustomButton Content="打开"
                           Background="Green"
                           Foreground="#fff"
                           HorizontalAlignment="Center"
                           VerticalAlignment="Center"
                           VerticalContentAlignment="Center"
                           HorizontalContentAlignment="Center"
                           Width="100"
                           Height="60"
                           CornerRadius="20"
                           BackgroundOfMouseHover="LightBlue"
                           />
    </Grid>
​
</Window>

思考

复杂、需要注意的地方:

1、依赖属性的命名格式、参数格式,可以使用propdp快捷键。

2、理解资源字典中的标签

哪个标签嵌套哪个标签,分别是在哪一层使用哪个标签。

绑定Button已有依赖属性时使用TemplateBinding,TemplateBinding的含义和用法。

绑定CustomButton自定义依赖属性时使用Binding,注意Binding后面的格式,例如:

ini 复制代码
<Setter TargetName="border" Property="Background" 
Value="{Binding BackgroundOfMouseHover,RelativeSource={RelativeSource TemplatedParent}}"/>

当触发器的Setter中不明确指定哪个组件的属性时,先为组件增加一个x:Name,再用TargetName指定组件的名字。

3、对齐属性的含义

注意区分:

HorizontalAlignment

VerticalAlignment

HorizontalContentAlignment

VerticalContentAlignment

感觉是这样的:

HorizontalAlignment、VerticalAlignment用于描述组件自身位于上层组件的对齐情况。 想象有一个外壳(Border标签),描述该外壳相对上层的位置。

对于ControlTemplate也就只有一个Content,里面正好放一个大的外壳,用于描述该CustomButton。

HorizontalContentAlignment、VerticalContentAlignment 用于描述组件内部的对齐情况。 外壳内部内容相对于外壳的位置。

总结

希望本文能在WPF自定义控件方面为各位提供有益的帮助。期待大家在评论区留言交流,分享您的宝贵经验和建议。

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

作者:greencode

出处:cnblogs.com/redcode/p/18077542

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!

相关推荐
小蜗牛慢慢爬行33 分钟前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
向宇it1 小时前
【从零开始入门unity游戏开发之——unity篇01】unity6基础入门开篇——游戏引擎是什么、主流的游戏引擎、为什么选择Unity
开发语言·unity·c#·游戏引擎
wm10431 小时前
java web springboot
java·spring boot·后端
仰望大佬0072 小时前
Avalonia实例实战五:Carousel自动轮播图
数据库·microsoft·c#
糖朝2 小时前
c#读取json
c#·json
龙少95433 小时前
【深入理解@EnableCaching】
java·后端·spring
溟洵5 小时前
Linux下学【MySQL】表中插入和查询的进阶操作(配实操图和SQL语句通俗易懂)
linux·运维·数据库·后端·sql·mysql
向宇it7 小时前
【从零开始入门unity游戏开发之——C#篇26】C#面向对象动态多态——接口(Interface)、接口里氏替换原则、密封方法(`sealed` )
java·开发语言·unity·c#·游戏引擎·里氏替换原则
SomeB1oody7 小时前
【Rust自学】6.1. 定义枚举
开发语言·后端·rust
SomeB1oody7 小时前
【Rust自学】5.3. struct的方法(Method)
开发语言·后端·rust