发文章
发文工具
撰写
网文摘手
文档
视频
思维导图
随笔
相册
原创同步助手
其他工具
图片转文字
文件清理
AI助手
留言交流
附加属性,大家都不陌生,最常见的是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); } } } }
来自: 昵称10504424 > 《工作》
0条评论
发表
请遵守用户 评论公约
WPF依赖属性详解
WPF依赖属性详解前言。属性和依赖属性。--在Grid当中,具备Row/Column附加属性--> <Button Grid.Row='''''...
DataGrid控件自动显示行号
在项目中碰到了这个问题,在网上搜了半天,发现了一种解决方案,这种方法主要是在DataGrid加载Row时设定Row的行号,主要代码如下:5 private static void OnShowRowIndexPropertyChanged(DependencyObj...
[WPF]实现密码框的密码绑定
public static void SetIsPasswordBindingEnabled(DependencyObject obj, bool value) { obj.//when the buffer changed, upate the passwordBox''s password privat...
Silverlight快速开发框架RapidSL新特性
Silverlight快速开发框架RapidSL新特性。RapidSL.SL.App.Portal提供主框架的UI逻辑,只需要开发自己的App,如RapidSL.SL.App.Main.var x...
附加属性
附加属性。虽然代码清单3-5中的XAML很好地把FontSize和FontStyle作为StackPanel的逻辑附加属性,但是C#代码告诉我们这里并没有什么神奇...
HTML5常用的标签
var canvas = document.getElementById(''mycanvas'');var ctx = canvas.getContext(''2d'');var obj = document.getElementById(''mycanvas'');var ...
4、HTML5 新 增 元 素
DOCTYPE html><html><head lang="en"> <meta charset="UTF-8"> <title>HTML5新增属性&...
一行 Object.keys() 引发的血案
当常规属性的数量少于对象初始化时的属性数量时,常规属性会直接作为对象内属性存放。对象属性列表是通过。快属性虽然访问很快,但是如...
jquery的对象数组的添加元素,删除元素
jquery的对象数组的添加元素,删除元素jquery对象数组。其中jQuery.inArray(''b'',arrList)是b这个元素在数组arrList 中的位置 splice(index,1)函数中第一个参数index是要删除元素在数...
微信扫码,在手机上查看选中内容