依赖属性

一 、依赖属性

1、 依赖属性的意义与作用

  数据绑定

2、定义依赖属性

        基本:声明  注册  包装
        //1  声明
        public static DependencyProperty valueProperty;
       //2   注册 
        static DependenProperties()
        {
            valueProperty = DependencyProperty.Register("value", typeof(string), typeof(DependenProperties),new PropertyMetadata(default(string)));
        }
        //3 包装 
        public string value
        {
            get
            {
                return (string)this.GetValue(valueProperty);
            }
            set
            {
               this.SetValue(valueProperty, "小明");
            }
        }
备注:在类中必须继承 DependencyObject

3、依赖属性回调方法与参数

 ValidateValueCallback :属性值验证回调
  //2   注册 
 static DependenProperties()
 {
    valueProperty = DependencyProperty.Register("value", typeof(string), typeof(DependenProperties),new PropertyMetadata(default(string),new PropertyChangedCallback (OnValueChangedCallback)),new ValidateValueCallback(OnValidateValueCallback));
 }
//回调方法必须是静态方法
//参数一:DependencyObject  : 属性所在的对象  
//参数二:DependencyPropertyChangedEventArgs : 变化动作所关联的数据
public static void  OnValueChangedCallback(DependencyObject  o,DependencyPropertyChangedEventArgs arg)
{
    ...... 
}
//验证回调函数
//参数一:Object :属性将要写入的值【最新值】
//返回值:bool 类型:是否允许写入
public static bool  OnValidateValueCallback(Object o)
{
    ...... 
   return true;
}
 CoerceValueCallback:强制值回调

  代码如下:
  //2   注册 
 static DependenProperties()
 {
    valueProperty = DependencyProperty.Register("value", typeof(string), typeof(DependenProperties),new PropertyMetadata(default(string),new PropertyChangedCallback (OnValueChangedCallback),new CoerceValueCallback() ),new ValidateValueCallback(OnValidateValueCallback));
 }
//回调方法必须是静态方法
//参数一:DependencyObject  : 属性所在的对象  
//参数二:DependencyPropertyChangedEventArgs : 变化动作所关联的数据
public static void  OnValueChangedCallback(DependencyObject  o,DependencyPropertyChangedEventArgs arg)
{
    ...... 
}
//验证回调函数
//参数一:Object :属性将要写入的值【最新值】
//返回值:bool 类型:是否允许写入
public static bool  OnValidateValueCallback(Object o)
{
    ...... 
   return true;
}
//强制回调函数
// <param name="d">属性对象</param>
/// <param name="baseValue">当前属性的最新值</param>
/// <returns>希望属性可以接收的值</returns>
public  static void OnCoerceValueCallback(DependencyObject d, object baseValue)
{
     return  null;
}
 PropertyChangedCallback:属性变化回调

  代码如下:
  //2   注册 
 static DependenProperties()
 {
    valueProperty = DependencyProperty.Register("value", typeof(string), typeof(DependenProperties),new PropertyMetadata(default(string),new PropertyChangedCallback (OnValueChangedCallback) ));
 }
//回调方法必须是静态方法
//参数一:DependencyObject  : 属性所在的对象  
//参数二:DependencyPropertyChangedEventArgs : 变化动作所关联的数据
public static void  OnValueChangedCallback(DependencyObject  o,DependencyPropertyChangedEventArgs arg)
{
    ...... 
}

注意:

   属性注册:  【推荐】
//属性注册
 static CallBack() 
        {
            ValueProperty = DependencyProperty.Register(
                "Value",
                typeof(string),
                typeof(CallBack),
                new FrameworkPropertyMetadata(default(string),  FrameworkPropertyMetadataOptions.BindsTwoWayByDefault|  FrameworkPropertyMetadataOptions.AffectsMeasure,
                new PropertyChangedCallback(OnValueChangesCallBack),new CoerceValueCallback (OnCoerceValueCallback)),
                new ValidateValueCallback(ValidateValueCallback)
                );
        }
//FrameworkPropertyMetadata 对象比PropertyMetadata多了几个参数:
//其中的 FrameworkPropertyMetadataOptions. |  FrameworkPropertyMetadataOptions. 选项参数,当值发生变化后他会重新渲染页面,重新显示最新值。 
//FrameworkPropertyMetadataOptions选项:

//AffectsArrange、AffectsMeasure、AffectsParentArrange、AffectsParentMeasure:属性变化的时候,需要通知容器进行重新测量和排列。Margin值变化的时候,就会把相邻的对象挤开

//AffectsRender:属性值的变化导致元素重新渲染、重新绘制

//BindsTwoWayByDefault:默认情况以双向绑定的方式处理绑定行为

//Inherits:继承。FontSize,父对象进行这个属性设置的时候,会对子对象进行相同的影响

//IsAnimationProhibited:这个属性不能用于动画

//IsNotDataBindable:不能使用表达式,设置依赖属性

//Journal:Page开发,属性的值会被保存到 日志

//SubPropertiesDoNotAffectRender:对象属性子属性变化时,不去重新渲染对象

//DefaultValue:默认值

输入属性值----->触发验证回调------>【验证通过】----->写入到属性值------>【值发生变化后】------>触发属性变化回调 -----> 强制回调。

4、依赖附加属性

1、依赖附加属性的意义与作用
给其他对象提供依赖属性。
比如有的属性不能绑定。【password】
2、 定义依赖属性 【新建 Controller类:】
基本:
声明
  public static DependencyProperty PasswordValueProperty;
注册
   public static readonly DependencyProperty MyPropertyProperty =
            DependencyProperty.RegisterAttached("PasswordValue", typeof(string), typeof(Controller), 
                new PropertyMetadata(default(string), 
                    new PropertyChangedCallback(OnPropertyChangedCallback) )
                
                );
包装
      public static string  GetPasswordValue(DependencyObject obj)
        {
            return (string)obj.GetValue(MyPropertyProperty);
        }

        public static void SetPasswordValue(DependencyObject obj, string  value)
        {
            obj.SetValue(MyPropertyProperty, value);
        }

值发生变化后触发的回调函数

  public static void OnPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as PasswordBox).Password = (string)e.NewValue;   
        }
xmal代码如下:
<Window x:Class="WpfApp1.DependenProperties.DependenProperties"
        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:WpfApp1.DependenProperties"
        xmlns:sys="clr-namespace:System;assembly=System.Runtime"
        mc:Ignorable="d"
        Title="DependenProperties" Height="450" Width="800">
    <Window.Resources>
        <sys:String x:Key="pwd">123</sys:String>
    </Window.Resources>
    <Grid>
        <PasswordBox Password="" local:Controller.PasswordValue="{Binding Source={StaticResource pwd}}"></PasswordBox> 
    </Grid>
</Window>

3、主要回调
     回调和依赖属性一样使用。
4、 属性元数据参数
       同依赖属性一样。
5、 使用场景
6、与依赖属性的区别总结
依赖属性:必须在依赖对象里,附加属性不一定。
5、类型转换器
 新建依赖属性类: 【Control】
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace WpfApp1.TypeConverterDemo
{
    [TypeConverter(typeof(TypeConvertDemo))]
    public class Control
    {
        public double Width { get; set; }   
        public double Height { get; set; }

    }

    public class ControlProperty:ContentControl { 
        public Control Value
        {
            get { return (Control)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }
 
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(Control), typeof(ControlProperty), new PropertyMetadata(null)); 

    }
}

 新建数据类型转换类:【TypeConvertDemo】继承 TypeConverter
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfApp1.TypeConverterDemo
{
    public class TypeConvertDemo : TypeConverter
    {
        /// <summary>
        ///类型转换
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="culture">当前本地化信息</param>
        /// <param name="value">传递值</param>
        /// <returns></returns>
        public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
        {
            var temp = Convert.ToString(value).Split(',');
            var c = new Control()
            {
                Width = Convert.ToDouble(temp[0]),
                Height = Convert.ToDouble(temp[1])
            };
            return c;
        }
    }
}

 新建xaml:【Window1.xaml】
<Window x:Class="WpfApp1.TypeConverterDemo.Window1"
        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:WpfApp1.TypeConverterDemo"
        mc:Ignorable="d"
        Title="Window1" Height="450" Width="800">
    <Grid>
        <local:ControlProperty Value="12,34" x:Name="cc"></local:ControlProperty>
        <Button Content="提交" Click="Button_Click"></Button>
    </Grid>
</Window>

Window1.xaml.cs Button触发的事件

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.Shapes;

namespace WpfApp1.TypeConverterDemo
{
    /// <summary>
    /// Window1.xaml 的交互逻辑
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            _ = this.cc.Value;
        }
    }
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容