前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[UWP]附加属性1:概述

[UWP]附加属性1:概述

作者头像
dino.c
发布2019-01-18 10:57:21
6890
发布2019-01-18 10:57:21
举报
文章被收录于专栏:dino.c的专栏dino.c的专栏

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

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

代码语言:javascript
复制
/// <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中使用附加属性:

代码语言:javascript
复制
<StackPanel Grid.Row="1"/>

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

代码语言:javascript
复制
button.SetValue(Grid.RowProperty, 1);

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

代码语言:javascript
复制
/// <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,生成代码如下:

代码语言:javascript
复制
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:

代码语言:javascript
复制
<?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>
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-02-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 什么是附加属性(attached property )
  • 2. 附加属性有什么作用
  • 3. 附加属性的使用
  • 4. 完整的自定义附加属性
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档