这一篇博客是关于如何使用附加属性和创建自定义附加属性的。

1. 附加属性使用,

WPF中对附加属性使用最多的莫过于对控件布局时设置控件的位置,例如在Canvas中有一个Rectangle, Ellipse, Button,我们需要设置它们的位置,

    <Canvas>
<Rectangle x:Name="_rect" Fill="LightBlue" Width="100" Height="50" Canvas.Left="200" Canvas.Top="50"/> <Ellipse Width="100" Height="100" Fill="LightCoral" Canvas.Left="150" Canvas.Top="200"/> <Button Content="I am a button" Width="100" Height="35" Canvas.Left="50" Canvas.Bottom="50"/>
</Canvas>

除了在XAML中设置依赖属性外,也可以在C#代码中设置,例如:

   Canvas.SetLeft(_rect, );
Canvas.SetTop(_rect, );

显示效果:

附加属性使用起来非常简单。

2. 自定义附加属性

现在有这样一个需求,需要将上面的Button,Ellipse,Rectangle旋转一定角度。我们可以这样来实现:

XAML:

    <Canvas>
<Rectangle x:Name="_rect" Fill="LightBlue" Width="100" Height="50" Canvas.Top="100" RenderTransformOrigin=".5,.5">
<Rectangle.RenderTransform>
<RotateTransform Angle="45"/>
</Rectangle.RenderTransform>
</Rectangle> <Ellipse Width="150" Height="100" Fill="LightCoral" Canvas.Left="150" Canvas.Top="100" RenderTransformOrigin=".5,.5">
<Ellipse.RenderTransform>
<RotateTransform Angle="60"/>
</Ellipse.RenderTransform>
</Ellipse> <Button Content="I am a button" Width="100" Height="35" Canvas.Left="50" Canvas.Bottom="50" RenderTransformOrigin=".5,.5">
<Button.RenderTransform>
<RotateTransform Angle="160"/>
</Button.RenderTransform>
</Button>
</Canvas>

效果如下:

细心的你已经发现上面的三段代码基本一样,而且还挺长的。我们可以使用附加属性来实现,新建一个RotationHelper类,代码如下:

using System.Windows;
using System.Windows.Media; namespace UseAttachedProperty.Helper
{
public class RotationHelper : DependencyObject
{
public static double GetAngle(DependencyObject obj)
{
return (double)obj.GetValue(AngleProperty);
} public static void SetAngle(DependencyObject obj, double value)
{
obj.SetValue(AngleProperty, value);
} public static readonly DependencyProperty AngleProperty =
DependencyProperty.RegisterAttached("AngleProperty", typeof(double), typeof(RotationHelper),
new PropertyMetadata(0.0,OnAngleChanged)); private static void OnAngleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
UIElement element = d as UIElement; if(element != null)
{
element.RenderTransformOrigin = new Point(0.5, 0.5);
element.RenderTransform = new RotateTransform((double)e.NewValue);
}
}
}
}

将RotationHelper类继承DependencyObject,这样不光Button,Ellipse,可以使用,其他继承自DependencyObject的元素均可使用。

现在在XAML中使用自定义Angle附加属性。

<Window x:Class="UseAttachedProperty.MainWindow"
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:helper="clr-namespace:UseAttachedProperty.Helper"
xmlns:local="clr-namespace:UseAttachedProperty"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Canvas>
<Rectangle x:Name="_rect" Fill="LightBlue" Width="100" Height="50" Canvas.Top="100" helper:RotationHelper.Angle="45" /> <Ellipse Width="150" Height="100" Fill="LightCoral" Canvas.Left="150" Canvas.Top="100" helper:RotationHelper.Angle="60" /> <Button Content="I am a button" Width="100" Height="35" Canvas.Left="50" Canvas.Bottom="50" helper:RotationHelper.Angle="160" />
</Canvas>
</Window>

此时显示效果和上面通过XAML中使用RenderTransform一样。

感谢您的阅读。代码点击这里下载。

PS:目前在工作中,

1. 给TextBox和PasswordBox设置水印文字时,使用到自定义附加属性,示例代码下载

2. 在WPF MVVM模式下,需要直接绑定PasswordBox的Password属性时是不可以的,因为Password属性不是依赖属性,此时使用自定义附加属性解决了这个问题。示例代码下载

WPF QuickStart系列之附加属性(Attached Property)的更多相关文章

  1. WPF QuickStart系列

    接触WPF有一段时间了,现在做的项目也是WPF相关的.所以决定写一个WPF QuickStart系列的文章.也是自己对WPF学习的总结,如果对你有帮助,就非常棒了.因为不善言辞,所以尽量以WPF示例和 ...

  2. WPF QuickStart系列之样式和模板(Style and Template)

    在WPF桌面程序中,当我们想构建一个统一的UI表现时(在不同操作系统下,显示效果一致),此时我们就需要使用到WPF中的样式和模板技术.简单来说,如果我们需要简单的给一个Button设置宽,高,Marg ...

  3. WPF QuickStart系列之数据绑定(Data Binding)

    这篇博客将展示WPF DataBinding的内容. 首先看一下WPF Data Binding的概览, Binding Source可以是任意的CLR对象,或者XML文件等,Binding Targ ...

  4. WPF QuickStart系列之线程模型(Thread Model)

    这篇博客将介绍WPF中的线程模型. 首先我们先来看一个例子,用来计算一定范围内的素数个数. XAML: <Grid> <Grid.RowDefinitions> <Row ...

  5. C# WPF – 利用“Attached Property” 把 RoutedEvent 接上 ICommand

    本文说明怎样把 DoubleClick 连接至 ICommand.方法很多.推荐使用 Attach Property 方式,因为它能把任何 RoutedEvent 接上任何 ICommand. 之前写 ...

  6. UWP开发入门(十一)——Attached Property的简单应用

    UWP中的Attached Property即附加属性,在实际开发中是很常见的,比如Grid.Row: <Grid Background="{ThemeResource Applica ...

  7. Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架

    Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架   本章节,我将通过示例介绍如何搭建mvvmlight开发环境.示例中的我会针对wpf ...

  8. MvvmLight学习篇—— Mvvm Light Toolkit for wpf/silverlight系列(导航)

    系列一:看的迷迷糊糊的 一.Mvvm Light Toolkit for wpf/silverlight系列之准备工作 二.Mvvm Light Toolkit for wpf/silverlight ...

  9. WPF 高级篇 MVVM 附加属性

    原文:WPF 高级篇 MVVM 附加属性 WPF 特性之一 附加属性 在本文里实现文本框内容的验证 public class TextBoxHelper:DependencyObject { publ ...

随机推荐

  1. 隐藏左侧快速导航除DMS导航树之外的其他区域

    <style type="text/css"> /*隐藏左侧快速导航除DMS导航树之外的其他区域*/ .ms-quicklaunchouter { display: n ...

  2. poj 1220(短除法)

    http://poj.org/problem?id=1220 题意:进制转换,把a进制转换为b进制. 如果数据不大的话,那么这个题还是很简单的,但这个题就是数据范围太大,所以这里可以采用短除法来做. ...

  3. FIDO 标准简介

    FIDO 联盟(Fast IDentity Online Alliance)简介 网站:http://fidoalliance.org FIDO Alliance,成立于2012年7月. FIDO的目 ...

  4. docker数据拷贝

    docker数据拷贝的方式有很多种,下面介绍几种数据拷贝的方式:此处只是介绍几种简易的方式,更多方式可以google下. 从容器中向主机拷贝数据 docker cp <containerId&g ...

  5. ios 引入第三方库 运行时找不到函数实现

    今天引入webtrends 这个库,结果一直运行时找不到函数,纳闷了一下午! 后来发现,是other flag没有设置对,对于那些包含category用来扩展ios原始类型的库,链接的时候需要特别的链 ...

  6. ACM/ICPC 之 Prim范例(ZOJ1586-POJ1789(ZOJ2158))

    两道Prim解法范例题型,简单的裸Prim,且两题相较以边为重心的Kruskal解法而言更适合以点为重心扩展的Prim解法. ZOJ1586-QS Network 题意:见Code 题解:直接的MST ...

  7. ACM/ICPC 之 模拟 (HNUOJ 13391-换瓶模拟)

    题意:汽水瓶有三个部分cap+plastic bottle+ label(瓶盖-瓶身-瓶底),给出数据:n为原瓶数,x,y,z为这三个部分可以用相应的数字换取新瓶子,求最大总瓶数. 模拟(暴力) // ...

  8. TokuDB 引擎安装测试

    背景: TokuDB引擎是有Tokutek开发的一个数据库存储引擎,在设计之初便引入了独特的索引算法,在其官网测试的文章中看到TokuDB性能比InnoDB高出很多. MySQL是一个插件式的数据库, ...

  9. 关于MySQL count(distinct) 逻辑的一个bug【转】

    本文来自:http://dinglin.iteye.com/blog/1976026#comments 背景 客户报告了一个count(distinct)语句返回结果错误,实际结果存在值,但是用cou ...

  10. 向数据库中全部表中增加一个字段的SQL

    SELECT 'ALTER TABLE ' + NAME + ' ADD 字段名 int not null default 0' FROM sysobjects AS sWHERE s.[type] ...