附加属性

附加属性,大家都不陌生,最常见的是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. ReactiveCocoa源码拆分解析(二)

    (整个关于ReactiveCocoa的代码工程可以在https://github.com/qianhongqiang/QHQReactive下载) 上面抽丝剥茧的把最主要的信号机制给分离开了.但在RA ...

  2. 1.1ASP.NET Web API 2入门

    HTTP 不只是为了生成 web 页面.它也是建立公开服务和数据的 Api 的强大平台.HTTP 是简单的. 灵活的和无处不在.你能想到的几乎任何平台有 HTTP 库,因此,HTTP 服务可以达到范围 ...

  3. 计算 TP90TP99TP...

    what-do-we-mean-by-top-percentile-or-tp-based-latency tp90 is a minimum time under which 90% of requ ...

  4. Extjs 制作柱状图

    在JSP页面制作柱状图,可以根据数据的变化动态实时的变化 主要是使用EXTJS自带的插件达到效果 Ext.require('Ext.chart.*'); Ext.require([ 'Ext.Wind ...

  5. php文件类

    1.需求 了解php对文件的一些操作 2.例子 写了一个类,可以操作文件,包含增,删,查 <?php class myfile{ public function write_file($stri ...

  6. C#高级编程笔记 Day 5, 2016年9月 13日 (泛型)

    [重点]泛型:有了泛型,就可以创建独立于被包含类型的类和方法了.我们不必给不同的类型编写功能相同的许多方法和类,只创建一个方法或类即可,以下是泛型的特点:性能.类型安全性.二进制代码重用.代码的扩展. ...

  7. Python简单源码解析

    主要为一些简单的源代码的解析以及一些方法的理解. 说明:这些文件都不是我写的,详情可参考Github上的内容. 批量修改文件类型 def batch_rename(work_dir, old_ext, ...

  8. 转:浅谈UNIX下Apache的MPM及httpd.conf配置文件中相关参数配置

    为什么要并发处理 以Apache为代表的web服务器中,如果不支持并发,则在一个客户端连接的时候,如果该客户端的任务没有处理完,其他连接的客户端将会一直处于等待状态,这事不可想象的,好像没有为什么要不 ...

  9. celery 异步任务小记

    这里有一篇写的不错的:http://www.jianshu.com/p/1840035cb510 自己的"格式化"后的内容备忘下: 我们总在说c10k的问题, 也做了不少优化, 然 ...

  10. 【转】Java读取matlab的.mat数据文件

    参考:Java读取mat文件 下载链接:ujmp  jmatio 下载完两个.jar文件之后,如何引用到java项目当中?项目名称->右键->Property->Java Build ...