zoukankan      html  css  js  c++  java
  • WPF QuickStart系列之附加属性(Attached Property)

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

    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, 100);
       Canvas.SetTop(_rect, 50);

    显示效果:

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

    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属性不是依赖属性,此时使用自定义附加属性解决了这个问题。示例代码下载

  • 相关阅读:
    k8s 节点的 NodeAffinity 使用
    template 与 host , item trigger的关系
    mysql 性能优化思路
    nginx 配sorry page
    修改tomcat JVM 大小 jdk--目录修改
    (转)MySQL慢查询分析优化 + MySQL调优
    注册表操作 Microsoft.Win32.Registry与RegistryKey类
    C#(99):WCF之.NET Remoting通讯
    CallContext线程数据缓存-调用上下文
    C#(99):JSON与对象的序列化与反序列化
  • 原文地址:https://www.cnblogs.com/wangchaoyuana/p/7523566.html
Copyright © 2011-2022 走看看