zoukankan      html  css  js  c++  java
  • [UWP]附加属性1:概述

    1. 什么是附加属性(attached property )

    附加属性依赖属性的一种特殊形式,常见的Grid.Row,Canvas.Left都是附加属性。

    /// <summary>
    //  从指定元素获取 Left 依赖项属性的值。
    /// </summary>
    /// <param name="obj">The element from which the property value is read.</param>
    /// <returns>Left 依赖项属性的值</returns>
    public static double GetLeft(DependencyObject obj)
    {
        return (double)obj.GetValue(LeftProperty);
    }
    
    /// <summary>
    /// 将 Left 依赖项属性的值设置为指定元素。
    /// </summary>
    /// <param name="obj">The element on which to set the property value.</param>
    /// <param name="value">The property value to set.</param>
    public static void SetLeft(DependencyObject obj, double value)
    {
        obj.SetValue(LeftProperty, value);
    }
    
    /// <summary>
    /// 标识 Left 依赖项属性。
    /// </summary>
    public static readonly DependencyProperty LeftProperty =
        DependencyProperty.RegisterAttached("Left", typeof(double), typeof(MyCanvas), new PropertyMetadata(0d));
    

    附加属性的简单定义如上述代码所示。可以看出和依赖属性不同的地方在于没有作为属性包装器的Setter和Getter,而多了两个静态函数GetXXX和SetXXX。并且注册标识符使用DependencyProperty.RegisterAttached而不是DependencyProperty.Register。

    2. 附加属性有什么作用

    和依赖属性不同的地方在于,依赖属性是依赖对象本身的属性,附加属性是附加在其他对象身上的属性,通俗来说就是在别的对象内插入自己的属性。上面提到的Grid.Row,就是Grid将Row属性附加到没有Row属性的其它类中,以便进行布局。

    3. 附加属性的使用

    附加实行的使用方式和依赖属性十分相似。

    在XAML中使用附加属性:

    <StackPanel Grid.Row="1"/>
    

    在C#代码中使用附加属性:

    button.SetValue(Grid.RowProperty, 1);
    

    4. 完整的自定义附加属性

    /// <summary>
    //  从指定元素获取 Left 依赖项属性的值。
    /// </summary>
    /// <param name="obj">The element from which the property value is read.</param>
    /// <returns>Left 依赖项属性的值</returns>
    public static double GetLeft(DependencyObject obj)
    {
        return (double)obj.GetValue(LeftProperty);
    }
    
    /// <summary>
    /// 将 Left 依赖项属性的值设置为指定元素。
    /// </summary>
    /// <param name="obj">The element on which to set the property value.</param>
    /// <param name="value">The property value to set.</param>
    public static void SetLeft(DependencyObject obj, double value)
    {
        obj.SetValue(LeftProperty, value);
    }
    
    /// <summary>
    /// 标识 Left 依赖项属性。
    /// </summary>
    public static readonly DependencyProperty LeftProperty =
        DependencyProperty.RegisterAttached("Left", typeof(double), typeof(MyCanvas), new PropertyMetadata(0d, OnLeftChanged));
    
    
    private static void OnLeftChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        double oldValue = (double)args.OldValue;
        double newValue = (double)args.NewValue;
        if (oldValue == newValue)
            return;
    }
    
    
    

    以上代码为一个相对完整的自定义附加属性,自定义附加属性的步骤如下

    1. 使用 DependencyProperty.RegisterAttached注册附加属性标识符,标示符的名称必须是PropertyName+"Property",如这个例子中的"LeftProperty"。在PropertyMetadata中指定属性默认值。

    2. 实现静态的属性访问器函数,名称必须是GetPropertyName 和SetPropertyName,如例子中的public static double GetLeft(DependencyObject obj)和public static void SetLeft(DependencyObject obj, double value)。

    3. 如果需要监视属性值变更,可以在PropertyMetadata中定义一个PropertyChangedCallback方法,一遍命名方式为OnPropertyNameChanged,如上述例子中的private static void OnLeftChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)。

    注意: 属性访问器中不要有多余的代码,理由参考依赖属性。

    VisualStudio自带附加属性的代码段是propa,生成代码如下:

    public static int GetMyProperty(DependencyObject obj)
    {
        return (int)obj.GetValue(MyPropertyProperty);
    }
    
    public static void SetMyProperty(DependencyObject obj, int value)
    {
        obj.SetValue(MyPropertyProperty, value);
    }
    
    // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MyPropertyProperty =
        DependencyProperty.RegisterAttached("MyProperty", typeof(int), typeof(ownerclass), new PropertyMetadata(0));
    
    

    要生成上述例子的完整附加属性代码,可使用自定义的代码段,快捷键是ap:

    <?xml version="1.0" encoding="utf-8"?>
    <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
      <CodeSnippet Format="1.0.0">
        <Header>
          <Keywords>
            <Keyword>ap</Keyword>
          </Keywords>
          <SnippetTypes>
            <SnippetType>Expansion</SnippetType>
          </SnippetTypes>
          <Title>Attached Property</Title>
          <Author>dino.c</Author>
          <Description>For Attached Property</Description>
          <HelpUrl>
          </HelpUrl>
          <Shortcut>ap</Shortcut>
        </Header>
        <Snippet>
          <References>
            <Reference>
              <Assembly>
              </Assembly>
            </Reference>
          </References>
          <Declarations>
            <Literal Editable="true">
              <ID>int</ID>
              <ToolTip>int</ToolTip>
              <Default>int</Default>
              <Function>
              </Function>
            </Literal>
            <Literal Editable="true">
              <ID>MyProperty</ID>
              <ToolTip>属性名</ToolTip>
              <Default>MyProperty</Default>
              <Function>
              </Function>
            </Literal>
           <Literal Editable="false">
    					<ID>classname</ID>
    					<ToolTip>类名</ToolTip>
    					<Function>ClassName()</Function>
    					<Default>ClassNamePlaceholder</Default>
    				</Literal>
          </Declarations>
          <Code Language="csharp">
                  <![CDATA[
            /// <summary>
            //  从指定元素获取 $MyProperty$ 依赖项属性的值。
            /// </summary>
            /// <param name="obj">The element from which the property value is read.</param>
            /// <returns>$MyProperty$ 依赖项属性的值</returns>
            public static $int$ Get$MyProperty$(DependencyObject obj)
            {
                return ($int$)obj.GetValue($MyProperty$Property);
            }
    
            /// <summary>
            /// 将 $MyProperty$ 依赖项属性的值设置为指定元素。
            /// </summary>
            /// <param name="obj">The element on which to set the property value.</param>
            /// <param name="value">The property value to set.</param>
            public static void Set$MyProperty$(DependencyObject obj, $int$ value)
            {
                obj.SetValue($MyProperty$Property, value);
            }
    
            /// <summary>
            /// 标识 $MyProperty$ 依赖项属性。
            /// </summary>
            public static readonly DependencyProperty $MyProperty$Property =
                DependencyProperty.RegisterAttached("$MyProperty$", typeof($int$), typeof($classname$), new PropertyMetadata(0,On$MyProperty$Changed));
    
    
            private static void On$MyProperty$Changed(DependencyObject obj, DependencyPropertyChangedEventArgs args)
            {
                $classname$ target = obj as $classname$;
                $int$ oldValue = ($int$)args.OldValue;
                $int$ newValue = ($int$)args.NewValue;
                if (oldValue == newValue)
                  return;
            }
    
            ]]>
          </Code>
        </Snippet>
      </CodeSnippet>
    </CodeSnippets>
    
  • 相关阅读:
    virtualbox mout 错误解决
    Python pip 学习
    tzset()与localtime()
    TSE部署实践
    变量和关系符和JAVA基本类型笔记与常考面试题
    实例:判断客户是否中奖与纸牌互换,计算银行本息
    实例:五位数各位数之和与员工实领工资
    关于变量,JAVA基本数据类型,运算符类型,如何从控制台接收输入的数据
    Java的程序执行过程与编译原理
    CMD控制器常用命令
  • 原文地址:https://www.cnblogs.com/dino623/p/6359728.html
Copyright © 2011-2022 走看看