WPF-依赖属性和附加属性《十》

发布于:2023-01-15 ⋅ 阅读:(199) ⋅ 点赞:(0)

非常重要

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

依赖属性(Dependency property)

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

1.首先看一下依赖属性怎么建立的,输入propdp,点击tab按钮2次,就会自动出现

 2.建立一个默认的依赖属性

补充:如果建立一个类报错的话

 继承依赖对象就没有报错了,上面继承的Windows其实也是继承了依赖对象,所以不会报错

 其实点击任意一个控件,看里面的属性,都含有依赖属性

3. 使用依赖属性给Button增加鼠标划过显示颜色,建立一个类,继承Button 

4.使用快捷键propdp建立完成,代码如下

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

namespace WpfApp2
{
    public class ButtonEx : Button
    {
        static ButtonEx()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonEx), new FrameworkPropertyMetadata(typeof(ButtonEx)));//使ButtonEx去读取ButtonEx类型的样式,而不是去读取Button的样式
        }
        public int MyButtonEx
        {
            get { return (int)GetValue(ButtonExProperty); }
            set { SetValue(ButtonExProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ButtonExProperty =
            DependencyProperty.Register("MyButtonEx", typeof(int), typeof(ButtonEx), new PropertyMetadata(0));
                                    //依赖属性名称,依赖属性数据类型,所属哪个类中,属性的元数据
    }
}

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

6.增加样式

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:WpfApp2"
                    >
    <Style TargetType="{x:Type local:ButtonEx}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <DockPanel Name="dpCon" Width="{Binding Width, RelativeSource={x:Static RelativeSource.TemplatedParent}}" 
                               Height="{Binding Height, RelativeSource={x:Static RelativeSource.TemplatedParent}}"
                               Background="{Binding Background, RelativeSource={x:Static RelativeSource.TemplatedParent}}"
                               ToolTip="{Binding ToolTip, RelativeSource={x:Static RelativeSource.TemplatedParent}}"
                               >
                        <DockPanel DockPanel.Dock="Top" Name="dpBtn">
                            <DockPanel.Background>
                                <ImageBrush ImageSource="{Binding ForeImage, RelativeSource={x:Static RelativeSource.TemplatedParent}}" Stretch="{Binding Stretch,RelativeSource={x:Static RelativeSource.TemplatedParent}}"/>
                            </DockPanel.Background>
                            <TextBlock FontSize="15" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#f9fcff" Text="{Binding Content, RelativeSource={x:Static RelativeSource.TemplatedParent}}"></TextBlock>
                        </DockPanel>
                    </DockPanel>
                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding IsMouseOver,RelativeSource={x:Static RelativeSource.Self}}" Value="True">
                            <Setter Property="Background" TargetName="dpBtn">
                                <Setter.Value>
                                    <ImageBrush ImageSource="{Binding BackImage, RelativeSource={x:Static RelativeSource.TemplatedParent}}" Stretch="{Binding Stretch,RelativeSource={x:Static RelativeSource.TemplatedParent}}"/>
                                </Setter.Value>
                            </Setter>
                            <Setter Property="Background" TargetName="dpCon" Value="{Binding MouseOverBackColor, RelativeSource={x:Static RelativeSource.TemplatedParent}}"></Setter>
                        </DataTrigger>
                        <Trigger Property="IsEnabled" Value="true"/>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="Gray"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

7.前台界面 

 

可见,经过依赖属性之后,ButtonEx按钮就带了MouseOverBackColor属性,可以对其进行设置颜色。  依赖修改的比附加更多。依赖是整体都修改了,而附加是用哪个再附加哪个。

附加属性(DependencyProperty)

        顾名思义,就是附加上面的属性,自身是没有的,别人附加上面的,就变成了自己的属性,就可以使用点. 点击 出来。比如说,wpf中PasswordBox控件是不能进行绑定数据的,但是你把它绑定一个密码,那么就是附加属性了。附加属性,也属于一种依赖属性。

1.附加属性建立,输入propa,点击tab按钮2次

2.修改对应的参数

        public static string GetPassword(DependencyObject obj)
        {
            return (string)obj.GetValue(MyPassword);
        }

        public static void SetPassword(DependencyObject obj, string value)
        {
            obj.SetValue(MyPassword, value);
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MyPassword =
            DependencyProperty.RegisterAttached("Password", typeof(string), typeof(MainWindow), new PropertyMetadata(null));

3.前端进行调用

<Window x:Class="WpfApp2.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:WpfApp2"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <PasswordBox local:MainWindow.Password="{Binding PW}" HorizontalAlignment="Left" Margin="416,183,0,0" VerticalAlignment="Top" Width="120"/>

    </Grid>
</Window>

4.写调用方法

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 WpfApp2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            PW = "123456";
            this.DataContext = this;
        }

        public static string GetPassword(DependencyObject obj)
        {
            return (string)obj.GetValue(MyPassword);
        }

        public static void SetPassword(DependencyObject obj, string value)
        {
            obj.SetValue(MyPassword, value);
        }

        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MyPassword =
            DependencyProperty.RegisterAttached("Password", typeof(string), typeof(MainWindow), new PropertyMetadata((s,e)=>
            {
                var pw = s as PasswordBox;
                pw.Password = e.NewValue.ToString();
            }));   //这里和xaml中建立关系

        public string PW { get; set; }
    }
}