附加属性

附加属性,大家都不陌生,最常见的是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. 第3月第11天 vs2005调试 ace编译

    1.vs2005调试 http://blog.csdn.net/u010797208/article/details/40452797 2.macbook ace编译 小坑: 源代码clockid_t ...

  2. 【Alpha版本】冲刺阶段——Day 1

    我说的都队 031402304 陈燊 031402342 许玲玲 031402337 胡心颖 03140241 王婷婷 031402203 陈齐民 031402209 黄伟炜 031402233 郑扬 ...

  3. FZU 2112 并查集、欧拉通路

    原题:http://acm.fzu.edu.cn/problem.php?pid=2112 首先是,票上没有提到的点是不需要去的. 然后我们先考虑这个图有几个连通分量,我们可以用一个并查集来维护,假设 ...

  4. 用Canvas写桌球游戏!!!

    声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢! 昨天上班的时候闲着无事,就用Canvas写了个桌球游戏来玩玩....所以就拿这游戏上来水一发.或许对一些刚学canvas的人有帮助. 话说 ...

  5. [BZOJ4408][Fjoi 2016]神秘数

    [BZOJ4408][Fjoi 2016]神秘数 试题描述 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13},1 = 12 = 1+13 = 1 ...

  6. 帝国CMS视频

    http://list.youku.com/albumlist/show?id=17602333&ascending=1.html

  7. Markdown入门

    http://www.jianshu.com/p/1e402922ee32/ 有道云笔记支持Markdown

  8. Unity3D NGUI动态生成模糊背景图

    先上效果. 制作原理:模糊的部分是用UITexture,前面是一个UISprite.用主摄像机渲染出一张纹理,把这张纹理模糊处理,把这张纹理赋值给UITexture. 脚本代码 using Unity ...

  9. iOS 多个异步网络请求全部返回后再执行具体逻辑的方法

    对于dispatch多个异步操作后的同步方法,以前只看过dispatch_group_async,看看这个方法的说明: * @discussion * Submits a block to a dis ...

  10. C#与Java多态方面的语法差异

    C++.C#.Java,无奈三种语言让我多次混淆,多次搞清楚,不写个Demo我想还是会忘记的. 就好像是一个满水的杯子,倒掉一点,才能装下更多. 有时候博客就是一个倒水的地方,可以让我们清空自己,然后 ...