为什么使用附加属性

附加属性的一个用途是允许不同的子元素为父元素中定义的属性指定唯一的值。 此方案的一个具体应用是,让子元素通知父元素它们在用户界面 (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. 题解 Luogu P1514 【引水入城】

    有一种神奇的算法叫做floodfill 就是一个n*m的矩阵,a[i][j]为当前高度,我们可以任选一个点倒水,开始bfs,如果要搜的点没有被搜到过,并且高度小于当前的点,我们就把这个点加入队列中 而 ...

  2. C++ 中可调用的且有函数功能的东东

    第一个:函数     其实函数在声明的时候都有个名字: 这个名字可以看作是是指针,将其直接赋值给函数指针 也可以看作是可取指的对其& 再赋值给函数指针 第二个:函数指针   通过其被赋值的方式 ...

  3. TearmQuery()

    lucene 中的  TearmQuery() 在.search( tearmQuery, q)查询时 比较矫情 q只能是小写

  4. api接口返回动态的json格式?我太难了,尝试一下 linq to json

    一:背景 1. 讲故事 前段时间和一家公司联调api接口的时候,发现一个奇葩的问题,它的api返回的json会动态改变,简化如下: {"Code":101,"Items& ...

  5. 002_go语言的值类型

    代码演示: package main import "fmt" func main() { fmt.Println("go"+"lang") ...

  6. linux系统中SSH免密设置报错

    执行 ssh-add ~/.ssh/msi_rsa 时报下面错误 Could not open a connection to your authentication agent. 解决办法: 执行命 ...

  7. Vue中diff算法的理解

    Vue中diff算法的理解 diff算法用来计算出Virtual DOM中改变的部分,然后针对该部分进行DOM操作,而不用重新渲染整个页面,渲染整个DOM结构的过程中开销是很大的,需要浏览器对DOM结 ...

  8. C# ASP 异步存储数据

    1.异步委托 在导航栏接收到提交的请求后,调用个各子画面的保存答案方法,之后实例化委托 saveToDB . 当执行BeginInvoke后,服务器会另起线程执行saveToDB里的的方法,因为这里要 ...

  9. CVE-2020-14644 weblogic iiop反序列化漏洞

    0x00 weblogic 受影响版本 Oracle WebLogic Server 12.2.1.3.0, 12.2.1.4.0, 14.1.1.0.0 0x01 环境准备 1.安装weblogic ...

  10. super与this的区别,更进一步的区别!——Java学习

    文章目录 this与super的含义 前言 例证 this super 总结 this与super的含义 在Java中,this有两层含义: 指示隐式参数的引用(就是当前对象的引用) 调用该类的其他构 ...