主頁 > .NET開發 > WPF依賴屬性

WPF依賴屬性

2022-04-27 06:23:38 .NET開發

理解依賴項屬性

依賴項屬性是專門為WPF創建的,在WPF的核心特征中使用,

創建依賴項屬性

public class DP: DependencyObject
{
	//宣告依賴項屬性  
	public static readonly DependencyProperty MydpProperty;
    
     static DP()
	{
         //指示依賴屬性使用什么服務(如資料系結、影片以及日志)
		FrameworkPropertyMetadata metadata = https://www.cnblogs.com/wzmcnblogs/p/new FrameworkPropertyMetadata(default(double),
			FrameworkPropertyMetadataOptions.AffectsMeasure);
		
         //注冊依賴屬性
		MydpProperty = DependencyProperty.Register("Mydp", typeof(double), typeof(DP), metadata,
			new ValidateValueCallback(ShirtValidateCallback));
         //以上Register方法引數
         //1、屬性名 2、屬性資料型別 3、擁有該屬性的型別 4、附加屬性設定的FrameworkPropertyMetadata物件(可選) 5、驗證屬性的回呼函式(可選)
	}
    
    //添加屬性包裝器 DependencyObject.SetValue() or DependencyObject.GetValue()   
    //DependencyObject.Clear(DP.MydpProperty) 洗掉本地值設定
	public double Mydp
	{
		set { SetValue(MydpProperty, value); }
		get { return (double)GetValue(MydpProperty); }
	}
    
    
	private static bool ShirtValidateCallback(object value)
	{
		return true;
	}
}

使用依賴項屬性

依賴項屬性的兩個關鍵行為——更改通知和動態值識別,Visual Studio快捷鍵 (propdp+Tab)

  • 更改通知:當屬性值發生改變,依賴項屬性不會自動引發事件,以通知一個屬性值發生變化,而是觸發一個受保護的OnPropertyChangedCallBack()方法,該方法通過兩個WPF服務(資料系結和觸發器)傳遞資訊,并呼叫PropertyChangedCallback回呼函式,

  • 動態值識別:按照一定優先級來檢索基本值,檢索改變屬性值的提供者,

    優先級由小到大讓如下:

    1、默認值(FrameworkPropertyMetadata物件設定的值),2、繼承而來的值,3、主題樣式值, 4、專案樣式值,5、本地值(元素物件直接設定的值)

    1、基本值(如上),2、運算式值(資料系結和資源)3、影片的目標,應用該影片,4、運行CoerceValueback回呼函式修的正屬性值,

共享的依賴項屬性

DependencyProperty.AddOwner(Typeof(DependencyObject));
//注冊在TextElement靜態建構式中,在TextBlock靜態建構式中只是簡單的重用
TextBlock.FontFamilyProperty = TextElement.FontFamilyProperty.AddOwner(typeof(TextBlock));

附加屬性

注冊附加屬性使用RegisterAttached()方法,與注冊依賴屬性相同,附加屬性不設定屬性包裝器,通過呼叫兩個靜態方法來設定和獲取屬性值,Visual Studio快捷鍵

(propa+Tab)

//注冊附加屬性  
public static readonly DependencyProperty PasswordProperty =
	DependencyProperty.RegisterAttached("Password", typeof(string), typeof(ADP), new PropertyMetadata(string.Empty));

public static string GetPassword(DependencyObject obj)
{
	return (string)obj.GetValue(PasswordProperty);
}
public static void SetPassword(DependencyObject obj, string value)
{
	obj.SetValue(PasswordProperty, value);
}

//這段代碼不會拋例外,這是因為Button不會去找他不知道的屬性值
Button btn = sender as Button;
btn.SetValue(PasswordBox.PasswordCharProperty, '*');

//PasswordCharProperty是屬于PasswordBox的屬性值,所以密碼圖形會發生改變,
if (this.pwd is PasswordBox passwordbox)
{
	passwordbox.SetValue(PasswordBox.PasswordCharProperty, '*');
}

示例,以PasswordBox添加附加屬性來對密碼進行binding

public class PasswordHelper
{
	/// <summary>
	/// 回呼函式中避免無意義的賦值操作
	/// </summary>
	static bool _isUpdate = false;
		
	/// <summary>
	/// PasswordProperty  附加屬性的功能就像是一個橋梁,通過回呼函式和密碼框事件來實作資料通知,
	/// </summary>
	public static readonly DependencyProperty PasswordProperty =
		DependencyProperty.RegisterAttached("Password", typeof(string), typeof(PasswordHelper),
			new PropertyMetadata(string.Empty, new PropertyChangedCallback(PasswordChangedCallBack)));

	public static string GetPassword(DependencyObject obj)
	{
		return (string)obj.GetValue(PasswordProperty);
	}

	public static void SetPassword(DependencyObject obj, string value)
	{
		obj.SetValue(PasswordProperty, value);
	}
	private static void PasswordChangedCallBack(DependencyObject o, DependencyPropertyChangedEventArgs e)
	{
		//當附加屬性PasswordHelper.PasswordProperty發生改變時,觸發此回呼方法
		PasswordBox passwordbox = o as PasswordBox;
		passwordbox.PasswordChanged -= Passwordbox_PasswordChanged;
		if (!_isUpdate)
		{
			//PasswordProperty系結屬性發生變化時,將PasswordProperty值賦給界面PasswordBox的Password屬性
			passwordbox.Password = e.NewValue?.ToString();
		}
		passwordbox.PasswordChanged += Passwordbox_PasswordChanged;
	}

	private static void Passwordbox_PasswordChanged(object sender, RoutedEventArgs e)
	{
		//當界面PasswordBox的Password發生變化時觸發此事件處理器,
		PasswordBox passwordBox = sender as PasswordBox;
		_isUpdate = true;
		//當密碼值發生變化時,將密碼賦值給附加屬性PasswordProperty
		SetPassword(passwordBox, passwordBox.Password);
		_isUpdate = false;
	}

	public static bool GetAttach(DependencyObject obj)
	{
		return (bool)obj.GetValue(AttachProperty);
	}

	public static void SetAttach(DependencyObject obj, bool value)
	{
		obj.SetValue(AttachProperty, value);
	}

	//初始化時為PasswordBox的PasswordChanged事件添加事件處理器
	public static readonly DependencyProperty AttachProperty =
		DependencyProperty.RegisterAttached("Attach", typeof(bool), typeof(PasswordHelper),
			new PropertyMetadata(false, new PropertyChangedCallback(AttachChangedCallBack)));
	private static void AttachChangedCallBack(DependencyObject o, DependencyPropertyChangedEventArgs e)
	{
		PasswordBox passwordBox = o as PasswordBox;
		if (passwordBox != null)
			return;
		//當舊值是true時,清理事件處理器
		if ((bool)e.OldValue)
		{
			passwordBox.PasswordChanged -= Passwordbox_PasswordChanged;
		}
		//當此附加屬性設定為True時添加事件處理啟
		if ((bool)e.NewValue)
		{
			passwordBox.PasswordChanged += Passwordbox_PasswordChanged;
		}
	}
}
  <PasswordBox  Height="20" Margin="0,10" local:PasswordHelper.Attach="True"
                local:PasswordHelper.Password="{Binding Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

屬性驗證

WPF提供兩種方法來阻止非法值:

  • ValidateValueCallback:該回呼函式可接受或拒絕新值,通常用與捕獲違反屬性約束的明顯錯誤,作為DependencyProperty.Register()的一個引數提供該回呼函式,
  • CoerceValueCallback:該回呼函式能將新值修改為更能接受的值,作為FrameworkPropertyMetadata物件的建構式的一個引數提供該回呼函式,

進行屬性驗證的程序:

1)首先,CoerceValueCallback方法有機會修改提供的值,或者回傳DependencyProperty.UnsetValue,這會完全拒絕修改,

2)接下來激活ValiadataValueCallback方法,回傳true接受一個合法值,回傳false拒絕值,ValiadataValueCallback方法不能訪問設定屬性的物件,不能檢查其他屬性值,

3)最后,如果前兩個階段都成功,就會觸發PropertyChangedCallback方法,

public class MyBtn : Button
{
	public double Max
	{
		get { return (double)GetValue(MaxProperty); }
		set { SetValue(MaxProperty, value); }
	}

	// Using a DependencyProperty as the backing store for Max.  This enables animation, styling, binding, etc...
	public static readonly DependencyProperty MaxProperty =
		DependencyProperty.Register("Max", typeof(double), typeof(MyBtn),
			new PropertyMetadata(default(double), new PropertyChangedCallback(MaxPropertyChangedCallback),
				new CoerceValueCallback(MaxCoerceValueCallback)), new ValidateValueCallback(MaxValidateValueCallback));

    //當此回呼回傳DependencyProperty.UnsetValue時,不會進入PropertyChangedCallback回呼函式,回呼修改后回傳的值型別要與DependncyProperty型別一致,否則會在INorifyPropertyChanged介面的PropertyChanged事件的呼叫的地方拋出例外,
    public static object MaxCoerceValueCallback(DependencyObject sender, object obj)
    {
		if (double.Parse(obj.ToString()) > 50)
		{
			return (object)50.0;
		}
		return obj;

#if test
        return DependencyProperty.UnsetValue;
#endif
    }

    public static void MaxPropertyChangedCallback(DependencyObject o, DependencyPropertyChangedEventArgs e)
	{
        MyBtn button = (MyBtn)o;
        button.Height = (double)e.NewValue;
    }
    
    //當此回呼函式回傳false時,不會再進入CoerceValueCallback和PropertyChangedCallback回呼函式,會在INorifyPropertyChanged介面的PropertyChanged事件的呼叫的地方拋出例外,
    public static bool MaxValidateValueCallback(object value)
    {
        if (double.TryParse(value.ToString(), out double i))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}
作者:藍白永恒
出處:https://www.cnblogs.com/wzmcnblogs/p/16183637.html
文章內容:以上內容均為本人學習整理,如有錯誤,望不吝賜教
著作權:本文著作權歸作者和博客園共有
轉載:歡迎轉載,但未經作者同意,必須保留此段宣告;必須在文章中給出原文連接;否則必究法律責任

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/464953.html

標籤:WPF

上一篇:優化的基于樹狀位壓縮陣列的字符集合

下一篇:如何將資料物件推送到php中的物件陣列

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more