热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

WPF数据绑定(1简单数据绑定)

2019独角兽企业重金招聘Python工程师标准小疯最近的项目组工作开发中需要用到WPF,所以最近在学习WPF,小疯对于WPF中的绑定比较迷糊&#

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

小疯最近的项目组工作开发中需要用到WPF,所以最近在学习WPF,小疯对于WPF中的绑定比较迷糊,认为这里需要多注意。然后小疯在这里找到了一篇文章,转过来分享一下:

 

数据绑定就是将各种数据与用户展现控件进行关联的过程。WPF的数据绑定机制可以以最少的代码方便地处理这样的关联。

简单数据绑定

1 无数据绑定

在实现这样的用户交互的时候:

clip_image002[4]

 

在没有任何数据绑定机制实现的时候无非采用

this.nameTextBox.Text = person.Name;

this.ageTextBox.Text = person.Age.ToString();

这样的赋值的方法,而一旦数据改变了,将界面的值写回给person对象。

1.1对象改变

我们现在需要当对象发生改变的时候,UI的现实如何同步跟着改变呢?

实现起来还是比较复杂的,看如下代码就明白了。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;//INotifyPropertyChanged

namespace SimpleDataBinding
{
    class Person:INotifyPropertyChanged 
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void Notify(string PropName)
        {
            if (this.PropertyChanged != null)
            {
                PropertyChanged(this,new PropertyChangedEventArgs(PropName));
            }
        }

        public Person()
        {
            _Age = 0;
            _name = "Null";
        }

        private string _name;
        public string Name
        {
            get
            {  return _name; }
            set
            {
                if (value == _name)
                { return; }
                _name = value;//注意:不能用this.Name来赋值,如果这样形成循环调用,栈溢出
                Notify("Name");
            }
        }

        private int _Age;
        public  int Age
        {
            get
            { return _Age; }
            set
            {
                if (value == _Age) return;
                _Age = value;
                Notify("Age");
            }
        }

    }
}

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace SimpleDataBinding
{
    ///


    /// Window1.xaml 的交互逻辑
    ///

    public partial class WithoutDataBinding : Window
    {
        private Person _person;

        public WithoutDataBinding()
        {
            InitializeComponent();

            //可以采用如下对象初始化,但本示例为了使用使用属性改变UI改变就先不赋值。
            //_person = new Person
            //{
            //    Name = "zhangying",
            //    Age = 28
            //};
            _person = new Person();

            _person.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e)
           {
               switch (e.PropertyName)
               {
                   case "Name":
                       this.txt_name.Text = _person.Name;
                       break;
                   case "Age":
                       this.txt_age.Text = _person.Age.ToString();
                       break;

               }
           };

        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            _person.Name = "zhangying";
            _person.Age = 28;
        }

    }
}

 

1.2 UI改变

当UI的输入值发生变化的时候,如何同步对象的值呢?这需要给他们设置事件代码:

private void txt_name_TextChanged(object sender, TextChangedEventArgs e)

{

_person.Name = this.txt_name.Text;

}

private void txt_age_TextChanged(object sender, TextChangedEventArgs e)

{

int age = 0;

if(int.TryParse(this.txt_age.Text,out age)

{

_person.Age = age ;

}

}

2数据绑定

上面的示例是使用人工的手段将对象属性与UI显示进行同步,而WPF数据绑定则是注册两个属性与数据绑定引擎,来处理同步,合适的数据转换,如下图:

clip_image004[4]

2.1 Bindings

1.使用元素属性绑定:

2. 简化属性绑定

更简化方式:

看一个更多特性的绑定方式(属性元素的方式):

Converter="{StaticResource ageConverter}" />

上面的绑定可以采用如下简洁方式:

Foreground="{Binding Path=Age, Mode=OneWay, Source={StaticResource Tom},

Converter={StaticResource ageConverter}}" />

注意上面的引号的用法和不用引号的用法,使用属性元素的方式必须用引号。

下面图表列出绑定到一个对象时候可能用到的属性:

clip_image006[4]

clip_image008[4]

这些属性后面将一一介绍到。

2.2 隐式数据源Implicit Data Source

在WPF中,每个FrameworkElement 和FrameworkContentElement对象都有一个DataContex属性,该属性是Object类型,所以你可以给它指定任何类型的值。当我们定义个对象作为绑定对象,则绑定引擎在逻辑树上寻找该数据库绑定源,如下图所示:

clip_image010[4]

2.3 数据岛Data Islands

看以下代码示例就明白了:

clip_image012[4]

private void btn_Click(object sender, RoutedEventArgs e)

{

Person person = (Person)this.FindResource("zy");

MessageBox.Show(string.Format("I am {0},Age is {1}",person.Name,person.Age.ToString()));

}

2.4 显示数据源Explicit Data Source

显示数据源设置对于多个数据源是很重要的,我们可以通过绑定属性的Source来实现。

clip_image014[4]

注意上面两个文本框设置了不同的数据源的属性。

2.5 绑定到其他控件binding to other controls

如下代码所示:

2.6 值转换 Value Conversation

上面的代码我们发现绑定是将一个数值类型绑定到一个字符串,类型不符合,这究竟是如何做到的呢?原来这是一个号称Value Converter类的功劳,它实现了IValueConverter接口,该接口有两个方法:Convert和ConvertBack。(该接口在System.Windows.Data命名空间,PresentationFramework.dll程序集中),实现 IValueConverter 接口时,最好用ValueConversionAttribute 属性来修饰此实现,以便向开发工具指示转换所涉及的数据类型,如下面的示例所示:(以下示例摘录自MSDN)

看下面的使用方法:

clip_image016[4]

使用方法,先指定数据源

clip_image018[4]

clip_image020[4]

2.7 Editable Value Conversion

2.8 Validation

一个验证规则就是在一条目标数据更新来源数据的时候的一段数据验证代码,这段代码一般是继承ValidationRule类并覆盖Validate方法,一个内置的规则称为ExceptionValidationRule

如下代码我们可以看到使用最基本的验证的方式:

clip_image022[4]

当我们运行程序的时候

clip_image024[4]

红色边框显示输入框数据格式错误。但是我们发现这样仍然不够友好,因为没有消息提示到底为什么错误。

为了显示错误,需要使用绑定的事件来侦听ValidationError,代码示例很容易说明这点:

clip_image026[4]

这样还不行,还必须如下图设置:

clip_image028[4]

运行结果大家肯定很明白了,当然这也许还不是我们需要的,我们可以更多地控制行为,这就要求我们自定义验证规则。下面我们以一个实例来讲解自定义验证规则。

首先我们通过继承ValidationRule类然后覆写validate方法,还是让代码说明一切吧:

clip_image030[4]

clip_image032[4]

在实际项目中,可能大家对错误提示采用对话框不是很喜欢,最好的方式是WindowsForm的验证方式Tooltip,但有一点需要注意ValidateRule没有类似ValidateSucess事件让我们清除错误的时候产生的Tooltip,以至于整个Tooltip的显示很奇怪。

2.9绑定路径句法Binding Path Syntax

以下列出MSDN上的描述:

使用 Path 属性可以指定您要绑定到的源值:

· 在最简单的情况下,Path 属性值是要用于绑定的源对象的属性名,如 Path=PropertyName。

· 在 C# 中可以通过类似语法指定属性的子属性。 例如,子句 Path=ShoppingCart.Order 设置与对象或属性 ShoppingCart 的 Order 子属性的绑定。

· 若要绑定到附加属性,应在附加属性周围放置圆括号。 例如,若要绑定到附加属性 DockPanel..::.Dock,则语法是 Path=(DockPanel.Dock)。

· 可以在要应用索引器的属性名后面的方括号内指定属性的索引器。 例如,子句 Path=ShoppingCart[0] 将绑定设置为与属性的内部索引处理文本字符串“0”的方式对应的索引。 还支持嵌套的索引器。

· 可以在 Path 子句中混合索引器和子属性;例如,Path=ShoppingCart.ShippingInfo[MailingAddress,Street].

· 在索引器内部,您可以有多个由逗号 (,) 分隔的索引器参数。 可以使用圆括号指定每个参数的类型。 例如,您可以有 Path="[(sys:Int32)42,(sys:Int32)24]",其中 sys 映射到 System 命名空间。

· 如果源为集合视图,则可以用斜杠 (/) 指定当前项。 例如,子句 Path=/ 用于设置到视图中当前项的绑定。 如果源为集合,则此语法指定默认集合视图的当前项。

· 可以结合使用属性名和斜杠来遍历作为集合的属性。 例如,Path=/Offices/ManagerName 指定源集合的当前项,该源集合包含也作为集合的 Offices 属性。 其当前项是一个包含 ManagerName 属性的对象。

· 也可以使用句点 (.) 路径绑定到当前源。例如,Text=”{Binding}” 等效于 Text=”{Binding Path=.}”。

转义机制

· 在索引器 ([ ]) 内部,插入符号 (^) 用于对下一个字符进行转义。

· 如果您在 XAML 中设置 Path,则还需要使用 XAML 实体对 XAML 分析程序专用的某些字符进行转义:

· 使用 & 对字符“&”进行转义。

· 使用 > 对结束标记“>”进行转义。

· 此外,如果您使用标记扩展语法描述属性中的整个绑定,则需要使用反斜杠 \ 对 WPF 标记扩展分析程序专用的字符进行转义:

· 反斜杠 \ 本身是转义字符。

· 等号 (=) 将属性名与属性值隔开。

· 逗号 (,) 用于分隔属性。

· 右大括号 (}) 是标记扩展的结尾。

Binding the ToolTip property to the validation error message

Name="ageTextBox" ...

ToolTip="{Binding

ElementName=ageTextBox,

Path=(Validation.Errors)[0].ErrorContent}">

2.10相对数据源Relative Source

还是代码来说明更易理解

ToolTip="{Binding RelativeSource={RelativeSource Self},

Path=(Validation.Errors)[0].ErrorContent}">

在上面实例中我们采用 ElementName=txtDate这样的方式指定的,这里使用self来表示引用该标签所在的元素生成的对象,当然我们还可以使用类似于parent指向上一级,关于Relative resource在后续章节会继续讨论。

2.11更新源数据触发器Update Source Trigger

在前面我们基本上是在目标控件的失去焦点的时候发生相关验证并更新数据源的,而实际上更新数据源的机制有多种类型,如下:

namespace System.Windows.Data

{

     public enum UpdateSourceTrigger

     {

          Default = 0, // updates "naturally" based on the target control

          PropertyChanged = 1, // updates the source immediately

          LostFocus = 2, // updates the source when focus changes

          Explicit = 3, // must call BindingExpression.UpdateSource()

      }

}

而在XAML里面必须如下声明:


转:https://my.oschina.net/yexiaofeng/blog/1826330



推荐阅读
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • IB 物理真题解析:比潜热、理想气体的应用
    本文是对2017年IB物理试卷paper 2中一道涉及比潜热、理想气体和功率的大题进行解析。题目涉及液氧蒸发成氧气的过程,讲解了液氧和氧气分子的结构以及蒸发后分子之间的作用力变化。同时,文章也给出了解题技巧,建议根据得分点的数量来合理分配答题时间。最后,文章提供了答案解析,标注了每个得分点的位置。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
author-avatar
诺汐衹湜忲傻
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有