首页 > 其他分享 >.NET|--WPF|--笔记合集|--依赖项属性|--2.注册依赖项属性

.NET|--WPF|--笔记合集|--依赖项属性|--2.注册依赖项属性

时间:2024-08-31 10:48:23浏览次数:3  
标签:依赖 DependencyProperty TextBlock -- System Windows 属性

前言


使用一个实例, 其实分2步骤
定义, 实例化.

但是依赖项属性为不能直接实例化, 因为DependencyProperty类没有公开的构造函数,
只能使用静态的DependencyProperty.Register方法创建DependencyProperty实例.

DependencyProperty.Register源码

// System.Windows.DependencyProperty
public static DependencyProperty Register(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback)
{
	RegisterParameterValidation(name, propertyType, ownerType);
	PropertyMetadata defaultMetadata = null;
	if (typeMetadata != null && typeMetadata.DefaultValueWasSet())
	{
		defaultMetadata = new PropertyMetadata(typeMetadata.DefaultValue);
	}
	DependencyProperty dependencyProperty = RegisterCommon(name, propertyType, ownerType, defaultMetadata, validateValueCallback);
	if (typeMetadata != null)
	{
		dependencyProperty.OverrideMetadata(ownerType, typeMetadata);
	}
	return dependencyProperty;
}


DependencyProperty.Register在TextBlock源码中使用

public class TextBlock : FrameworkElement // 其它继承的基类省略.
{
	// 第1步:定义依赖项属性
	public static readonly DependencyProperty TextWrappingProperty;
	
	// 第2步:注册依赖项属性( 本篇笔记要讲的 )
	static TextBlock()
	{
		TextWrappingProperty = 
		DependencyProperty.Register
		(
			"TextWrapping", 
			typeof(TextWrapping), //一个枚举类"System.Windows.TextWrapping"
			typeof(TextBlock), 
			new FrameworkPropertyMetadata(TextWrapping.NoWrap, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender), 
			IsValidTextWrap
		);
	}

	// 注册依赖项属性的参数"ValidateValueCallback",用于验证属性值的回调函数.
	private static bool IsValidTextWrap(object o)
	{
		TextWrapping textWrapping = (TextWrapping)o;
		if (textWrapping != TextWrapping.Wrap && textWrapping != TextWrapping.NoWrap)
		{
			return textWrapping == TextWrapping.WrapWithOverflow;
		}
		return true;
	}

	// 第3步:属性包装器( 以后会说,先注册成功了,再说这一步 )
	public TextWrapping TextWrapping
	{
		get
		{
			return (TextWrapping)GetValue(TextWrappingProperty);
		}
		set
		{
			SetValue(TextWrappingProperty, value);
		}
	}
}

DependencyProperty.Register参数介绍

这个方法是 DependencyProperty.Register 方法的实现,用于注册一个新的依赖项属性。这个方法接受五个参数,分别是 namepropertyTypeownerTypetypeMetadatavalidateValueCallback。以下是对这五个参数的详细解释:

1. name (string)
  • 解释:依赖项属性的名称。
  • 用途:这是依赖项属性的标识符,用于在代码和XAML中引用该属性。它必须是唯一的,以避免冲突。
2. propertyType (Type)
  • 解释:依赖项属性的类型。
  • 用途:指定该依赖项属性能够存储的数据类型。例如,可以是 intdoublestringBrush 等等。这决定了属性可以接受和返回的数据类型。
3. ownerType (Type)
  • 解释:定义依赖项属性的所有者类型。
  • 用途:指示哪个类拥有这个依赖项属性。通常是控件或其他 DependencyObject 派生类。这也用于查找属性的默认值和元数据。
4. typeMetadata (PropertyMetadata)
  • 解释:属性元数据,包括默认值、回调函数和其他属性行为信息。
  • 用途:提供有关属性的附加信息,如默认值、属性改变时的回调、属性影响的布局行为等。这些元数据定义了属性的行为特性。
  • 源码: public PropertyMetadata(object defaultValue, PropertyChangedCallback propertyChangedCallback, CoerceValueCallback coerceValueCallback)...先知道主要有这3个参数, 关于这个PropertyMetadata,开始单独做篇笔记.
  • 疑问:属性元数据的默认值和依赖项属性的值, 有关系不?
5. validateValueCallback (ValidateValueCallback)
  • 解释:用于验证属性值的回调函数。
  • 用途:这是一个委托,用于验证传递给依赖项属性的值是否有效。通过这个回调,可以确保设置到属性上的值符合预期,例如值在一定范围内或满足特定条件。
方法详细解释
  • 参数验证:首先,RegisterParameterValidation 方法用于验证 namepropertyTypeownerType 参数是否有效。这是为了确保参数的正确性和有效性。
  • 默认元数据处理:接下来,方法检查 typeMetadata 是否不为空以及其 DefaultValueWasSet 方法是否返回 true。如果设置了默认值,则创建一个新的 PropertyMetadata 对象,将 typeMetadata 的默认值作为参数传递。
  • 注册属性RegisterCommon 方法用于实际注册属性,返回一个新的 DependencyProperty 实例。这个方法包含了处理属性注册的核心逻辑。
  • 覆盖元数据:如果 typeMetadata 不为空,则调用 OverrideMetadata 方法,将元数据应用到 DependencyProperty 上,以便为特定所有者类型提供特定的行为。
示例

假设我们要注册一个新的依赖项属性 HighlightColor,该属性类型是 Brush,所有者类型是 TextBlock,并且有一个默认值 null。我们还可以提供一个值验证回调来确保只有特定类型的值可以赋给这个属性。

public static readonly DependencyProperty HighlightColorProperty = DependencyProperty.Register(
    "HighlightColor",                         // 属性名称
    typeof(Brush),                            // 属性类型
    typeof(TextBlock),                        // 所有者类型
    new PropertyMetadata(null),               // 属性元数据,默认值为 null
    new ValidateValueCallback(ValidateColor)  // 值验证回调函数
);

// 验证回调函数
private static bool ValidateColor(object value)
{
    return value == null || value is Brush;
}
总结

DependencyProperty.Register 方法的五个参数分别定义了依赖项属性的名称、类型、所有者、元数据和验证逻辑。
通过这些参数,可以详细定义和控制依赖项属性的行为,确保其在应用程序中唯一且高效地工作。

System.Windows.Controls.TextBlock中注册依赖项属性


// 定义依赖项属性
public static readonly DependencyProperty TextProperty;

static TextBlock()
{
        // 注册依赖项属性
        TextProperty = DependencyProperty.Register
        (
        "Text", 
        typeof(string), 
        typeof(TextBlock), 
        new FrameworkPropertyMetadata
            (
                string.Empty, FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsRender, 
                OnTextChanged, 
                CoerceText
            )
        );
}

自己注册一个依赖项属性

# 使用LINQPad运行

/*
注意事项 : 
不能直接启动(F5), 
多次直接启动(F5)会报错 : "不能在同一 AppDomain 中创建多个 System.Windows.Application 实例。"

当报错的时候,有2种解决方案 : 

1.使用"菜单栏--Query--Kill Process and Execute"

2.更改设置 : 
Edit -- Preference -- Advanced -- Execution
Always use Fresh Process per Execution


这2种方法, "kill Process and Execute"和"Always use Fresh Process per Execution",
其实意思是一样~

*/

/*

*/


#region 测试方法

internal void Test()
{
	System.Windows.Controls.Image image = new System.Windows.Controls.Image();
	System.Windows.DependencyObject dependencyObject;
	System.Windows.DependencyProperty dependencyProperty;
	//System.Windows.DependencyProperty dp = new System.Windows.DependencyProperty();
}

#endregion

#region 注册

// 注册
public static readonly System.Windows.DependencyProperty HighlightColorProperty = System.Windows.DependencyProperty.Register
(
	"HighlightColor",										// 属性名称,如果名称是"Text",则会报错:“Text”属性已由“TextBlock”注册。
	typeof(string),                            				// 属性类型
	typeof(System.Windows.Controls.TextBlock),				// 所有者类型,如果使用非派生自DependencyObject的,则会报错":“XXXX”类型必须派生自 DependencyObject。
	new System.Windows.PropertyMetadata(null),				// 属性元数据,默认值为 null
	new System.Windows.ValidateValueCallback(ValidateColor)	// 值验证回调函数
);

// 验证回调函数
private static bool ValidateColor(object value)
{
	return true;
	// 可以增加自己的验证,比如下面的验证↓
	//return value == null || value is System.Windows.Media.Brush;
}


#endregion
// 程序入口
void Main()
{

	System.Windows.Application app = new System.Windows.Application();
	var mainWindow = new MainWindows
	{
		Title = "Main Window",
		Width = 960,
		Height = 400,
		WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen
	};
	app.Run(mainWindow);
}

// 主窗口
public class MainWindows : System.Windows.Window
{
	public MainWindows()
	{
		Init();
	}

	public void Init()
	{
		// 创建一个Grid
		System.Windows.Controls.Grid grid = new System.Windows.Controls.Grid();

		// 创建一个TextBlock
		System.Windows.Controls.TextBlock textBlock = new System.Windows.Controls.TextBlock
		{
			Text = "依赖项属性,\r\n 注册成功 \r\n --zh89233",
		};

		// 将TextBlock添加到Grid
		grid.Children.Add(textBlock);
		// 将Grid设置为Window的内容
		this.Content = grid;
	}
}



a89b6220001a1bb9e7b07cf795065621.png

结尾

其实注册方法, 看着简单, 但是毕竟有5个参数, 
我当时第一次注册时候, 因为参数总是有问题, 我根据提示进行修改后才注册成功的,
大家也可以试试, 真正的让代码运行起来, 能运行到定义和注册, 
就先运行到这里, 到这一步运行对了, 再说下一步. 

其实AI确实能提高学习效率, 以前看不懂的地方, 问一下,
回答的还是有鼻子有眼的, 
特别是书里有些作者的想要表达的"思想感情",真的一下读不出来...

标签:依赖,DependencyProperty,TextBlock,--,System,Windows,属性
From: https://www.cnblogs.com/love-zf/p/18389970

相关文章

  • .NET|--WPF|--笔记合集|--依赖项属性|--1.定义依赖项属性
    前言一般情况下,我们是不用定义依赖项属性的,更多的是直接使用即可.那么何时需要我们定义依赖项属性呢?1.设计自定义的WPF元素;2.为原本不支持数据绑定,动画等WPF功能的代码中,需要添加数据绑定,动画等WPF功能时.定义依赖项属性一般的类型来说,如果想要使用的......
  • .NET|--WPF|--笔记合集|--依赖项属性|--4.依赖项属性值优先级
    前言前几篇笔记讲到了依赖项属性的定义,注册等.接下来就该是依赖项属性的实战了.如果依赖项属性是一个主机的话,前几个步骤还在于组装这个主机,组装好了之后,就要开始使用了,是骡子是马,拉出来遛遛.但是一般任何事物在使用之前,都有一些注意事项,如果不了解这些注......
  • 8.4linux定时任务-环境变量-数据库
    配合SUID本地环境变量提权思路原理:利用sh环境变量替换,使得/tmp/ps得到root权限;ps=sh过程:手写调用文件-编译-复制文件-增加环境变量-执行gccdemon1.c-oshellcp/bin/sh/tmp/psexportPATH=/tmp:$PATH#webshell权限无法设置环境变量./shellid提前本地定时任务(cronta......
  • .NET|--WPF|--笔记合集|--依赖项属性|--3.属性包装器
    前言属性包装器的主要作用是将依赖属性的访问方式转换为标准的CLR属性访问方式,从而使代码更加简洁、直观,并提供一致性和更好的开发体验。通过属性包装器,开发者可以利用依赖属性的高级功能,同时保持代码的可读性和易用性。"属性包装器"在TextBlock源码中使用publicclass......
  • [DPDK] Docker容器内安装DPDK
    Docker安装DPDK参考:容器安装DPDK。确认版本兼容性我使用的是Mellanox-5网卡。为了确认支持的DPDK版本,请先确认自己的OFED和frimware版本。查看firmware版本:$ibstatCA'mlx5_0'CAtype:MT4119Firmwareversion:16.35.3006查看OFED版本:$ofed_info-......
  • linux磁盘已满,查看哪个文件占用多
    使用df-h查看磁盘空间占用情况FilesystemSizeUsedAvailUse%Mountedonudev3.9G03.9G0%/devtmpfs799M3.1M796M1%/run/dev/vda199G99G0G100%/tmpfs3.9G03.9G0%/dev/shmtmpfs......
  • 一个免费好用的魔法
    这款虽然是免费的但一天只能免费一个小时,但你可以多造几个号就能一直免费用的时候要把火绒,360等类似的软件关了,不然有时候会得不了。因为是免费的所以有人数限制,一般在9.30之后人都特别多,只有到晚上或者中午和早上时候人少,手机端和PC端是分开的,手机端人是特别少的。官网连接:htt......
  • 网络安全公开数据集Maple-IDS,恶意流量检测数据集开放使用!
    MapleDataset枫叶数据集MapleDataset枫叶数据集由东北林业大学网络安全实验室(https://maple.nefu.edu.cn/lab/)公开发布,是用于入侵检测评估的数据集,其目的在于提升异常基础入侵检测系统(IDS)以及入侵预防系统(IPS)的性能与可靠性。在网络攻击愈发复杂的当下,拥有一个可靠且紧跟时代的......
  • vue3 导出为Excel文件
    服务端给的一个下载接口:/order/exportOrderOpenInvoice导出转化为ExcelconstexportOrder=async()=>{ letreqData={};  letexportOrderOpenInvoiceUrl="/order/exportOrderOpenInvoice";   try{   constresponse=awaitaxios.get(exportOrderOpenInvo......
  • 【网络知识系列】域名抢注
    原创祺印说信安以下文章来源于河南等级保护测评,作者铸盾安全一、概述域名仿冒尝试利用用户在地址栏中直接输入URL时引入的印刷错误(即“打字错误”)。通过利用用户错误,网络威胁行为者将毫无戒心的用户引导至与原始域名极为相似的非法域名。这种策略涉及购买和注册与现有域名......