Silverlight 创建 Customer Control 2:Using DependencyProperty

本文详细介绍了WPF中的依赖属性(DependencyProperty),包括其定义、特点、使用场景及如何注册。通过实例展示了依赖属性如何用于绑定及通知机制。

 

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>

 

转载于:https://www.cnblogs.com/waitrabbit/archive/2010/11/29/1891300.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值