zoukankan      html  css  js  c++  java
  • WPF知识点全攻略09- 附加属性

    附加属性也是一种特殊的依赖属性。

    Canvas中的Canvas.Left,Canvas.Top ,DockPanel中DockPanel.Dock等就是附加属性。

    更加.NET类属性的写法经验。这个中可以直接点出来的,都是不用实例化的静态的。以Top属性为例:

    public static readonly DependencyProperty TopProperty =
        DependencyProperty.RegisterAttached("Top", 
        typeof(double), typeof(Canvas),
        new FrameworkPropertyMetadata(0d,
            FrameworkPropertyMetadataOptions.Inherits));
     
    public static void SetTop(UIElement element, double value)
    {
        element.SetValue(TopProperty, value);
    }
     
    public static double GetTop(UIElement element)
    {
        return (double)element.GetValue(TopProperty);
    }

     看如下代码效果:

    <Canvas Background="#AAAAAA" Height="150" Width="200">
        <Rectangle Canvas.Left="50" Canvas.Top="50" Width="50" Height="50" Fill="Red" />
    </Canvas>

    代码中可以看到, Convas.Left附加属性实际作用在 Rectangle在Canvas中的Left属性上,Convas.Top附加属性实际作用在 Rectangle在Canvas中的Top属性上。

    再来看一个例子:

    <Grid>
        <Grid.Clip>
            <EllipseGeometry Center="400 200" RadiusX="160" RadiusY="200" />
        </Grid.Clip>
        <Image Source="ping.jpg" Stretch="Fill" />
    </Grid>

    通过Grid的附加属性Clip我们截取到了想要的图片效果。

     那么什么时候去使用附加属性呢?下面是WPF经典Material Design主题开源项目Material Design In XAML Toolkit中对于阴影部分处理的源码。

    public static class ShadowAssist
        {
            public static readonly DependencyProperty ShadowDepthProperty = DependencyProperty.RegisterAttached(
                "ShadowDepth", typeof (ShadowDepth), typeof (ShadowAssist), new FrameworkPropertyMetadata(default(ShadowDepth), FrameworkPropertyMetadataOptions.AffectsRender));
    
            public static void SetShadowDepth(DependencyObject element, ShadowDepth value)
            {
                element.SetValue(ShadowDepthProperty, value);
            }
    
            public static ShadowDepth GetShadowDepth(DependencyObject element)
            {
                return (ShadowDepth) element.GetValue(ShadowDepthProperty);
            }
    
            private static readonly DependencyPropertyKey LocalInfoPropertyKey = DependencyProperty.RegisterAttachedReadOnly(
                "LocalInfo", typeof (ShadowLocalInfo), typeof (ShadowAssist), new PropertyMetadata(default(ShadowLocalInfo)));
    
            private static void SetLocalInfo(DependencyObject element, ShadowLocalInfo value)
            {
                element.SetValue(LocalInfoPropertyKey, value);
            }
    
            private static ShadowLocalInfo GetLocalInfo(DependencyObject element)
            {
                return (ShadowLocalInfo) element.GetValue(LocalInfoPropertyKey.DependencyProperty);
            }
    
            public static readonly DependencyProperty DarkenProperty = DependencyProperty.RegisterAttached(
                "Darken", typeof (bool), typeof (ShadowAssist), new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.AffectsRender, DarkenPropertyChangedCallback));
    
            private static void DarkenPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
            {
                var uiElement = dependencyObject as UIElement;
                var dropShadowEffect = uiElement?.Effect as DropShadowEffect;
    
                if (dropShadowEffect == null) return;
    
                if ((bool) dependencyPropertyChangedEventArgs.NewValue)
                {
                    SetLocalInfo(dependencyObject, new ShadowLocalInfo(dropShadowEffect.Opacity));
    
                    var doubleAnimation = new DoubleAnimation(1, new Duration(TimeSpan.FromMilliseconds(350)))
                    {
                        FillBehavior = FillBehavior.HoldEnd
                    };
                    dropShadowEffect.BeginAnimation(DropShadowEffect.OpacityProperty, doubleAnimation);                
                }
                else
                {
                    var shadowLocalInfo = GetLocalInfo(dependencyObject);
                    if (shadowLocalInfo == null) return;
    
                    var doubleAnimation = new DoubleAnimation(shadowLocalInfo.StandardOpacity, new Duration(TimeSpan.FromMilliseconds(350)))
                    {
                        FillBehavior = FillBehavior.HoldEnd
                    };
                    dropShadowEffect.BeginAnimation(DropShadowEffect.OpacityProperty, doubleAnimation);
                }
            }
    
            public static void SetDarken(DependencyObject element, bool value)
            {
                element.SetValue(DarkenProperty, value);
            }
    
            public static bool GetDarken(DependencyObject element)
            {
                return (bool) element.GetValue(DarkenProperty);
            }
    
            public static readonly DependencyProperty CacheModeProperty = DependencyProperty.RegisterAttached(
                "CacheMode", typeof(CacheMode), typeof(ShadowAssist), new FrameworkPropertyMetadata(new BitmapCache { EnableClearType = true, SnapsToDevicePixels = true }, FrameworkPropertyMetadataOptions.Inherits));
    
            public static void SetCacheMode(DependencyObject element, CacheMode value)
            {
                element.SetValue(CacheModeProperty, value);
            }
    
            public static CacheMode GetCacheMode(DependencyObject element)
            {
                return (CacheMode)element.GetValue(CacheModeProperty);
            }
    
            public static readonly DependencyProperty ShadowEdgesProperty = DependencyProperty.RegisterAttached(
                "ShadowEdges", typeof(ShadowEdges), typeof(ShadowAssist), new PropertyMetadata(ShadowEdges.All));
    
            public static void SetShadowEdges(DependencyObject element, ShadowEdges value)
            {
                element.SetValue(ShadowEdgesProperty, value);
            }
    
            public static ShadowEdges GetShadowEdges(DependencyObject element)
            {
                return (ShadowEdges) element.GetValue(ShadowEdgesProperty);
            }
        }
    <Setter Property="wpf:ShadowAssist.ShadowDepth" Value="Depth1" />

    谷歌提出的“材料设计” 理念中,阴影是比较重要的一部分,而该项目就是使用了附加属性来达到了效果。其中还有不少特性也是通过附加属性来完成的,给我如何使用附加属性,提供了比较好的模板。

    可以参考学习:https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit

  • 相关阅读:
    【leetcode】修剪二叉搜索树
    053-621
    053-620
    053-619
    053-618
    053-617
    053-616
    053-615
    053-614
    053-613
  • 原文地址:https://www.cnblogs.com/kuangxiangnice/p/11071843.html
Copyright © 2011-2022 走看看