Silverlight实用窍门系列:34.Silverlight中不得不了解使用的依赖属性【附带源码实例】
Silverlight中我们经常使用自定义控件,并且在自定义控件中制作自定义属性,在项目中大量的创建这个自定义控件,每次都需要占用内存来创建这个属性的默认值。可很多时候我们都只需要去使用这个属性的默认值就可以,并不用每次都使用这个属性。所以在Silverlight和WPF中引入了依赖属性这个概念,以节约内存并且可以灵活的使用属性。
首先我们了解一下Silverlight中有3种属性的创建方式:一、CLR自定义属性。二、依赖属性。三、附加属性。
一、下面我们来看一下CLR自定义属性的创建方式如下,相信大家都创建过:
private string _RectWidth;
public string RectWidth
{
get { return _RectWidth; }
set { _RectWidth = value; }
}
二、依赖属性是存储于基类DependencyObject中的一个键值配对字典中的。它并没有存储在所属的类中,所以不会每次都去重新创建一个属性默认值占用内存。下面我们来看看创建一个依赖属性的代码如下:
#region 设置一个X坐标属性
public double X
{
get { return (double)GetValue(XProperty); }
set { SetValue(XProperty, value); }
}
// 创建一个名为X的依赖属性,并且设置这个依赖属性X变化的时候,让rectangle1控件位置也变化。
public static readonly DependencyProperty XProperty =
DependencyProperty.Register("X", typeof(double), typeof(Rectan), new PropertyMetadata(OnXChanged));
private static void OnXChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Rectan rec = d as Rectan;
rec.rectangle1.SetValue(Canvas.LeftProperty, e.NewValue);
}
#endregion
注意在OnXChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)函数中处理在依赖属性变化时进行的操作。在本例中改变rectangle1矩形框的位置。注册好了依赖属性之后我们可以通过XAML方式和CS代码方式来控制自定义控件类的依赖属性分别如下:
XAML方式控制依赖属性:
<uc:Rectan X="15" Y="105" x:Name="Uil" Width="105" Height="45" HorizontalAlignment="Left" VerticalAlignment="Top"></uc:Rectan>
CS代码控制依赖属性:
this.Ikd.SetValue(Rectan.XProperty, 150.0);
this.Ikd.SetValue(Rectan.YProperty, 150.0);
下面我们看注册依赖属性的Register函数的相关参数以及用法:
在这里主要是通过DependencyProperty.Register(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata);函数注册依赖属性的。在OnXChanged()函数中我们可以处理当属性值变化的时候需要进行的逻辑操作。
// 摘要:
// 使用属性的指定属性名称、属性类型、所有者类型和属性元数据注册依赖项属性。
// 参数:
// name:
// 要注册的依赖项对象的名称。
// propertyType:
// 属性的类型。
// ownerType:
// 正注册依赖项对象的所有者类型。
// typeMetadata:
// 属性元数据实例。实例中可以包含一个 System.Windows.PropertyChangedCallback 实现引用。
// 返回结果:
// 一个依赖项对象标识符,应使用它在您的类中设置 public static readonly 字段的值。随后可以在您自己的代码以及任何第三方用户代码中使用该标识符在将来引用该依赖项属性,用于某些操作,比如以编程方式设置该属性的值,或是在代码中附加
// System.Windows.Data.Binding。
public static DependencyProperty Register(string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata);
三、附加属性是一种特殊的依赖属性,是全局依赖属性,它的注册方式是DependencyProperty.RegisterAttached();参数和依赖属性的注册参数相同。
下面我们来看本实例中的完整的XAML代码和XAML.CS代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace SLDependencyProp
{
public partial class Rectan : UserControl
{
public Rectan()
{
InitializeComponent();
}
private string _RectWidth;
public string RectWidth
{
get { return _RectWidth; }
set { _RectWidth = value; }
}
#region 设置一个X坐标属性
public double X
{
get { return (double)GetValue(XProperty); }
set { SetValue(XProperty, value); }
}
// 创建一个名为X的依赖属性,并且设置这个依赖属性X变化的时候,让rectangle1控件位置也变化。
public static readonly DependencyProperty XProperty =
DependencyProperty.Register("X", typeof(double), typeof(Rectan), new PropertyMetadata(OnXChanged));
private static void OnXChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Rectan rec = d as Rectan;
rec.rectangle1.SetValue(Canvas.LeftProperty, e.NewValue);
}
#endregion
#region 设置一个Y坐标属性
public double Y
{
get { return (double)GetValue(YProperty); }
set { SetValue(YProperty, value); }
}
// 创建一个名为X的依赖属性,并且设置这个依赖属性X变化的时候,让rectangle1控件位置也变化。
public static readonly DependencyProperty YProperty =
DependencyProperty.Register("Y", typeof(double), typeof(Rectan), new PropertyMetadata(OnYChanged));
private static void OnYChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Rectan rec = d as Rectan;
rec.rectangle1.SetValue(Canvas.TopProperty, e.NewValue);
}
#endregion
}
}
<UserControl x:Class="SLDependencyProp.Rectan"
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"
mc:Ignorable="d"
d:DesignHeight="45" d:DesignWidth="105">
<Canvas x:Name="LayoutRoot" Background="White">
<Rectangle Height="45" HorizontalAlignment="Left" RadiusX="15" RadiusY="15" Fill="BurlyWood" Name="rectangle1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="105" />
</Canvas>
</UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace SLDependencyProp
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
this.Ikd.SetValue(Rectan.XProperty, 150.0);
this.Ikd.SetValue(Rectan.YProperty, 150.0);
}
}
}
<UserControl x:Class="SLDependencyProp.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:uc="clr-namespace:SLDependencyProp"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<uc:Rectan X="15" Y="105" x:Name="Uil" Width="105" Height="45" HorizontalAlignment="Left" VerticalAlignment="Top"></uc:Rectan>
<uc:Rectan x:Name="Ikd" Width="105" Height="45" HorizontalAlignment="Left" VerticalAlignment="Top"></uc:Rectan>
<uc:Rectan Width="105" Height="45" HorizontalAlignment="Left" VerticalAlignment="Top"></uc:Rectan>
</Grid>
</UserControl>
本实例采用VS2010+Silverlight 4.0编写,如需源码请点击 SLDependencyProp.rar 下载。