当前位置:网站首页>依赖属性、依赖附加属性以及类型转换
依赖属性、依赖附加属性以及类型转换
2022-06-25 09:38:00 【@@Mr.Fu】
一 、依赖属性
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;
}
}
}
边栏推荐
- CyCa 2022 children's physical etiquette primary teacher class Shenzhen headquarters station successfully concluded
- [MySQL learning notes 22] index
- Question B of the East China Cup: how to establish a population immune barrier against novel coronavirus?
- 处理图片类库
- Match a mobile number from a large number of mobile numbers
- Download the arm64 package of Debian on X86 computer
- Flutter dialog: cupertinoalertdialog
- 22 mathematical modeling contest 22 contest C
- Creating a binary tree (binary linked list) from a generalized table
- Experience in writing C
猜你喜欢
Puzzle (019.2) hexagonal lock
Title B of the certification cup of the pistar cluster in the Ibagu catalog
Rxjs TakeUntil 操作符的学习笔记
Huipay international permet au commerce électronique transfrontalier de devenir une plate - forme de paiement transfrontalière conforme!
Pytorch_ Geometric (pyg) uses dataloader to report an error runtimeerror: sizes of tenants must match except in dimension 0
x86的编码格式
Question B of the East China Cup: how to establish a population immune barrier against novel coronavirus?
Cubemx stm32f105rb USB flash drive reading and writing detailed tutorial
Redis(二)分布式锁与Redis集群搭建
Can two Mitsubishi PLC adopt bcnettcp protocol to realize wireless communication of network interface?
随机推荐
2台三菱PLC走BCNetTCP协议,能否实现网口无线通讯?
PMP考试多少分算通过?
【mysql学习笔记22】索引
Android database security: after the user exits, the transaction rollback log still stores relevant data information
Question B of the East China Cup: how to establish a population immune barrier against novel coronavirus?
【mysql学习笔记21】存储引擎
How to "transform" small and micro businesses (II)?
‘Flutter/Flutter. h‘ file not found
8、智慧交通项目(1)
汇付国际为跨境电商赋能:做合规的跨境支付平台!
Neat Syntax Design of an ETL Language (Part 2)
Redis(一)原理与基本使用
Set the location permission in the shutter to "always allow"
力扣-104. 二叉树的最大深度
NFC read / write mode development - book summary
如何自制一个安装程序,将程序打包生成安装程序的办法
链表 删除链表中的节点
Kotlin Foundation
Etcd教程 — 第四章 Etcd集群安全配置
Repo sync will automatically switch the correspondence between the local branch and the remote branch - how to customize this behavior