Silverlight依赖属性

觉得这篇文章写得不错,让我理解了Dependency Propperties,转载过来,让更多的人学习下。

转载自:http://virgoooos.iteye.com/blog/592047,如果您对转载有异议,请通知我。

学习SL/WPF,Dependency Properties(依赖属性)是一个全新(陌生)但又无法回避的概念。

1.为什么会出现依赖属性?

先回想一下传统的属性(Property):通常我们读取或赋值一个属性时,实际上是在对属性背后的某个私有成员进行读写。那么随着对象的属性越来越多,再加上从对象派生出去的子对象,子对象再生出“孙子”对象......最终的对象运行实例中会有大量的私有成员,而每私有成员都要分配内存,占用一定的资源。

但反过来想想,通常我们在使用一个控件/对象时,往往只用到了某几个属性,大部分属性(有时候甚至达到90%以上)都是采用的默认值(或者也可以理解为没有用到),这对于WPF/SL来说无疑是一种极大的性能损耗。

所以在此背景之下,DP(Dependency Properties的简称)就出现了,我们再回想一下静态(static)方法或成员,静态成员/方法的调用不依赖于实例,它是class级别的,不管这个类有多少个实例,静态成员在内存中只占一份,这正是我们所要的!


2.依赖属性的大致原理及好处

所有具备依赖属性的对象,都是继承自DependencyObject,DependencyObject中有一个"字典"存储区用来存放依赖属性,而且都是用static方式读取的,所以你现在应该想明白了:为啥不能直接用txt.Left = xxx来直接赋值,而必须用txt.SetValue(Canvas.Left,xxx)来处理,因为static成员是实例无法调用的。

DP的优点: 
(1)有效降低内存消耗。 
(2)直接继承上级的属性值(这里也解释了为什么上级控件对下级控件自动布局,因为下级控件自动继承了上级控件的相关属性值) 

(3)自动实现了“变化通知”(dp有内置的Change Notification回调接口)


3.依赖属性值的读取策略  

 

这张图描述了GetValue与SetValue的内部读取策略。


4.依赖属性的使用示例:

下面我们演示如何给一个用户自定义控件添加Message依赖属性

(1)先建一个Silverlight User Control,取名为MyControl

<UserControl x:Class="DPStudy.MyControl"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Border CornerRadius="5" BorderThickness="3"
		BorderBrush="#FFEF410D" Width="300" Height="40" Margin="5">
    <TextBlock x:Name="txt" Text="" VerticalAlignment="Center"
		HorizontalAlignment="Center"></TextBlock>
  </Border>
</UserControl>

CS部分:(技巧:Visual Studio中只要键入propdp,再连敲二次Tab键,vs就会自动添加一个依赖属性的代码模板) 

using System.Windows;  
using System.Windows.Controls;  
  
  
namespace DPStudy  
{  
	public partial class MyControl : UserControl  
	{  
			  
		  
		public static readonly DependencyProperty MessageProperty = DependencyProperty.Register("Message", typeof(string), typeof(MyControl), new PropertyMetadata("Message的默认值", new PropertyChangedCallback(OnMessagePropertyChanged)));  
  
		public string Message  
		{  
			get { return (string)GetValue(MessageProperty); }  
			set { SetValue(MessageProperty, value); }  
		}  
  
		/// <summary>  
		/// Message变化时的通知处理  
		/// </summary>  
		/// <param name="d"></param>  
		/// <param name="e"></param>  
		private static void OnMessagePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)  
		{  
			MyControl ctl = d as MyControl;  
			ctl.txt.Text = d.GetValue(MyControl.MessageProperty).ToString();  
		}        
  
		public MyControl()  
		{  
			InitializeComponent();  
  
			this.Loaded += new RoutedEventHandler(MyControl_Loaded);  
		}  
  
		void MyControl_Loaded(object sender, RoutedEventArgs e)  
		{  
			this.txt.Text = Message;//初始加载时,显示Message的初始值  
		}  
	}  
}  
这里我们定义了一个Message的string类型依赖属性,和普通属性的区别是:必须使用DependencyProperty.Register来注册该属性,而且“属性命名”要以Property为后缀;另外在读取时,必须调用SetValue/GetValue静态方法来读取其值,最后我们还可以添加一个"属性值变化时的"回调处理。
(2)将MyControl放到MainPage.xaml中小试牛刀 

MainPage.Xaml内容如下: 

<UserControl x:Class="DPStudy.MainPage"  
	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:l="clr-namespace:DPStudy"  
	mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">  
  <StackPanel x:Name="LayoutRoot">          
		<l:MyControl x:Name="myctl"></l:MyControl>  
		<Button Click="Button_Click" Content="改变Message属性值" Width="130" ></Button>  
	</StackPanel>  
</UserControl>  

MainPage.Xaml.cs内容如下: 

using System.Windows;  
using System.Windows.Controls;  
  
namespace DPStudy  
{  
	public partial class MainPage : UserControl  
	{  
		public MainPage()  
		{  
			InitializeComponent();              
		}  
		 
		private void Button_Click(object sender, RoutedEventArgs e)  
		{  
			myctl.SetValue(MyControl.MessageProperty, "新值");  
		}  
	}  
}  

运行后,点击按钮将改变MyControl控件的Message属性值,同时MyControl中的文本控件的文字也将变成"新值"。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值