为什么使用附加属性

附加属性的一个用途是允许不同的子元素为父元素中定义的属性指定唯一的值。 此方案的一个具体应用是,让子元素通知父元素它们在用户界面 (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. Typora + PicGo-Core + Custom Command 实现上传图片到图床

    教程参考 Typora+PicGo-Core(command line)+Gitee实现图片上传到图床 主要借鉴 picgo 操作命令 Typora + PicGo + Gitee 实现图片自动上传到 ...

  2. 【问题记录】springMVC @Valid使用不生效问题

    问题描述 在网上找到如何使用@Valid注解后,就把用到的配置和jar包加上,然后测试发现一直不生效.下面是配置及解决方法 配置 1.引入依赖 2.添加相应的配置(springmvc配置文件) < ...

  3. UI自动化填写问卷(selenium)+定时任务(懒人必备)

    1.自动填报 UI自动化 selenium 开发程序动机:天天有人催着填写问卷,弄的头大.主要还是懒的每天一个个去填写内容. 开发总时长:2个小时:学习+开发+修改 遇到的小问题: 在自动化填写地图的 ...

  4. 如何利用NLog输出结构化日志,并在Kibana优雅分析日志?

    上文我们演示了使用NLog向ElasticSearch写日志的基本过程(输出的是普通文本日志),今天我们来看下如何向ES输出结构化日志.并利用Kibana中分析日志. NLog输出结构化日志 Elas ...

  5. Unity 入门

  6. Python3 连接 Oracle 数据库

    Python3 连接 Oracle 数据库 需要导出一些稍微复杂的数据,用Python处理很方便 环境 Win10 Python 3.7.0 Oracle 11g 安装依赖 安装 cx_Oracle ...

  7. Markdown上手

    Markdown 学习日记 标题 二级标题 两个#+空格 快捷键:Ctrl + 2 三级标题 三个#+空格 快捷键:Ctrl + 3 最多支持六级标题 字体 加粗 文字 两个 *+文字+两个 * 快捷 ...

  8. Java入门到实践系列(2)——Java环境搭建

    一.上集回顾 在<Java入门到实践系列(1)--Java简介>中提到过,Java程序是运行在Java虚拟机的,也展示过下面这张图. JDK:Java程序开发工具包. JRE:Java运行 ...

  9. 文章要保存为TXT文件,其中的图片要怎么办?Python帮你解决

    前言 用 python 爬取你喜欢的 CSDN 的原创文章,保存为TXT文件,不仅查看不方便,而且还无法保存文章中的代码和图片. 今天教你制作成 PDF 慢慢看.万一作者的突然把号给删了,也会保存备份 ...

  10. C#设计模式之1-工厂方法模式

    工厂方法模式(Factory Method Pattern) 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/389 访问 ...