为什么使用附加属性

附加属性的一个用途是允许不同的子元素为父元素中定义的属性指定唯一的值。 此方案的一个具体应用是,让子元素通知父元素它们在用户界面 (UI) 中的呈现方式。 一个示例是 DockPanel.Dock 属性。 该 DockPanel.Dock 属性是作为附加属性创建的,因为它设计为在中包含的元素上设置,而不是在自身中包含的元素上设置 DockPanel DockPanel 。 DockPanel类定义 DependencyProperty 名为的静态字段 DockProperty ,然后提供 GetDock 和 SetDock 方法作为附加属性的公共访问器。

一、附加属性的特点

1、特殊的依赖属性
2、用于非定义该属性的类 例如Grid面板的RowDefinition、ColumnDefinition、Canvas面板的Left、Right,DockPanel面板的Dock都是附加属性。

二、附加属性的定义

1、声明数据属性变量。 public static 的DependencyProperty类型的变量。
2、在属性系统中进行注册,使用DependencyProperty.RegisterAttached()方法来注册,方法参数和注册依赖属性时Register()方法的参数一致。
3、调用静态方法设置和获取属性值。通过调用DependencyObject的SetValue()和GetValue()方法来设置和获取属性的值。两个方法应该命名为SetPropertyName()方法和GetPropertyName()方法。

三、示例(给页面上的Grid表格控件做特殊边框样式)

创建帮助类定义并注册附加属性:

using System.Windows;

using System.Windows.Controls;

using System.Windows.Media;

namespace Opacs.Client.Utilities

{

public static class GridHelper

{

public static bool GetShowBorder(DependencyObject obj)

{

return (bool)obj.GetValue(ShowBorderProperty);

}

public static void SetShowBorder(DependencyObject obj, bool value)

{

obj.SetValue(ShowBorderProperty, value);

}

public static readonly DependencyProperty ShowBorderProperty =

DependencyProperty.RegisterAttached("ShowBorder", typeof(bool), typeof(GridHelper), new PropertyMetadata(OnShowBorderChanged));

private static void OnShowBorderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

{

var grid = d as Grid;

if ((bool)e.OldValue)

{

grid.Initialized -= (s, arg) => { };

}

if ((bool)e.NewValue)

{

grid.Initialized += (s, arg) =>

{

var controls = grid.Children;

var count = controls.Count;

for (var i = 0; i < count; i++)

{

var item = controls[i] as FrameworkElement;

#region 单元格边框Thickness详细设计

var rowCount = grid.RowDefinitions.Count;

var columnCount = grid.ColumnDefinitions.Count;

var row = Grid.GetRow(item);

var column = Grid.GetColumn(item);

var rowspan = Grid.GetRowSpan(item);

var columnspan = Grid.GetColumnSpan(item);

var thicknessValue = 1;

var thickness = new Thickness(thicknessValue);

var thicknessColor = Colors.DarkGray;

var background = new SolidColorBrush(Colors.White);

if (row == 0)

{

background = new SolidColorBrush(Colors.LightGray);

}

if (row > 0 && row <= rowCount - 1)

{

thickness.Top = 0;

}

if (column > 0 && column <= columnCount - 1)

{

thickness.Left = 0;

}

item.BorderThicknessRemove(ref thickness);

#endregion

var border = new Border()

{

BorderBrush = new SolidColorBrush(thicknessColor),

BorderThickness = thickness,

Background = background

};

Grid.SetRow(border, row);

Grid.SetColumn(border, column);

Grid.SetRowSpan(border, rowspan);

Grid.SetColumnSpan(border, columnspan);

grid.Children.RemoveAt(i);

border.Child = item;

grid.Children.Insert(i, border);

}

};

}

}

public static void BorderThicknessRemove(this FrameworkElement item, ref Thickness thickness)

{

if (item.Tag != null)

{

if (item.Tag.Equals("LeftWideBorder"))

{

thickness.Left = 0;

}

if (item.Tag.Equals("RightWideBorder"))

{

thickness.Right = 0;

}

}

}

}

}

在xaml页面上使用附加属性:

<dxwui:NavigationPage

x:Class="Opacs.Client.Views.UserCheck.OptometryView"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:utilities="clr-namespace:Opacs.Client.Utilities">

<Grid

  HorizontalAlignment="Stretch"

  VerticalAlignment="Stretch"

  utilities:GridHelper.ShowBorder="True">    //功能是给grid表格添加自定义的边框

  <Grid.ColumnDefinitions>

    <ColumnDefinition Width="*" />

  </Grid.ColumnDefinitions>

  <Grid.RowDefinitions>

    <RowDefinition Height="Auto" />

  </Grid.RowDefinitions>

<TextBlock

  Grid.Row="0"

  Grid.Column="0"

  VerticalAlignment="Center"

  TextAlignment="Center"

  TextWrapping="Wrap" />

</Grid>

<dxwui:NavigationPage>

四、附加属性的另外一种用法:

定义附加属性类

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Input;

using System.Windows.Media;

namespace Demo3.Control

{

public class ControlAttachProperty

{

#region 圆角

public static CornerRadius GetCornerRadius(DependencyObject obj)

{

return (CornerRadius)obj.GetValue(CornerRadiusProperty);

}

public static void SetCornerRadius(DependencyObject obj, CornerRadius value)

{

obj.SetValue(CornerRadiusProperty, value);

}

public static readonly DependencyProperty CornerRadiusProperty =

DependencyProperty.RegisterAttached("CornerRadius", typeof(CornerRadius), typeof(ControlAttachProperty), new PropertyMetadata(null));

#endregion

}

}

在xaml页面使用它:

给自定义的附加属性赋值

<Window x:Class="Demo3.MainWindow"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:c="clr-namespace:Demo3.Control"

Background="Black"

Title="MainWindow"

WindowStartupLocation="CenterScreen"

Height="350"

Width="525">

<StackPanel>

<TextBox x:Name="UserName"

Width="230"

Height="38"

Margin="0,20,0,0"

FontSize="18"

VerticalContentAlignment="Center"

c:ControlAttachProperty.CornerRadius="5" />     //给自定义的附加属性赋值

Style="{StaticResource DefaultTextBox}"

</StackPanel>

</Window>

在style文件中进行使用

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:c="clr-namespace:Demo3.Control"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<ResourceDictionary.MergedDictionaries>

<ResourceDictionary Source="/Demo3;component/Resources/Style/DeleteButton.xaml" />

</ResourceDictionary.MergedDictionaries>

<!--TextBox默认样式-->

<Style x:Key="DefaultTextBox" TargetType="{x:Type TextBox}">

<Setter Property="ContextMenu" Value="{DynamicResource TextBoxContextMenu}" />

<Setter Property="VerticalContentAlignment" Value="Center" />

<Setter Property="SnapsToDevicePixels" Value="True" />

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="{x:Type TextBox}">

<Border x:Name="Bg"

SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"

CornerRadius="{TemplateBinding c:ControlAttachProperty.CornerRadius}"    //这里的Border控件的CornerRadius属性的值=(TemplateBinding)父级的c:ControlAttachProperty.CornerRadius附加属性的值=5

Background="White"

BorderBrush="Transparent"

BorderThickness="0">

</Border>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

</ResourceDictionary>

wpf附加属性详解的更多相关文章

  1. WPF DrawingVisual详解

    在WPF中,如果需要绘制大量图形元素,并且对性能要求严苛的话,最好使用DrawingVisual,当然,你也可以选用 Path类和比Path类更轻量级的Geometry(几何形状)来实现你的需求,但是 ...

  2. WPF数据绑定详解

    元素绑定 数据绑定最简单的形式是,源对象是WPF元素而且源属性是依赖属性.依赖项属性具有内置的更改通知支持,当在源对象中改变依赖项属性的值时,会立即更新目标对相中的绑定属性. <!--Xaml程 ...

  3. WPFの触发器详解

    例子1 简单触发器Triggers——满足简答的条件,触发 <Window x:Class="Styles.SimpleTriggers" xmlns="http: ...

  4. wpf 客户端【JDAgent桌面助手】开发详解(三) 瀑布流效果实现与UI虚拟化优化大数据显示

    目录区域: 业余开发的wpf 客户端终于完工了..晒晒截图 wpf 客户端[JDAgent桌面助手]开发详解-开篇 wpf 客户端[JDAgent桌面助手]详解(一)主窗口 圆形菜单... wpf 客 ...

  5. wpf 客户端【JDAgent桌面助手】开发详解(二)桌面宠物制作详解

    目录区域: wpf 客户端[JDAgent桌面助手]业余开发的终于完工了..晒晒截 wpf 客户端[JDAgent桌面助手]开发详解-开篇 wpf 客户端[JDAgent桌面助手]开发详解(一)主窗口 ...

  6. WPF依赖属性详解

    WPF依赖属性详解 WPF 依赖属性 英文译为 Dependency Properties,是WPF引入的一种新类型的属性,在WPF中有着极为广泛的应用,在WPF中对于WPF Dependency P ...

  7. wpf 客户端【JDAgent桌面助手】开发详解(四) popup控件的win8.0的bug

    目录区域: 业余开发的wpf 客户端终于完工了..晒晒截图 wpf 客户端[JDAgent桌面助手]开发详解-开篇 wpf 客户端[JDAgent桌面助手]详解(一)主窗口 圆形菜单... wpf 客 ...

  8. wpf中的触发器详解 (转自 乂乂的日志 - 网易博客)

    2010-03-24 16:19:07|  分类: WPF相关 |  标签: |字号大中小 订阅     wpf中的触发器详解 WPF/C# 2009-08-24 11:32:50 7.1.2  简单 ...

  9. wpf 客户端【JDAgent桌面助手】开发详解-开篇

    上周二 发表了一个帖子:wpf 客户端[JDAgent桌面助手]业余开发的终于完工了..晒晒截图... 没有想到不到一个周时间已经浏览量过8千,估计过几天就过万了..很开心啊.. 评论中好多网友问我要 ...

随机推荐

  1. Python自动化运维 技术与最佳实践PDF高清完整版免费下载|百度云盘|Python基础教程免费电子书

    点击获取提取码:7bl4 一.内容简介 <python自动化运维:技术与最佳实践>一书在中国运维领域将有"划时代"的重要意义:一方面,这是国内第一本从纵.深和实践角度探 ...

  2. 【SDOI2010】猪国杀 题解(模拟)

    前言:嗅到了一丝头秃的味道…… ------------------ 题目链接 题目实在太长,变量也很多.建议至少读个三五遍再做题.不要忽略任何细节,不要想当然.(因为真正玩三国杀肯定不像猪一样出牌啊 ...

  3. 使用MPI进行分布式内存编程(2)

    MPI的英文全称为message passing interface,中文名为消息传递接口,他不是一种新的语言,而是一个可以被C,C++,Fortran程序调用的库. 预备知识 1.编译与执行 使用类 ...

  4. python3.2求和与最值

    #1到100求和sum1=0for x in range(101): sum1=sum1+xprint(sum1) #1到100偶数求和sum2=0for x in range(0,101,2): p ...

  5. 微信小程序后台springboot+mybatis+mysql“采坑”集锦

    "采坑"错误集锦 1.service层 错误描述:2019-04-14 22:09:52.027 ERROR 8416 --- [nio-8082-exec-5] o.a.c.c. ...

  6. 测试面试题集锦(四)| Linux 与 Python 编程篇(附答案)

    本文为霍格沃兹测试学院学员学习笔记. 本系列文章总结归纳了一些软件测试工程师常见的面试题,主要来源于个人面试遇到的.网络搜集(完善).工作日常讨论等,分为以下十个部分,供大家参考.如有错误的地方,欢迎 ...

  7. CPU:别再拿我当搬砖工了!

    数据搬运工 Hi,我是CPU一号车间的阿Q,有段日子没见面了. 还记得上回说到咱们厂里用上了DMA技术(太慢不能忍!CPU又拿硬盘和网卡开刀了!)之后,我们总算解放了,再也不用奔波于网卡.硬盘与内存之 ...

  8. jquary常见问题总结

    如何调用本地json 1. 调用 <script src="solution.json?cb=readData"></script> 2. json 修改 ...

  9. 题解 P1407

    建图方式:旧关系女人连男人,现关系男人连女人(当然,反过来也可以) 原因可以这样考虑: 如果一个男的把女的绿了,那么这个女人就会去找一个她曾经交往过的男人,也就是在这种情况下,某种"影响&q ...

  10. 阿里云体验实验室 教你如何《快速搭建LNMP环境》

    ## 体验平台简介 面向开发者和中小企业打造的一站式.全云端的开发平台,打开浏览器就可以开发.调试.上线,所测即所得,并结合无服务器的模式,重新定义云原生时代的研发工作方法论.旨在降低开发者上手成本和 ...