无废话WPF系列12: 依赖属性和附加属性

简介:

一、依赖属性

依赖属性就是自己自己没有值,通过Binding从数据源获得值,就是依赖在别人身上,拥有依赖属性的对象称为依赖对象。

几种应用依赖属性的场景:

1. 希望可在样式中设置属性。

2. 希望属性支持数据绑定。

3. 希望可使用动态资源引用设置属性。

4. 希望从元素树中的父元素自动继承属性值。

5. 希望属性可进行动画处理。

6. 希望属性系统在属性系统、环境或用户执行的操作或者读取并使用样式更改了属性以前的值时报告。

7. 希望使用已建立的、WPF 进程也使用的元数据约定,例如报告更改属性值时是否要求布局系统重新编写元素的可视化对象。

依赖对象创建时并不包含存储数据空间。WPF中必须使用依赖对象作为依赖属性的宿主。

 

声明和使用依赖属性

提示:创建依赖属性时可以使用代码片段propdp

XAML

 

1
2
3
4
5
6
7
8
9
10
11
12
13
< Window  x:Class="DeepXAML.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:DeepXAML"      
         xmlns:sys="clr-namespace:System;assembly=mscorlib"
         Title="MainWindow" Height="250" Width="450">
     < StackPanel  x:Name="stackPanel">
         < TextBox  x:Name="textBox1" Margin="10"  Text="{Binding Path=Title}"></ TextBox >
         < TextBox  x:Name="textBox2" Margin="10" Text="{Binding Path=Title}"></ TextBox >
     </ StackPanel >
</ Window >
 
后台代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using  System;
using  System.Collections.Generic;
using  System.Windows;
using  System.Windows.Data;
using  System.Windows.Documents;
 
namespace  DeepXAML
{
     public  partial  class  MainWindow : Window
     {
         public  MainWindow()
         {
             InitializeComponent();
             Game game = new  Game { Title = "WarCraft"  };
             this .stackPanel.DataContext = game;
         }
     }
 
     public  class  Game:DependencyObject
     {
         public  string  Title
         {
             get  { return  ( string )GetValue(NameProperty); }
             set  { SetValue(NameProperty, value); }
         }
         // Using a DependencyProperty as the backing store for Name.  This enables animation, styling, binding, etc...
         public  static  readonly  DependencyProperty NameProperty =
             DependencyProperty.Register( "Title" , typeof ( string ), typeof (Game));       
    
}

DependencyProperty.Register方法解释

a.第一个参数指明以哪个CLR属性作为依赖属性的包装

b. 第二参数指明依赖属性存期什么类型的值

c. 此依赖属性宿主的类型。

依赖属性的值存在哪里?

在WPF运行时,维护了一个全局的Hashtable存取依赖属性的值。

 

二、附加属性

附加属性就是自己没有这个属性,在某些上下文中需要就被附加上去。比如TextBox的Grid.Row属性,如果我们定义TextBox类时定义一个Row属性是没有意义的,因为我们并不知道一定会放在Grid里,这样就造成了浪费。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
< Window  x:Class="DeepXAML.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:DeepXAML"      
         xmlns:sys="clr-namespace:System;assembly=mscorlib"
         Title="MainWindow" Height="250" Width="450">
     < Grid >
         < Grid.RowDefinitions >
             < RowDefinition  Height="2*"></ RowDefinition >
             < RowDefinition ></ RowDefinition >
         </ Grid.RowDefinitions >
         < TextBox  Grid.Row="0"></ TextBox >
         < TextBox  Grid.Row="1"></ TextBox >
     </ Grid >
</ Window >

实际上在编译后,Grid.Row会在Grid的类里生成SetRow方法,Grid来调整控件的控制。也就是附加属性会生成方法,不会占用内存空间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class GameAP : DependencyObject
{
     public static int GetName(DependencyObject obj)
     {
         return (int)obj.GetValue(NameProperty);
     }
 
     public static void SetName(DependencyObject obj, int value)
     {
         obj.SetValue(NameProperty, value);
     }
 
     // Using a DependencyProperty as the backing store for Name.  This enables animation, styling, binding, etc...
     public static readonly DependencyProperty NameProperty =
         DependencyProperty.RegisterAttached("Name", typeof(int), typeof(GameAP), new UIPropertyMetadata(0));
     
}
1
  
本文转自敏捷的水博客园博客,原文链接http://www.cnblogs.com/cnblogsfans/archive/2011/02/27/1966165.html如需转载请自行联系原作者

王德水
相关文章
|
9月前
|
C#
2000条你应知的WPF小姿势 基础篇<57-62 依赖属性进阶>
2000条你应知的WPF小姿势 基础篇<57-62 依赖属性进阶>
26 0
|
9月前
|
存储 开发框架 .NET
2000条你应知的WPF小姿势 基础篇<51-56 依赖属性>
2000条你应知的WPF小姿势 基础篇<51-56 依赖属性>
29 0
|
12月前
|
C#
WPF属性---重复样式和触发器
WPF属性---重复样式和触发器
88 0
|
前端开发 C# 图形学
【WPF】WPF开发用户控件、用户控件属性依赖DependencyProperty实现双向绑定、以及自定义实现Command双向绑定功能演示
Wpf开发过程中,最经常使用的功能之一,就是用户控件(UserControl)了。用户控件可以用于开发用户自己的控件进行使用,甚至可以用于打造一套属于自己的UI框架。依赖属性(DependencyProperty)是为用户控件提供可支持双向绑定的必备技巧之一,同样用处也非常广泛。
834 0
【WPF】WPF开发用户控件、用户控件属性依赖DependencyProperty实现双向绑定、以及自定义实现Command双向绑定功能演示
WPF项目中不支持 ResizingPanel,未在类型“ResizingPanel”中找到可附加的属性“ResizeWidth”
WPF项目中不支持 ResizingPanel,未在类型“ResizingPanel”中找到可附加的属性“ResizeWidth”
|
C# 容器 .NET
WPF属性(二)附加属性
原文:WPF属性(二)附加属性 附加属性是说一个属性本来不属于某个对象,但由于某种需求而被后来附加上,也就是把对象放入一个特定环境后对象才具有的属性就称为附加属性,附加属性的作用就是将属性与数据类型解耦,让数据类型的...
815 0
|
C# .NET 开发框架
WPF属性(一)依赖属性
原文:WPF属性(一)依赖属性 依赖属性是一种可以自己没有值,并能通过使用Binding从数据源获得值的属性,拥有依赖属性的对象称为依赖对象,在传统开发中,一个对象所占用的内存在调用new操作符进行实例化的时候就已经决定了,而WPF允许对象在被创建的时候并不包含用于存储数据的空间,只保留在需要用到数据时能够获得默认值、借用其他对象数据或实时分配空间的能力,这种对象就是依赖对象,而这种实时获取数据的能力就是靠依赖属性来实现。
783 0
|
C# C++
WPF附加属性的Set函数不调用的问题
原文:WPF附加属性的Set函数不调用的问题 今天写程序的时候用到了附加属性,我是用VS内置的propa的代码段来实现的,代码如下:     class Attach    {        public static bool GetIsEnabl...
831 0
|
C# 测试技术
WPF 中依赖属性的继承(Inherits)
原文:WPF 中依赖属性的继承(Inherits) WPF中依赖属性的值是是可以设置为可继承(Inherits)的,这种模式下,父节点的依赖属性会将其值传递给子节点。例如,数据绑定中经常使用的DataContextProperty:     var host = new ContentContro...
850 0
|
2月前
|
C# 开发者 Windows
基于Material Design风格开源、易用、强大的WPF UI控件库
基于Material Design风格开源、易用、强大的WPF UI控件库
175 0