附加属性

附加属性,大家都不陌生,最常见的是Canvas.Left/Canvas.Top,类似的也有Grid.Row/Grid.Column等附加属性。举个最常见的例子

<Canvas>
<Ellipse Fill="Red" Width="100" Height="60" Canvas.Left="56" Canvas.Top="98"/>
</Canvas>

需要说明的是并不是所有的附加属性都是元素放进去后才会有附加效果,上面的例子只是刚好是这种错觉的巧合情况,Grid.Row也属于这种巧合。
还是举个反例来说明

<Canvas>
<Button Content="Copy" ToolTip="Copy the Selected Items"ToolTipService.ShowOnDisabled="True"/>
</Canvas>

ToolTipService类是一个静态类,和Button风马牛不相及,两者之间没有任何关系。

这就是关于附加属性DebugLZQ认为需要说明的地方。

为控件添加一个自定义的附加属性

1.我们有这样的一个XAML

    <Canvas>
<Ellipse Fill="Red" Width="100" Height="60" />
<Rectangle Fill="Blue" Width="80" Height="80" Canvas.Left="100" Canvas.Top="100" />
<Button Content="Hello" Canvas.Left="130" Canvas.Top="30" FontSize="20" />
</Canvas>

假如,我们需要实现控件绕中心旋转一定的角度。通常我们需要写类似的Rotate

        <Ellipse Fill="Red" Width="100" Height="60" RenderTransformOrigin=".5,.5">
<Ellipse.RenderTransform>
<RotateTransform Angle="30" />
</Ellipse.RenderTransform>
</Ellipse>

当然这样OK,程序运行没有问题。
但,缺点是需要写较多的代码;当我们需要为页面其他所有元素实现旋转时,又需要写大量类似的代码。

我们可以通过附加属性来简化代码。如何做呢?

2.为工程添加一个名为RotationManager的类,我们在这个类中添加一个附加属性,让其他都能使用这个附加属性。

我们在类中键入"propa"

和依赖属性类似,连按2次Tab,修改相应命名,如下:

        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("Angle", typeof(double), typeof(RotationManager), new PropertyMetadata(0.0));

这样我们就完成了附加属性的定义。
为了能够在XAML中使用,在XAML中添加如下映射。

<Window x:Class="CreatingAnAttachedProperty.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CreatingAnAttachedProperty"

这样,页面上的元素就可以使用这个附加属性了,如下:

    <Canvas>
<Ellipse Fill="Red" Width="100" Height="60" Canvas.Left="56" Canvas.Top="98" local:RotationManager.Angle="30"/>
<Rectangle Fill="Blue" Width="80" Height="80" Canvas.Left="285" Canvas.Top="171" local:RotationManager.Angle="45" />
<Button Content="Hello" Canvas.Left="265" Canvas.Top="48" FontSize="20" local:RotationManager.Angle="60"/>
</Canvas>

3.此时编辑器,没有任何旋转,若我们此时运行程序,也没有任何的旋转效果,为什么?因为我们只是添加了一个附加属性,给它付了个初值,当值改变的时候,我们并没有添加相应的处理逻辑。
依次,我们需要返回RotationManager.cs添加相应的值改变事件及事件处理逻辑。如下:

        public static readonly DependencyProperty AngleProperty =
DependencyProperty.RegisterAttached("Angle", typeof(double), typeof(RotationManager), new PropertyMetadata(0.0,OnAngleChanged)); private static void OnAngleChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var element = obj as UIElement;
if (element != null)
{
element.RenderTransformOrigin = new Point(0.5, 0.5);
element.RenderTransform = new RotateTransform((double)e.NewValue);
}
}

添加完成后,我们在编辑器中,看到如下效果:

如果我们运行,则效果如下:

相比于前面挨个挨个的添加Rotate效果,程序是Clearn很多?这就是附加属性带来的便利。

完整的RotationManager.cs如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;//necessary namespace CreatingAnAttachedProperty
{
class RotationManager: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("Angle", typeof(double), typeof(RotationManager), new PropertyMetadata(0.0,OnAngleChanged)); private static void OnAngleChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var element = obj as UIElement;
if (element != null)
{
element.RenderTransformOrigin = new Point(0.5, 0.5);
element.RenderTransform = new RotateTransform((double)e.NewValue);
}
}
}
}

Update:

WPF: Creating parameterized styles with attached properties

Wish it helps.

WPF整理-为控件添加自定义附加属性的更多相关文章

  1. WPF中查找控件的扩展类

    在wpf中查找控件要用到VisualTreeHelper类,但这个类并没有按照名字查找控件的方法,于是搜索网络,整理出下面这个类,感觉用起来很是方便. 贴出来,供大家参考. /// <summa ...

  2. WPF中Ribbon控件的使用

    这篇博客将分享如何在WPF程序中使用Ribbon控件.Ribbon可以很大的提高软件的便捷性. 上面截图使Outlook 2010的界面,在Home标签页中,将所属的Menu都平铺的布局,非常容易的可 ...

  3. WPF 调用WinForm控件

    WPF可以使用WindowsFormsHost控件做为容器去显示WinForm控件,类似的用法网上到处都是,就是拖一个WindowsFormsHost控件winHost1到WPF页面上,让后设置win ...

  4. InteropBitmap指定内存,绑定WPF的Imag控件时刷新问题。

    1.InteropBitmap指定内存,绑定WPF的Imag控件的Source属性 创建InteropBitmap的时候,像素的格式必须为PixelFormats.Bgr32, 如果不是的话在绑定到I ...

  5. easyui中tree控件添加自定义图标icon

    来源于:http://blog.163.com/lintianhuanhai@126/blog/static/165587366201421704420256/ <!DOCTYPE html&g ...

  6. 在WPF程序中将控件所呈现的内容保存成图像(转载)

    在WPF程序中将控件所呈现的内容保存成图像 转自:http://www.cnblogs.com/TianFang/archive/2012/10/07/2714140.html 有的时候,我们需要将控 ...

  7. 【WPF】监听WPF的WebBrowser控件弹出新窗口的事件

    原文:[WPF]监听WPF的WebBrowser控件弹出新窗口的事件 WPF中自带一个WebBrowser控件,当我们使用它打开一个网页,例如百度,然后点击它其中的链接时,如果这个链接是会弹出一个新窗 ...

  8. 在WPF的WebBrowser控件中抑制脚本错误

    原文:在WPF的WebBrowser控件中抑制脚本错误 今天用WPF的WebBrowser控件的时候,发现其竟然没有ScriptErrorsSuppressed属性,导致其到处乱弹脚本错误的对话框,在 ...

  9. 浅尝辄止WPF自定义用户控件(实现颜色调制器)

    主要利用用户控件实现一个自定义的颜色调制控件,实现一个小小的功能,具体实现界面如下. 首先自己新建一个wpf的用户控件类,我就放在我的wpf项目的一个文件夹下面,因为是一个很小的东西,所以就没有用mv ...

随机推荐

  1. mysql数据库 中文乱码

    看到一篇很好的文章,转录于此 中文乱码似乎是程序编写中永恒的一个话题和难点,就比如MySQL存取中文乱码,但我想做任何事情,都要有个思路才行,有了思路才知道如何去解决问题,否则,即使一时解决了问题,但 ...

  2. PHP写文件函数

    /** * 写文件函数 * * @param string $filename 文件名 * @param string $text 要写入的文本字符串 * @param string $openmod ...

  3. Daily Scrum Meeting ——ThirdDay

    一.Daily Scrum Meeting照片 二.Burndown Chart 三.项目进展 1.完成了github上的文档整理 Transcend/ActivityHelper 2.主界面侧滑框的 ...

  4. mount -t nfs 的使用

    服务安装:1. 在VMware Ubuntu中安装NFS服务: sudo apt-get install nfs-kernel-server2. 安装成功会出现配置文件/etc/exports. ls ...

  5. javascript基础04

    javascript基础04 1.循环语句 1.While 语句: while (exp) { //statements; } var i = 1; while(i < 3){ alert(i) ...

  6. C#高级编程笔记 Delegate 的粗浅理解 2016年9月 13日

    Delegate [重中之重] 委托 定义一:(参考)http://www.cnblogs.com/zhangchenliang/archive/2012/09/19/2694430.html 完全可 ...

  7. mysql 优化实例之索引创建

    mysql 优化实例之索引创建 优化前: pt-query-degist分析结果: # Query 23: 0.00 QPS, 0.00x concurrency, ID 0x78761E301CC7 ...

  8. 单节点下多个Tomcat服务器并存的端口号配置

    一个服务器节点同时安装多个tomcat服务器时,如果仅仅修改访问端口号则会提示端口冲突启动失败,还需要修改另外端口号解决,一共需要修改3处地方,修改如下: 编辑配置文件:server.xml 1.首先 ...

  9. CSS 魔法系列:纯 CSS 绘制三角形(各种角度)

    我们的网页因为 CSS 而呈现千变万化的风格.这一看似简单的样式语言在使用中非常灵活,只要你发挥创意就能实现很多比人想象不到的效果.特别是随着 CSS3 的广泛使用,更多新奇的 CSS 作品涌现出来. ...

  10. web前端学习部落22群 明白何谓Margin Collapse

    明白何谓Margin Collapse 不同于其他很多属性,盒模型中垂直方向上的Margin会在相遇时发生崩塌,也就是说当某个元素的底部Margin与另一个元素的顶部Margin相邻时,只有二者中的较 ...