`
mmdev
  • 浏览: 12921113 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

继续聊WPF——依赖项属性(1)

 
阅读更多

本系列文章是从我的QQ空间拷过来的。

依赖项属性可以称得上是WPF中比较难理解的概念,为了搞清楚这个概念,我都把.NET类库进行了反编译,但是,其结果我也是想到了的,微软不是傻子,.NET那么庞大,就算能被你反编译了,你也看不懂它的代码。

所以说,经过我一番研究,虽然没有把.NET的每一行代码都弄明白,不过,黄天终不负有心人,依赖项属性的使用方法与基本原理,我可以说已经弄明白了,恰巧,前两天在网上看到一篇讨论依赖项属性的文章,写得还不错,作者估计也是一位高人,再加上我个人的研究,从实际应用的角度来说,我现在已经掌握了依赖项属性的使用方法了,不妨告诉你,其实很简单,可以这么说,整个WPF都很简单,和许多刚接触WPF的朋友一样,一开始我也是认为它很复杂很难懂。

为什么这样说呢?大家都知道,微软官方总是为它自己推出的产品配备很完备的文档,对,就是那个很出名的MSDN。

许多初学WPF的朋友,一定也会像我一样,去查阅MSDN,通过上面的介绍来入门,可杯具正是发生在这个时候,WPF的难懂难学就是被微软自己的文档所误导,先别说翻译的质量不好,就算你看英文原文,你大概也会看得头晕。

真的,那些概念模型实在太抽象了,从刚接触WPF到现在,我都不知道把MSDN翻了多少遍了,甚至查到微软都把我的IP列入黑名单了,呵呵,而且,我也下载了英文原版的SDK来对比研究。

说实话,对.NET类库进行反编译的学习方法效率很低,表面上说可以更深入地了解.NET框架,但是,我不推荐这样学习,真的,得不尝失,花费很多精力和时间,而收获甚少;还有就是,反编译.NET类库是属于侵权,哈,幸好我们都生活在没有法律的中国,不然,一定会被微软告上法庭。

这次反编译,完全出于无奈,因为有些概念的确难以理解。

在研究的同时,我也进行了反思,最后感悟是——还是那句老话:理论的东西,哪怕你把它背下来了,你永远也不懂。

对我们来说,学编程为了什么?不就是为了应用吗?也就是说用于实战,既然这样,其实我们不必把理论的东西钻得太死,不然,钻牛角尖容易走火入魔。

依赖项属性的重点在于“依赖”二字,既然是依赖了,也就是说:依赖项属性的值的改变过程一定与其它对相关,不A依赖B就B依赖A,或者相互依赖。

说白了,所谓依赖,主要应用在以下地方:

1、双向绑定。有了这个,依赖项属性不用写额的代码,也不用实现什么接口,它本身就俱备双向绑定的特性,比如,我把员工对象的姓名绑定到摇文本框,一旦绑定,只要文本框中的值发生改变,依赖项属性员工姓名也会跟着变化,反之亦然;

2、触发器。这个东西在WPF中很重要,比如,一个按钮背景是红色,我想让它在鼠标停留在它上面是背景变成绿色,而鼠标一旦移开,按钮恢复红色。

如果在传统的Windows编程中,你一定会想办法弄一些事件,或者委托来处理,还要写一堆代码。告诉你,有了依赖项属性,你将一行代码都不用写,所有的处理均由WPF属性系统自动处理。而触发器只是临时改变属性的值,当触完成时,属性值自动被“还原”。

3、附加属性。附加属性也是依赖项属性,它可以把A类型的的某些属性推迟到运行时根据B类型的具体情况来进行设置,而且可以同时被多个类型对象同时维护同一个属性值,但每个实例的属性值是独立的。

4、A属性改变时,也同时改变其它属性的值,如TogleButton按下的同时,弹出下拉框。

为了进行比较,我们先来说说传统面向对象编程中对类属性的定义,请看下面一个简单的类,它只有一个公共属性。

    public class Student
    {
        public string Name { set; get; }
    }


这时候,我们布局一下WPF主窗口,如下所示XAML:

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="180" Width="300" Loaded="Window_Loaded">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="姓名:"/>
<TextBox x:Name="txtName" Grid.Column="1" Grid.Row="0" Margin="0,5,20,5"/>
<TextBlock Grid.Column="0" Grid.Row="1" Text="改变值:"/>
<TextBox x:Name="txtCh" Grid.Column="1" Grid.Row="1" Margin="0,5,20,5"/>
<Button x:Name="btn" Grid.Row="2" Grid.ColumnSpan="2" Margin="70,5,70,5" Click="btn_Click">显示属性值</Button>
</Grid>
</Window>

在窗口的加载完成事件中,我们作两个绑定:

(1)把Student的实例的Name属性与textBox的text属性绑定;

(2)同时与第二个文本框也绑定。

运行程序,在第一个文本框中输入内容,再点一下第二个文本框,或点一下按钮,虽然第二个文本框也会随之改变,但并不是同步改变,而是当焦点离开第一个文本框后才发生改变,这就不属于同步了。

完整代码如下:

        Student myStu = new Student { Name = "小明" };
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //绑定数据
            BindingOperations.SetBinding(txtName, TextBox.TextProperty,
                new Binding { Source = myStu, Path = new PropertyPath("Name"), Mode = BindingMode.TwoWay });
            BindingOperations.SetBinding(txtCh, TextBox.TextProperty,
                new Binding { Source = myStu, Path = new PropertyPath("Name"), Mode = BindingMode.TwoWay });
        }

        private void btn_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("当前实例的属性值:Name = " + myStu.Name);
        }

分享到:
评论

相关推荐

    Apress.Pro.WPF.in.C.Sharp.2008.2nd.Edition.Feb.2008

    6.1.2 WPF使用依赖项属性的方式 124 6.2 理解路由事件 126 6.2.1 定义和注册路由事件 126 6.2.2 关联事件处理程序 128 6.2.3 事件路由 129 6.3 WPF事件 137 6.3.1 生命周期事件 137 6.3.2 输入事件 139 6.3.3 键盘...

    亮剑.NET深入体验与实战精要2

    第1章 .NET,你真的知道了吗 3 1.1 搞清自己是干什么的 4 1.2 .NET的几个特性 7 1.3 万丈高楼平地起:面试者必会 9 1.3.1 C#介绍 10 1.3.2 命名空间 10 1.3.3 C#语法格式要点 10 1.3.4 变量 12 1.3.5 类型推断 12 ...

    亮剑.NET深入体验与实战精要3

    第1章 .NET,你真的知道了吗 3 1.1 搞清自己是干什么的 4 1.2 .NET的几个特性 7 1.3 万丈高楼平地起:面试者必会 9 1.3.1 C#介绍 10 1.3.2 命名空间 10 1.3.3 C#语法格式要点 10 1.3.4 变量 12 1.3.5 类型推断 12 ...

    asp.net知识库

    动态调用对象的属性和方法——性能和灵活性兼备的方法 消除由try/catch语句带来的warning 微软的应试题完整版(附答案) 一个时间转换的问题,顺便谈谈搜索技巧 .net中的正则表达式使用高级技巧 (一) C#静态成员和...

Global site tag (gtag.js) - Google Analytics