当前位置: 首页 > news >正文

WPF的IValueConverter用于校验和格式化TextBox的数字输入

         在数据绑定(Data Binding)的上下文中,我们经常使用继承 IValueConverter 接口的类,用于在源值和目标值之间进行转换。该接口定义了两个方法:Convert 和 ConvertBack,这两个方法分别用于从源值到目标值的转换和从目标值回到源值的转换(如果绑定支持双向绑定)。

        TextBox 控件的 UpdateSourceTrigger 属性用于控制何时更新绑定源的值,它有以下4个可选值:

  • PropertyChanged:当 TextBox 的内容发生任何变化时,都会更新绑定源。这是默认值,提供了即时反馈,但可能会增加应用程序的负载,因为每次击键都会触发更新。主要用于实时校验文本输入。
  • LostFocus:当 TextBox 失去焦点时,更新绑定源。这减少了不必要的更新,但可能意味着在用户完成输入之前,绑定源的值不会反映最新的更改。
  • Explicit:不会自动更新绑定源。你需要显式调用 BindingExpression 的 UpdateSource 方法来更新绑定源。
  • Default:使用绑定目标的默认 UpdateSourceTrigger 值。对于 TextBox,这通常是 PropertyChanged

        TextBox 控件的绑定模式(Mode)通常不是 TextBox 控件本身的直接属性,而是与数据绑定(Data Binding)相关的属性。当在 TextBox 的 Text 属性上使用数据绑定时,有时需要设置 Binding 对象的 Mode 属性来控制数据的流动方向。它有如下5个可选值:

  1. OneWay:这是单向绑定的默认模式。当源属性的值改变时,目标属性(即 TextBox 的 Text 属性)的值会自动更新。但是,对目标属性的更改不会传播回源属性。

  2. TwoWay:这是双向绑定的模式。当源属性或目标属性的值改变时,另一个属性的值也会自动更新。在 TextBox 的上下文中,这意味着当你在文本框中输入文本时,绑定的源属性会更新;同样地,如果源属性的值在代码中被改变,文本框中的内容也会更新。

  3. OneWayToSource:这是另一种单向绑定模式,但与 OneWay 相反。在这种模式下,当目标属性(TextBox 的 Text 属性)的值改变时,源属性的值也会更新,但源属性的变化不会影响到目标属性。

  4. OneTime:在这种模式下,数据只在绑定时从源传输到目标一次。之后,源属性的变化不会反映到目标属性上,并且目标属性的变化也不会尝试回写到源属性。

  5. Default:这表示使用绑定目标的默认模式。对于 TextBox 的 Text 属性,默认模式通常是 TwoWay,但这也可能取决于具体的绑定上下文和父控件的设置。

 

        如下xaml页面中,左边的TextBox使用Converter属性,绑定值转换器,右边的则没有。

<Window x:Class="TextConverterTest.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:TextConverterTest"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Window.Resources><local:NumericToStringConverter x:Key="NToSConverter"/><Style TargetType="TextBox"><Setter Property="Height" Value="80"></Setter><Setter Property="Width" Value="180"></Setter><Setter Property="HorizontalContentAlignment" Value="Center"></Setter><Setter Property="VerticalContentAlignment" Value="Center"></Setter><Setter Property="FontSize" Value="20"></Setter></Style></Window.Resources><Grid Height="100" Width="400"><Grid.RowDefinitions><RowDefinition></RowDefinition></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition></ColumnDefinition><ColumnDefinition></ColumnDefinition></Grid.ColumnDefinitions><TextBox Grid.Row="0" Grid.Column="0" Text="{Binding Path=TextBoxLeftStr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource NToSConverter}}"></TextBox><TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=TextBoxRightStr, Mode=TwoWay}, UpdateSourceTrigger=PropertyChanged"></TextBox></Grid>
</Window>

         添加TextBox的Path绑定的字段属性。在构造函数中,必须要有【DataContext = this;】这行代码,用于获取或设置元素参与数据绑定时的数据上下文。

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{public string TextBoxLeftStr { get; set; }public string TextBoxRightStr { get; set; }public MainWindow(){InitializeComponent();DataContext = this;//必须要有,关联上下文}
}

        IValueConverter接口的具体实现: 

public class NumericToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{try{if (value == null || string.IsNullOrEmpty(value.ToString())){return "";}else if (value.ToString().Last() == '.'){return value.ToString();}decimal decimalValue = System.Convert.ToDecimal(value);string format = decimalValue % 1 == 0 ? "0" : "0.0"; // 如果小数部分为0则不显示小数,否则显示一位小数  return decimalValue.ToString(format, CultureInfo.InvariantCulture);}catch (Exception ex){MessageBox.Show(ex.Message);return "";}
}// ConvertBack方法可能不需要,因为通常TextBox到数值的转换是单向的  
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{try{if (value == null || string.IsNullOrEmpty(value.ToString())){return "";}else if (value.ToString().Last() == '.'){return value.ToString();}decimal decimalValue = System.Convert.ToDecimal(value);string format = decimalValue % 1 == 0 ? "0" : "0.0"; // 如果小数部分为0则不显示小数,否则显示一位小数  return decimalValue.ToString(format, CultureInfo.InvariantCulture);}catch (Exception ex){MessageBox.Show(ex.Message);return "";}
}
}

        在xaml中引入资源类:

<Window.Resources><local:NumericToStringConverter x:Key="NToSConverter"/>
</Window.Resources>

         实现效果:左TextBox最多只能输入1位小数。且左右两个TextBox均不能输入除数字和小数点以外的字符。

http://www.lryc.cn/news/388074.html

相关文章:

  • SQL Server的守护神:Always On 高可用性详解
  • Eureka入门
  • 高阶面试-netty部分
  • 在 C++的跨平台开发中,如何处理不同操作系统和编译器之间的细微差异,以确保程序能够稳定且高效地运行?
  • 独孤思维:脑子不好使,副业稳赚钱
  • 【数据结构】(C语言):二叉搜索树
  • 泛微开发修炼之旅--23基于ecology自研的数据库分页组件(分页组件支持mysql、sqlserver、oracle、达梦等)
  • 《昇思25天学习打卡营第4天 | mindspore Transforms 数据变换常见用法》
  • 【Python时序预测系列】基于LSTM实现多输入多输出单步预测(案例+源码)
  • git客户端工具之Github,适用于windows和mac
  • ai除安卓手机版APP软件一键操作自动渲染去擦消稀缺资源下载
  • Unity获取剪切板内容粘贴板图片文件文字
  • 利用谷歌云serverless代码托管服务Cloud Functions构建Gemini Pro API
  • 极狐GitLab 17.0 重磅发布,100+ DevSecOps功能更新来啦~【一】
  • python实现符文加、解密
  • 【解释】i.MX6ULL_IO_电气属性说明
  • 02-《石莲》
  • MySQL之聚簇索引和非聚簇索引
  • Web后端开发之前后端交互
  • 520. 检测大写字母 Easy
  • vue的跳转传参
  • docker配置镜像源
  • MySQL高级-SQL优化-insert优化-批量插入-手动提交事务-主键顺序插入
  • 认识100种电路之振荡电路
  • SSH 无密登录配置流程
  • Python自动化运维 系统基础信息模块
  • 如何安装和配置Monit
  • 【redis】redis分片集群基础知识
  • Python 面试【★★★★】
  • Knife4j 2.2.X 版本 swagger彻底禁用