• Silverlight:Dependency Property(依赖属性)学习笔记


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

    http://www.wpftutorial.net/DependencyProperties.html 这里有一篇通俗易懂的相关文章,不过是E文的,E文不好的朋友,也可以参考下面的内容:

    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
    xaml部分:
    代码
    <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部分:(技巧:vs2008中,只要键入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中的文本控件的文字也将变成"新值"

    转载请注明来自菩提树下的杨过

    文中源文件代码:DPStudy.rar
    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    使用Jenkins自带功能(不用shell)构建Docker镜像并推送到远程仓库
    方法2:使用Jenkins构建Docker镜像 --SpringCloud
    在jenkins中使用shell命令推送当前主机上的docker镜像到远程的Harbor私有仓库
    解决跟Docker私有仓库登陆,推送,拉取镜像出现的报错
    Linux 内存占用大排查
    方法1:使用Jenkins构建Docker镜像 --SpringCloud
    使用Jenkins编译打包SpringCloud微服务中的个别目录
    使用Jenkins的Git Parameter插件来从远程仓库拉取指定目录的内容
    稀疏检出-使用git检索出仓库里的某一个目录文件,而不是整个仓库的所有文件
    通过 Kubeadm 安装 K8S 与高可用,版本1.13.4
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1630526.html
Copyright © 2020-2023  润新知