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

  • 相关阅读:
    973. K Closest Points to Origin
    919. Complete Binary Tree Inserter
    993. Cousins in Binary Tree
    20. Valid Parentheses
    141. Linked List Cycle
    912. Sort an Array
    各种排序方法总结
    509. Fibonacci Number
    374. Guess Number Higher or Lower
    238. Product of Array Except Self java solutions
  • 原文地址:https://www.cnblogs.com/yang-fei/p/4706148.html
Copyright © 2011-2022 走看看