当前位置:网站首页>依赖属性、依赖附加属性以及类型转换
依赖属性、依赖附加属性以及类型转换
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 children's physical etiquette Yueqing City training results assessment successfully concluded
- Ruiji takeout project (II)
- 【mysql学习笔记22】索引
- Rxjs TakeUntil 操作符的学习笔记
- Repo sync will automatically switch the correspondence between the local branch and the remote branch - how to customize this behavior
- 瑞吉外卖项目(二)
- Best producer consumer code
- 【mysql学习笔记21】存储引擎
- Get started quickly with jetpack compose Technology
- 匯付國際為跨境電商賦能:做合規的跨境支付平臺!
猜你喜欢

WebApi性能优化

Solution to the problem of repeated startup of esp8266

Tiktok brand goes to sea: both exposure and transformation are required. What are the skills of information flow advertising?

I put a two-dimensional code with rainbow candy

Learning notes of rxjs takeuntil operator

Jetpack compose layout (IV) - constraintlayout

CyCa children's physical etiquette Yueqing City training results assessment successfully concluded

Exception: gradle task assemblydebug failed with exit code 1

Fcpx quickly add subtitles | Final Cut Pro import fcpxml subtitle file does not match the video time? I got it in code

Ruiji takeout project (II)
随机推荐
8. Intelligent transportation project (1)
oracle 函数 触发器
51 SCM time stamp correlation function
22 mathematical modeling contest 22 contest C
Computational Thinking and economic thinking
Rxjs TakeUntil 操作符的学习笔记
MySQL create given statement
Mysql 源码阅读(二)登录连接调试
x86电脑上下载debian的arm64的包
The problem of automatic page refresh after the flyer WebView pops up the soft keyboard
SQL to object thinking vs SQL of object thinking
字符串 实现 strStr()
纳米数据世界杯数据接口,中超数据,体育数据比分,世界杯赛程api,足球比赛实时数据接口
如何自制一个安装程序,将程序打包生成安装程序的办法
2021mathorcupc topic optimal design of heat dissipation for submarine data center
瑞吉外卖项目(二)
Flutter replaces the default icon of Gaud positioning
Shuttle JSON, list, map inter transfer
Can two Mitsubishi PLC adopt bcnettcp protocol to realize wireless communication of network interface?
Huipay international permet au commerce électronique transfrontalier de devenir une plate - forme de paiement transfrontalière conforme!