为什么使用附加属性

附加属性的一个用途是允许不同的子元素为父元素中定义的属性指定唯一的值。 此方案的一个具体应用是,让子元素通知父元素它们在用户界面 (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. JsLint undeclared ‘window’

    如果使用IDEA 设置一下 globals 或 /*global window */ ... your script goes here https://stackoverflow.com/quest ...

  2. MySQL--->存储引擎及图形化工具

    本章目标: 掌握MySQL存储引擎的特点 掌握Navicat图形化工具的使用 了解其他的一些图形化管理工具 1.存储引擎种类: 2. 表级锁和行级锁: 3.常见的引擎: InnoDB 存储引擎 MyI ...

  3. 计算vtable的大小

    在ClassFileParser::parseClassFile()函数中会计算vtable和itable所需要的大小,因为vtable和itable是内嵌在Klass中的,parseClassFil ...

  4. 2020-07-13:es是去查id再根据id去查数据库这种方式好,还是所有数据都放es,直接去查es好?

    福哥答案2020-07-13: 有人觉得第一种方法好,也有人觉得第二种方法好.如果搜索字段远小于显示字段,比如搜索字段为3个,显示字段有20个,这个时候用第一种方法好.es+hbase,一般这样搭配. ...

  5. MongoDB学习1:认识文档数据库MongoDB

    1. 关于MongoDB 什么是MongoDB 一个以JSON为数据模型的文档数据库 为什么叫文档数据库 文档来自于"JSON Document",并非我们一般理解的pdf,wor ...

  6. Java indexof

    java中字符串方法 indexof() indexof()可以返回输入的字符串在目标字符串中第一次出现的位置,如果没有出现返回int 0:

  7. 搭建Elasticsearch Logstash Kibana 日志系统

    分布式系统下由于日志文件分布在不同的系统上,分析比较麻烦,通过搭建elk日志系统,可快速排查日志信息. Elasticsearch是大数据处理框架,使用的分布式存储,可存储海量数据:基于Lucense ...

  8. 攻防世界-web(进阶)-NaNNaNNaNNaN-Batman

    用winhex打开,发现是一个javascript代码.将文件重命名为html文件,用浏览器打开. 打开是一个输入框,输入任何东西都梅反应,尝试弹框输入也无果,继续查看代码. 查看代码,可以看到最开始 ...

  9. unity探索者之支付宝支付,非第三方插件

    版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/8405044.html 支付宝的sdk接入方式和微信支付比较类似,大部分的工作也基本 ...

  10. 痞子衡嵌入式:解锁i.MXRTxxx上FlexSPI模块自带的地址重映射(Remap)功能

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT三位数系列隐藏的FlexSPI Remap功能. 前段时间痞子衡写了一篇文章 <利用i.MXRT1060,1010上新 ...