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>

[UWP]附加属性1:概述的更多相关文章

  1. [UWP]附加属性2:实现一个Canvas

    5. 附加属性实践:自定义Canvas 附加属性在UWP中是一个十分重要的组成部分,很多功能都依赖于附加属性实现,典型的例子是常用的Grid和Canvas.通常附加属性有三个使用场景:插入属性.触发行 ...

  2. [UWP]依赖属性1:概述

    1. 概述 依赖属性(DependencyProperty)是UWP的核心概念,它是有DependencyObject提供的一种特殊的属性.由于UWP的几乎所有UI元素都是集成于DependencyO ...

  3. [UWP]为附加属性和依赖属性自定义代码段(兼容UWP和WPF)

    1. 前言 之前介绍过依赖属性和附加属性的代码段,这两个代码段我用了很多年,一直都帮了我很多.不过这两个代码段我也多年没修改过,Resharper老是提示我生成的代码可以修改,它这么有诚意,这次就只好 ...

  4. [UWP]xaml中自定义附加属性使用方法的注意项

    ---恢复内容开始--- 随笔小记,欢迎指正 在UWP平台上做WVVM的时候,想针对ListBox的SelectionChanged事件定义一个自定义的命令,于是使用自定义附加属性的方式.可是最后自定 ...

  5. [UWP]了解模板化控件(6):使用附加属性

    1. 基本需求 之前的ContentView2添加了PointerOver等效果,和TextBox等本来就有Header的控件放在一起反而变得鹤立鸡群. 为了解决这个问题,这次把ContentView ...

  6. [UWP 自定义控件]了解模板化控件(6):使用附加属性

    1. 基本需求 之前的ContentView2添加了PointerOver等效果,和TextBox等本来就有Header的控件放在一起反而变得鹤立鸡群. 为了解决这个问题,这次把ContentView ...

  7. UWP&WP8.1 附加属性 和WebView的NavigateToString方法XAML绑定方法

    附加属性,即为添加一个没有的属性的. 使用方法和依赖属性相似,个人理解就是特殊形式的依赖属性. 经常的用处,以一个简单的来说,比如一个控件的某一个属性我们想在XAML中给其绑定数据.但是我们在XAML ...

  8. UWP深入学习三:依赖属性、附加属性和数据绑定

    Dependency properties overview Custom dependency properties Attached properties overview Custom atta ...

  9. [UWP]了解模板化控件(1):基础知识

    1.概述 UWP允许开发者通过两种方式创建自定义的控件:UserControl和TemplatedControl(模板化控件).这个主题主要讲述如何创建和理解模板化控件,目标是能理解模板化控件常见的知 ...

随机推荐

  1. S3C2440启动代码2440init.s彻底解析

    可以选择nand启动和nor启动,这两者之间的关系通过一个按键来选择 这个OM0有何玄机,在数据手册中有这么一段 位宽RAM启动了(当然,还得设置一些东西,下面就说), Nanaflash启动经历的过 ...

  2. ios数据存储——对象归档

    归档:数据从内存与闪存相互转化,类似“序列化”,将数据转换成二进制字节数据 操作:有两种方式,第一种是单个对象作为root进行归档和恢复,一个对象一个文件:第二种,可以同时归档多个对象到一个文件 注意 ...

  3. 【转】mysql-5..6.23-win64.zip安装及配置

    [强烈建议!!!!]把文件夹的名字也改成如下所说的,不然即使你什么环境配置都对,启动服务的时候依然会出现‘net’不是计算机内部或外部的命令这种令人很郁闷的问题了! 原文链接:http://jingy ...

  4. Sqlserver 时间字段批量增加

    update dt_article_attribute_value set end_time = dateadd(mi,30,start_time) create table tb(dt dateti ...

  5. layout_toLeftOf = “@id/XX” 提示找不到该id的控件

    调布局的时候,需要把一个控件A放在另一个控件B的左边,我的xml布局文件是按照顺序从左到右定义的控件,所以先定义的控件A,然后控件B,在控件A的属性中,定义 android:layout_toLeft ...

  6. UVa 10400 - Game Show Math

    题目大意:给出n(n<100)个正整数和一个目标数,按照给出数的顺序,运用+.-.*./四则运算(不考虑优先级),判断能否得出所要的结果. 首先考虑的就是暴力枚举,不过时间复杂度为O(4n),会 ...

  7. div垂直居中(js)

    window.onload = function(){ var xx = document.documentElement.clientHeight; // 470为要垂直居中的div的高度 he = ...

  8. iPhone的刷机 iPhone进UDF

    首先是进入udf出现问题.. 要点是 黑屏后按电源键到屏幕亮了+HOME键再一直按 按到黑屏 4秒左右后 放开HOME键 再按大概7秒就是udf界面了 不是界面~全黑的.你可以电源键是开不了机的. 然 ...

  9. 阿里CEO张勇公开信:把眼光从股市回到客户身上

     8月25日消息,面对全球资本市场的剧烈波动,阿里巴巴集团CEO张勇今日发表致员工信,倡议全体阿里员工把眼光从股市回到客户身上,脚踏实地的服务帮助客户,为客户创造价值,继而为股东和自己创造价值.  张 ...

  10. rsync 实验

    参考1:http://www.jb51.net/LINUXjishu/142722.html 参考2:http://sookk8.blog.51cto.com/455855/328076 主服务器IP ...