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

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(, new Duration(TimeSpan.FromMilliseconds()))
{
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()))
{
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

WPF知识点全攻略09- 附加属性的更多相关文章

  1. WPF知识点全攻略00- 目录

    知识点目录如下: 1.WPF相对WinFrom的优缺点 2.WPF体系结构 3.XAML 4.XAML页面布局 5.XAML内容控件 6.WPF中的“树” 7.Binding 8.依赖属性 9.附加属 ...

  2. WPF知识点全攻略10- 路由事件

    路由事件是WPF不得不提,不得不会系列又一 先来看一下他的定义: 功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件. 实现定义:路由事件是一个 C ...

  3. WPF知识点全攻略08- 依赖属性

    依赖属性是WPF不得不提,不得不会系列又一 先来看一下,自定义依赖属性的写法 public static readonly DependencyProperty IconProperty = Depe ...

  4. WPF知识点全攻略07- 数据绑定(Binding)

    数据绑定是WPF不得不提,不得不会系列之一 数据绑定简言之,就是把数据源的数据绑定到目标对象的属性上.目标对象可以是承自DependencyProperty的任何可访问的属性或控件,目标属性必须为依赖 ...

  5. WPF知识点全攻略06- WPF逻辑树(Logical Tree)和可视树(Visual Tree)

    介绍概念之前,先来分析一段代码: xaml代码如下: <Window x:Class="WpfApp1.MainWindow" xmlns="http://sche ...

  6. WPF知识点全攻略05- XAML内容控件

    此处简单列举出布局控件外,其他常用的控件: Window:WPF窗口 UserControl:用户控件 Page:页 Frame:用来浏览Page页 Border:嵌套控件,提供边框和背景. Butt ...

  7. WPF知识点全攻略04- XAML页面布局

    名称 说明 Canvas 使用固定坐标绝对定位元素 StackPanel 在水平或竖直方向放置元素 DockPanel 根据外部容器边界,自动调整元素 WrapPanel 在可换行的行中放置元素 Gr ...

  8. WPF知识点全攻略03- XAML

    XAML 是一种声明性标记语言,XAML 是一种基于 XML 并对 XML 结构规则进行了扩展. XAML特点: 定义应用程序的界面元素 显示的声明WPF资源(样式.模板.动画等) 可扩展性(自定义U ...

  9. WPF知识点全攻略02- WPF体系结构

    WPF体系结构图: PersentationFramework.dll包含WPF顶层的类型,包括哪些表示窗口.面板以及其他类型控件的类型.他还实现了高层编程抽象,如样式.开发人员直接使用的大部分类都来 ...

随机推荐

  1. ZOJ3321,ZOJ3317

    ZOJ3321 //there is at most one edge between two nodes. 因为这句话的局限性,又要满足环,那么一定是每个点度为2,然后为n节点的一个环 //#inc ...

  2. Codeforces 67A【模拟】

    题意: 给一个字符串代表相邻学生的比较,L代表左边多,R表示右边多,=表示左右相等. 保证每个人拿糖>=1,在分糖最少的情况下,输出每个学生所分得的糖. 思路: 模拟一下,第一个人一开始拿1个, ...

  3. opencv学习资料

    搜集一些基础书 数字图像处理 信号与系统 计算机视觉中的多视图几何 图像处理.分析与机器视觉 基于序列图像的视觉检测理论与方法 官网(各版本api) http://opencv.org/ opencv ...

  4. TFS 无法找到新加的Windows用户

    Windows 用户加入后,无法在TFS中的"浏览"中找到(只有已经加入TFS的Windows用户显示出来) 其实这时候只要直接输入 用户名 然后点击"保存更改" ...

  5. 洛谷P2505 [HAOI2012]道路(最短路计数)

    传送门 早上模拟赛考这题,结果竟然看错题目了orz 然后下午看完题解自己做的时候空间开小了白WA了好久orz 首先,如果以$S$为起点,一条边$(u,v)$在最短路上,则$dis[u]+edge[i] ...

  6. Matlab图像处理相关

    相关函数: 读取:imread() %参数为文件名(路径)或url,格式等 写入:imwrite() %参数为写入数据矩阵,写入文件名(路径),格式等 显示:imshow() %显示由输入决定,属性自 ...

  7. day04 Calendar类

  8. djangoForm组件

    https://www.cnblogs.com/jabbok/p/9273786.html 在之前学习了html form信息传递到django,然后进行处理,但是这很不方便. django有自己的组 ...

  9. 洛谷1072(gcd的运用)

    已知正整数a0,a1,b0,b1,设某未知正整数x满足: 1. x 和 a0 的最大公约数是 a1​: 2. x 和 b0​ 的最小公倍数是b1. Hankson 的“逆问题”就是求出满足条件的正整数 ...

  10. HTML实例之简单的网页布局

    需求: <html> <head> <title>简单的表格网页布局</title> <meta charset="UTF-8" ...