Don't think you are, know you are

博客园 首页 新随笔 管理

 

DependencyProperty 顾名思义“依赖属性”,它有以下特点: 

  • Root class must be inherited from UIElement or DependencyObject (Eg., Controls, User Controls, Windows (WPF), or any class derived from UIElement (Button, List, Slider etc.))

所在类必须继承自 UIElement 或者 DependencyObject ,比如 Control, User Control。

  • Dependency Properties have to be registered using DependencyProperty.Register method.

依赖属性必须用 DependencyProperty.Register 方法来注册。

  • Since DependencyProperty.Register is a static (C#) / Shared (VB.NET) method, all dependency properties should also be static/Shared fields, also the property changed callback methods should be static/Shared methods.

既然 DependencyProperty.Register 是一个静态方法,所有的 依赖属性 必须是静态的,以及属性改变的 CallBack 方法也必须是静态的。

  • Any property must be a dependency property if the property is being binded to.

如果一个属性是用来做数据绑定的,那么他必须是 依赖属性。

  • By convention, all Dependency Property fields should include the word “Property” at the end of the property name (e.g., for property Value, the Dependency Property name should be ValueProperty).

约定俗成,所有的 依赖属性 命名应当以 "Property" 来结尾。

 

简单来说,依赖属性和属性是一样的,不过它可以有默认值,当值发生变化时有通知机制,另外,在Silverlight中的绑定值,都必须是依赖属性。

 

另外它必须是静态 readonly 的。

 

使用例子如下:

 

        public static readonly DependencyProperty txtValueProperty = DependencyProperty.Register("txtValue", typeof(string), typeof(CustomerControl01), new PropertyMetadata("DefaultValueHere", new PropertyChangedCallback((o, a) =>
        {
            CustomerControl01 c = o as CustomerControl01;
            if (c.txt != null)
            {
                c.txt.Text = o.GetValue(CustomerControl01.txtValueProperty).ToString();
                c.btn.Content = o.GetValue(CustomerControl01.txtValueProperty).ToString();
            }
        }
           )));


        public string TxtValue
        {
            set
            {
                SetValue(txtValueProperty, value);
            }
            get
            {
                return GetValue(txtValueProperty) as string;
            }
        }

 

 它的静态属性是有道理的,我所认为的原因是,你在使用者的xaml文件里定义使用它的属性的时候,比如

<myControl:CustomerControl01 x:Name="myc1"  TxtValue="SetMyValueHere" Height="300" Style="{StaticResource CustomerControl01Style1}"/>

 

注意TxtValue="SetMyValueHere"需要先保存在一个静态变量里. 要想让付得值发挥作用,必须再添加

 public override void OnApplyTemplate()
        {
            FindControls();
            UpdateTxt();
            base.OnApplyTemplate();
        }


        private void UpdateTxt()
        {
            if (btn != null)
            {
                this.btn.Content = TxtValue;
                this.txt.Text = TxtValue;
            }         
        }
        private void FindControls()
        {
            this.btn = this.GetTemplateChild("btn1") as Button;
            this.txt = this.GetTemplateChild("txt1") as TextBox;
        }

就是说你在Find到你的Control之前,你需要把赋值属性的值,先保存在一个静态变量里,所以干脆把DependencyProperty 设为静态方便。

 

当然还有一个好处是,改变属性的值时,如上面的例子,可以调用预先定义的方法。

 

总体感觉是,微软又帮程序员做了很多封装的事情,要说这些东西完全用原先的属性机制,我认为是完全可以实现的,加一个静态变量,把定义的方法放到属性里。

 

但既然微软把这作为一个标准了,我们最好还是按照新的方式编写逻辑代码。 记住,在Silverlight中,如果你要在申明时绑定属性的值,这个属性必须(最好)申明为DependencyProperty。

 

完整例子如下:

 

控件代码:

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 CustomerControlLibrary
{
    public class CustomerControl01 : Control
    {
        public CustomerControl01()
        {
            this.DefaultStyleKey = typeof(CustomerControl01);
        }

        private Button btn;
        private TextBox txt;
        static string aa;

        public override void OnApplyTemplate()
        {
            FindControls();
            UpdateTxt();
            base.OnApplyTemplate();
        }


        private void UpdateTxt()
        {
            if (btn != null)
            {
                this.btn.Content = TxtValue;
                this.txt.Text = TxtValue;
            }
         
        }
        private void FindControls()
        {
            this.btn = this.GetTemplateChild("btn1") as Button;
            this.txt = this.GetTemplateChild("txt1") as TextBox; 
        }

        public static readonly DependencyProperty txtValueProperty = DependencyProperty.Register("txtValue", typeof(string), typeof(CustomerControl01), new PropertyMetadata("fffff", new PropertyChangedCallback((o, a) =>
        {
            CustomerControl01 c = o as CustomerControl01;
            //  c.btn.Content = c.GetValue(CustomerControl01.txtValueProperty).ToString();
            if (c.txt != null)
            {
                c.txt.Text = o.GetValue(CustomerControl01.txtValueProperty).ToString();
                c.btn.Content = o.GetValue(CustomerControl01.txtValueProperty).ToString();
            }
        }
           )));


        public string TxtValue
        {
            set
            {
                SetValue(txtValueProperty, value);
            }
            get
            {
                return GetValue(txtValueProperty) as string;
            }
        }

    }
}

 

调用者xaml代码:

<UserControl
    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:myControl="clr-namespace:CustomerControlLibrary;assembly=CustomerControlLibrary"
    xmlns:System="clr-namespace:System;assembly=mscorlib" x:Class="CustomerControlDemo.MainPage"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
	<UserControl.Resources>
		<Style x:Key="CustomerControl01Style1" TargetType="myControl:CustomerControl01">
			<Setter Property="Template">
				<Setter.Value>
					<ControlTemplate TargetType="myControl:CustomerControl01">
						<Grid>
                            <Button x:Name="btn1" Background="AliceBlue" Margin="80,51,67,58" Width="100" Height="50"/>
                            <TextBox x:Name="txt1" Margin="250,51,67,58" Width="100" Height="50" />
						</Grid>
					</ControlTemplate>
				</Setter.Value>
			</Setter>
		</Style>
	</UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="White">
        <myControl:CustomerControl01 x:Name="myc1"  TxtValue="hhhhhh" Height="300" Style="{StaticResource CustomerControl01Style1}"/>
        <Button x:Name="btn2" Width="50" Height="20" HorizontalAlignment="Left" Click="btn2_Click" />
    </Grid>
</UserControl>

 

posted on 2010-11-29 17:38  炭炭  阅读(528)  评论(0编辑  收藏  举报