WPF入门第六篇 WPF的Binding

这篇具有很好参考价值的文章主要介绍了WPF入门第六篇 WPF的Binding。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

WPF的Binding

在传统的Windows软件中,大部分都是UI驱动程序的模式,也可以说事件驱动程序。WPF作为Winform的升级,它把UI驱动程序彻底改变了,核心回到了数据驱动程序的模式上面,这样,程序就回到了算法和数据。数据,才是真正需要重点处理的。

Binding最为重要的一个特点是通讯,连接着前台与后台。首先看一下Binding最简单的使用方法:

一、元素之间的绑定

WPF入门第六篇 WPF的Binding

这里有3个控件,Slider、TextBox、Label,其中TextBox和Label都作为目标,Slider都作为数据源,把Slider中的值交由两个控件体现,移动滑块,TextBox会自动显示Value的值,也就是FontSize的值。因为两个绑定都设置了双向绑定,所以可以在文本框中输入值,然后丢失焦点,也能反馈回去。

看一下XAML中的绑定语句,这里用的ElementName就是制定要绑定的对象的名字,Path就是要绑定的依赖项属性,Mode就是绑定方式,这里需要说明的是Mode有五种方式:
ⅰ. OneWay 单向绑定
ⅱ. TwoWay 双向绑定
ⅲ. OneTime,最初根据源属性值设置目标属性,以后就忽略所有改变,就是说,只进行初始化。
ⅳ. OneWayToSource,这和OneWay相反。
ⅴ. Default,这是默认形式,它根据目标属性自动设置。
如果把TextBox中的值修改成其他的,滑条位置没有改变,字体大小也没有改变,这是怎么回事呢?当TextBox失去焦点的时候,就会发生相应的改变了。这是因为这个绑定中的默认更新机制,更新机制Binding.UpdateSourceTrigger,这个属性有4个枚举值:
ⅰ. PropertyChange,当值改变的时候,就更新。
ⅱ. LostFocus,当失去焦点的时候更新。
ⅲ. Explicit,当调用BindingExpression.UpdateSource()方法的时候更新,其他情况不会更新。
ⅳ. Default,默认形式。
注意:以上四种更新机制的设定,只会影响源数据,而不会影响目标数据。

二、元素自身的绑定

WPF入门第六篇 WPF的Binding

除了可以绑定别的元素,也可以绑定自身的其他属性,例如Slider自身的Opacity属性和自身的Value属性绑定,当滑块向左移动的时候,会逐渐隐藏起来。

三、后台数据与元素之间的绑定

前面说了元素之间的绑定和元素自身的绑定,最后重点来了,后台数据和前台元素的绑定,这种绑定方式很好地体现了数据驱动程序的运行模式。
首先新建Person类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfHouTaiBindingQianTai
{
    public class Person
    {
        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 年龄
        /// </summary>
        public int Age { get; set; }
    }
}

页面后台代码:

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.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;

namespace WpfHouTaiBindingQianTai
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Person person = new Person { Name = "SoftEasy" };
            Binding binding = new Binding() { Path = new PropertyPath("Name"), Source = person };
            this.TxtName.SetBinding(TextBox.TextProperty, binding);
        }
    }
}
<Window x:Class="WpfHouTaiBindingQianTai.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfHouTaiBindingQianTai"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TextBox x:Name="TxtName" HorizontalAlignment="Left" Margin="24,69,0,0"
                 TextWrapping="Wrap" VerticalAlignment="Top" Height="60" Width="600"/>
    </Grid>
</Window>

显示效果:
WPF入门第六篇 WPF的Binding

数据绑定的方式已经写完了。Binding是一条高速公路,那么为了提高数据传递的合法性和有效性,我们要在这条高速公路中建立起一系列的关卡,有的用来转换数据,有的用来校验数据,下面说一下Binding对数据的校验和转换。

(一)Binding的数据校验

Binding的数据校验工作是派生自ValidationRule类,并且对Validate方法进行重写的自定义类!
看一下实例:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace WpfHouTaiBindingQianTai
{
    public class DataValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            double d = 0;
            if (double.TryParse(value.ToString(),out d))
            {
                if(d >= 0 && d<= 100)
                {
                    return new ValidationResult(true, null);
                }
            }
            return new ValidationResult(false, "验证失败!");
        }
    }
}

先设计一个校验类,它继承ValidationRule类并且重写Validate方法。使用这个类的时候是创建Binding的时候设置校验的。
代码如下:

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.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;

namespace WpfHouTaiBindingQianTai
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            //Person person = new Person { Name = "SoftEasy" };
            //Binding binding = new Binding() { Path = new PropertyPath("Name"), Source = person };
            //this.TxtName.SetBinding(TextBox.TextProperty, binding);
            Binding binding = new Binding("Value") { Source = this.slider };
            binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            DataValidationRule dataValidationRule = new DataValidationRule();
            dataValidationRule.ValidatesOnTargetUpdated = true;
            binding.ValidationRules.Add(dataValidationRule);
            binding.NotifyOnValidationError = true;
            this.TxtFontSize.SetBinding(TextBox.TextProperty, binding);
            this.TxtFontSize.AddHandler(Validation.ErrorEvent, new RoutedEventHandler(this.ValidationError));
        }
        /// <summary>
        /// 验证错误
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ValidationError(object sender,RoutedEventArgs e)
        {
            if(Validation.GetErrors(this.TxtFontSize).Count > 0)
            {
                this.TxtFontSize.ToolTip = Validation.GetErrors(this.TxtFontSize)[0].ErrorContent.ToString();
            }
        }
    }
}
<Window x:Class="WpfHouTaiBindingQianTai.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfHouTaiBindingQianTai"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
  <Grid>
    <Label x:Name="LblFontSize" Content="SoftEasy" FontSize="{Binding ElementName=slider ,Path=Value,Mode=TwoWay}" 
           HorizontalAlignment="Left" Margin="24,18,0,0" VerticalAlignment="Top"/>
    <Slider x:Name="slider" HorizontalAlignment="Left" Margin="24,117,0,0"
            VerticalAlignment="Top" Width="330" Maximum="200" Minimum="20"/> //这里的最大值改成了200,为了测试让它报错
    <TextBox x:Name="TxtFontSize" HorizontalAlignment="Left" Height="23" Margin="24,69,0,0"
             TextWrapping="Wrap" Text="{Binding ElementName=slider ,Path=Value ,Mode=TwoWay}"
             VerticalAlignment="Top" Width="120"/>
  </Grid>
</Window>

显示效果:
WPF入门第六篇 WPF的Binding

因为设置了传过去的值不能是超过0~100,所以当超过了就显示红色边框。在Binding中,默认是会认为数据源是肯定正确的,所以如果将TextBox作为数据源,而Slider作为目标,数据源输入错误是没有显示的,那么怎么解决这个问题呢?设置 dataValidationRule.ValidatesOnTargetUpdated = true;

(二)Binding的数据转换

Binding还有另外一种机制称为数据转换,当Source端指定的Path属性值和Target端指定的目标属性不一致的时候,我们可以添加数据转换器(Convert)。上面我们提到的问题实际上就是double和string类型相互转换的问题,因为处理起来比较简单,所以WPF类库就自己帮我们做了,但有些数据类型转换就不是WPF能帮我们做的了,当遇到这些情况,我们只能自己动手来写Converter,方法是创建一个类并让这个类实现 IValueConverter接口。

//TimeConver.cs
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;

namespace WpfHouTaiBindingQianTai
{
    /// <summary>
    /// 自定义事件转换
    /// </summary>
    public class TimeConver : IValueConverter
    {
        //当值从绑定源传播给绑定目标时,调用方法Convert
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if(value == null)
            {
                return DependencyProperty.UnsetValue;
            }
            DateTime date = (DateTime)value;
            return date.ToString("yyyy-MM-dd");
        }

        //当值从绑定目标传播给绑定源时,调用此方法ConvertBack
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string str = value as string;
            DateTime txtDate;
            if(DateTime.TryParse(str,out txtDate))
            {
                return txtDate;
            }
            return DependencyProperty.UnsetValue;
        }
    }
}

这个就是日期转换类,它有两个方法:
ⅰ. 当值从绑定源传播给绑定目标时,调用方法Convert
ⅱ. 当值从绑定目标传播给绑定源时,调用此方法ConvertBack,方法ConvertBack的实现必须是方法Convert的反向实现。
这两个方法分别在里面写入怎么转换,转换成什么类型就是返回类型。
把这个绑定的Convert属性设置成我们设计的转换类的实例就可以了.文章来源地址https://www.toymoban.com/news/detail-404148.html

到了这里,关于WPF入门第六篇 WPF的Binding的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第六篇:区块链概述及应用场景

    作者:禅与计算机程序设计艺术 区块链(Blockchain)是一种分布式数据库,用于管理对等网络上交易或数据记录的不可篡改性、透明性和可追溯性,并为用户提供了支付服务、记账本功能、身份认证、存证等多种应用领域。简而言之,区块链是一个去中心化的、共享的、永久

    2024年02月08日
    浏览(41)
  • 微服务开发系列 第六篇:Redisson

    A、技术栈 开发语言:Java 1.8 数据库:MySQL、Redis、MongoDB、Elasticsearch 微服务框架:Spring Cloud Alibaba 微服务网关:Spring Cloud Gateway 服务注册和配置中心:Nacos 分布式事务:Seata 链路追踪框架:Sleuth 服务降级与熔断:Sentinel ORM框架:MyBatis-Plus 分布式任务调度平台:XXL-JOB 消息中间

    2024年02月07日
    浏览(55)
  • Java学习手册——第六篇输入输出

    几乎所有的开发语言都会有输入输出,程序的定义里面也有输入输出,可以见得输入输出是何等的重要。如果没有输入,人类如何与计算机交流?如果没有输出,一切努力都是白费,因为我们看不到结果。 这里的输入输出你可以简单的理解为人与人之间的沟通交流,虽然我们

    2024年02月02日
    浏览(46)
  • 第六篇从严谨起,谈谈量子计算安全

    作者:禅与计算机程序设计艺术 由于科技的飞速发展,人类也变得越来越“工科化”。因为有了科技的进步,我们终于可以做到这样一个地步——把一切都变成数字。这种全新的数字世界正在引领着我们的生活。而与此同时,随之而来的便是更加复杂、更加迅猛的计算机革命

    2024年02月07日
    浏览(54)
  • 【JAVA基础篇教学】第六篇:Java异常处理

    博主打算从0-1讲解下java基础教学,今天教学第五篇: Java异常处理。 异常处理是Java编程中重要的一部分,它允许开发人员在程序运行时检测和处理各种错误情况,以保证程序的稳定性和可靠性。在Java中,异常被表示为对象,它们是Throwable类的子类。常见的异常包括受检异常

    2024年04月13日
    浏览(42)
  • 第六篇,STM32脉冲宽度调制(PWM)编程

    1.PWM概念 PWM叫脉冲宽度调制(Pulse Width Modulation),通过编程控制输出方波的频率和占空比(高低电平的比例),广泛应用在测量,通信,功率控制等领域(呼吸灯,电机)。     PWM由定时器驱动,PWM周期就是定时器的周期,为了调节占空比,需要在定时器的基础上加上一个比较计

    2023年04月09日
    浏览(41)
  • 微信小程序第六篇:元素吸顶效果实现

     系列文章传送门: 微信小程序第一篇:自定义组件详解 微信小程序第二篇:七种主流通信方法详解 微信小程序第三篇:获取页面节点信息 微信小程序第四篇:生成图片并保存到手机相册 微信小程序第五篇:页面弹出效果及共享元素动画 话不多说,先看效果: 这种效果在

    2024年02月16日
    浏览(43)
  • 第六篇 弹性云计算中的资源管理技术

    作者:禅与计算机程序设计艺术 云计算已经成为当下热门话题之一,随着互联网、移动互联网和物联网等新一代技术的发展,云计算正在向更加复杂、弹性、便利的方向发展。但是在云计算平台上运行的应用越来越多,服务种类也越来越丰富,同时作为一个庞大的系统,其使

    2024年02月07日
    浏览(52)
  • 【RabbitMQ | 第六篇】消息重复消费问题及解决方案

    什么是 消息重复消费 ?首先我们来看一下消息的传输流程。消息生产者–MQ–消息消费者;消息生产者发送消息到MQ服务器,MQ服务器存储消息,消息消费者监听MQ的消息,发现有消息就消费消息。 所以消息重复也就出现在 两个阶段 1 :生产者多发送了消息给MQ; 2 :MQ的一条

    2024年04月26日
    浏览(50)
  • 【HarmonyOS4.0】第六篇-ArkUI系统组件(一)

    组件是构建页面的核心,每个组件通过对数据和方法的简单封装,实现独立的可视、可交互功能单元。组件之间相互独立,随取随用,也可以在需求相同的地方重复使用。 1.1.Text定义介绍 Text 是显示文本的基础组件之一,它可以包含子组件 Span ,当包含 Span 时不生效,只显示

    2024年01月25日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包