写点什么

WPF- 依赖属性、依赖附加属性以及类型转换

作者:@@神农
  • 2022 年 3 月 15 日
  • 本文字数:5023 字

    阅读完需:约 16 分钟

一 、依赖属性

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; } }}
复制代码


发布于: 刚刚阅读数: 2
用户头像

@@神农

关注

还未添加个人签名 2022.03.14 加入

好好学习,天天向上!

评论

发布
暂无评论
WPF-依赖属性、依赖附加属性以及类型转换_@@神农_InfoQ写作平台