WPF-依赖属性《十》

非常重要

依赖属性和附加属性,两者是有关系的,也是有些区别的,很多时候,可能会把两者混淆了。

依赖属性(Dependency property)

        就是一种自己没有值,并能通过使用Binding从数据源获取值,也就是依赖别人身上的属性,拥有依赖属性的对象,称为依赖对象。

1.下面举例给按钮增加一个依赖属性,把图片和按钮封装在一起,当做一个控件来使用,创建一个项目

  

2.增加一个类ButtonEx,继承Button

创建ButtonEx类的时候,选择“自定义控件”即可,会自动产生模板。

可以使用快捷键创建,输入propdp,点击tab按钮2次,就会自动出现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows;
using System.Windows.Controls;

namespace btnDemo
{
    public class ButtonEx : Button
    {
        static ButtonEx()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonEx), new FrameworkPropertyMetadata(typeof(ButtonEx)));//使ButtonEx去读取ButtonEx类型的样式,而不是去读取Button的样式
        }


        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, OnButtonTypeChangedCallback));

        //此方法是回调
        private static void OnButtonTypeChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            //此处回调,可以修改按钮上面的默认值,初始化的时候,就走这里
            var res = d as ButtonEx;
            res.ButtonType = (ButtonType)e.NewValue;
            //throw new NotImplementedException();
        }

        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 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 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 MousePressedBackground
        {
            get { return (Brush)GetValue(MousePressedBackgroundProperty); }
            set { SetValue(MousePressedBackgroundProperty, value); }
        }

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

    /// <summary>
    /// 按钮和图片组合的类型
    /// </summary>
    public enum ButtonType
    {
        Normal,
        Icon,
        Text,
        IconText,    //图片在左边
        TextIcon     //图片在右边
    }
}

3.建立ButtonEx的样式,建立资源字典Dictionary1.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                     xmlns:Controls="clr-namespace:btnDemo"
                    >
    <Style TargetType="{x:Type Controls: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 Controls:ButtonEx}">
                            <Border x:Name="border" Background="{TemplateBinding Background}"  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 Controls: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 Controls: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="MouseOverBackground" Value="#555"/>
                <Setter Property="MousePressedBackground" Value="#555"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Controls:ButtonEx}">
                            <Border Name="bor">
                                <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"/>
                                    <Setter Property="Background" Value="{Binding MouseOverBackground  ,RelativeSource={RelativeSource TemplatedParent}}" TargetName="bor"/>
                                </Trigger>
                                <Trigger Property="IsPressed" Value="True">
                                    <Setter Property="Foreground" Value="{Binding MousePressedForeground,RelativeSource={RelativeSource TemplatedParent}}" TargetName="Txt"/>
                                    <Setter Property="Background" Value="{Binding MousePressedBackground  ,RelativeSource={RelativeSource TemplatedParent}}" TargetName="bor"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
            <!--图片在右-->
            <Trigger Property="ButtonType" Value="TextIcon">
                <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 Controls:ButtonEx}">
                            <Border>
                                <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                                    <TextBlock x:Name="Txt" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                                    <Image Source="{TemplateBinding Icon}" Stretch="None"/>
                                </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>
</ResourceDictionary>

别忘记在App.xaml中引用

    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/WpfApp4;component/Dictionary1.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>

4.前台界面 

<Window x:Class="btnDemo.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:btnDemo"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel  Orientation="Vertical" HorizontalAlignment="Center">
            <Button Width="200" Height="50" Content="13212"  Background="Red" />
            <local:ButtonEx Width="200"   Height="50" Content="图在左" Icon="/imgs/1.png" MouseOverForeground="Green"   MouseOverBackground="Blue"  MousePressedForeground="Red"   MousePressedBackground="Yellow"  Click="ButtonEx_Click" Background="Red"     ButtonType="IconText"/>
            <local:ButtonEx Width="200"   Height="50" Content="图在右" Icon="/imgs/1.png"    ButtonType="TextIcon" />
        </StackPanel>

    </Grid>
</Window>

5.效果

可见,经过依赖属性之后,ButtonEx按钮就带了Icon属性,等等其他属性,可以对其进行设置颜色。 

在ButtonEx类中建立的属性,需要在xaml中去使用,2者需要结合起来使用,如果是封装控件那么2者都需要(在类和xaml中),如果是改变单独的控件,只需要在xaml中写样式就行了。

源码

https://download.csdn.net/download/u012563853/88623261

来源:

WPF-依赖属性《十》_wpf附加属性和依赖属性的使用场景-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

故里2130

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值