问题:

using System;
using System.ComponentModel.DataAnnotations; public class Cost
{
/// <summary>
/// 成本
/// </summary>
/// <value></value>
[Display(Name = "成本")]
public float? Cost { get; set; } /// <summary>
/// 成本2
/// </summary>
/// <value></value>
[Display(Name = "成本2")]
public float? Cost2 { get; set; } /// <summary>
/// 成本3
/// </summary>
/// <value></value>
[Display(Name = "成本3")]
public float? Cost3 { get; set; } /// <summary>
/// 成本4
/// </summary>
/// <value></value>
[Display(Name = "成本4")]
public float? Cost4 { get; set; } /// <summary>
/// 成本货币符号
/// </summary>
/// <value></value>
[Display(Name = "成本货币符号")]
[StringLength()]
public string CostCurrencySymbol { get; set; }
}

需要把上面这个类的数据绑定到以下界面:

四个成本字段分别绑定到四个 TextBox Text 属性,使用以下代码添加绑定:

1. 最开始只是简单的绑定

Binding costBinding = new Binding("Text", saleProductCodeDetail, nameof(saleProductCodeDetail.Cost);

costBinding.DataBindings.Add(costBinding);

使用该方法,我们可以往 TextBox 输入数据,甚至可以输入字母及文字,但是鼠标离开 TextBox 时,TextBox 内容会自动消失。

原因分析:由于我们把 float? 类型绑定到 Text 属性,Text 属性类型是字符串类型,而我们在这里只是简单的调用了数据绑定,而输入的文本并不会被自动格式化为绑定的数据类型,因此我们在绑定数据时,需要调用带有格式化参数的重载方法:

Binding costBinding = new Binding("Text", saleProductCodeDetail, nameof(saleProductCodeDetail.Cost, true);

costBinding.DataBindings.Add(costBinding);

使用以上方法可以保证数据输入后,当数据离开 TextBox 后内容不会消失,并且输入字母或者文字后,光标无法离开当前 TextBox。

2. 解决删除已有数据后光标无法离开 TextBox

上面的方法解决了输入内容后消失的问题,但是有一个问题:当把文本框中的已有的数字删除后,光标无法离开 TextBox

原因分析:当我们把已有数据删除后,文本内容变为 "",而字符串并不会被自动解析为 null 赋值到模型数据,所以这里需要添加转换的方法。

查了半天找到了解决方法:

https://bbs.csdn.net/topics/220010265#new_post

给 Binding 添加 Parse 事件:

costBinding.Parse += CostBinding_Parse;

private void CostBinding_Parse(object sender, ConvertEventArgs e)
{
Binding binding = (Binding)sender;
if (e.Value.ToString() == "")
{
e.Value = null;
}
}

以上是参考上面链接的方法,但是链接中转换的时候是 e.Value = DBNull.Value; 怎么也不好使,我们想一下,e.Value的类型是 float? 而我们如果赋值一个 DBNull.Value 的话并不是 null,所以赋值的话并不是 null。这个地方卡了很久。

3. 我们还可以添加格式化事件

当模型的数据为 null 时,我们可以把 TextBox 的 Text 设置为 ""

costBinding.Format += CostBinding_Format;

private void CostBinding_Format(object sender, ConvertEventArgs e)
{
Binding binding = (Binding)sender;
if (e.Value == null)
{
e.Value = "";
}
}

以上是解决 TextBox 绑定可空类型遇见的问题。

Winform TextBox 数据绑定空值校验问题的更多相关文章

  1. .net WinForm 的数据绑定

    .net WinForm 的数据绑定相当灵活 http://www.cnblogs.com/ydong/archive/2006/04/22/381847.html 原来只知道 Control 类上的 ...

  2. winform textbox 的自动实现功能

    好久没写博客了,主要是太懒了,之前因为做bs的比较多现在想转cs端了,虽然现在做cs也一年了,可接触的东西太过零碎了,以至于感觉这一年好像什么都没有学到.估计是因为学了之后没有记录,不扎实,然后又忘记 ...

  3. winform treeView 数据绑定

    转载:http://www.jetwu.cn/archives/737 winform treeView 数据绑定 private void Form1_Load(object sender, Eve ...

  4. WinForm TextBox 焦点停留到文本最后

    最近写个 WinForm 项目,TextBox 控件有内容的时候,获取焦点,光标总是在最前面,很不便于输入.那怎么样让光标停留到最后呢?如下代码可以实现:            this.txtBox ...

  5. WinForm TextBox自定义扩展方法数据验证

    本文转载:http://www.cnblogs.com/gis-crazy/archive/2013/03/17/2964132.html 查看公司项目代码时,存在这样一个问题:winform界面上有 ...

  6. C#:TextBox数据绑定

    经常写用一个TextBox显示某个对象,然后编辑之后再保存的程序.以前都是在TextBox_TextChanged事件中修改对象的值,或者保存的时候再读取TextBox.Text属性保存对象的值.这样 ...

  7. Winform Textbox控件字体垂直居中

    项目中遇到要求Textbox内的字体垂直居中的问题,在网上找一直没有理想的解决方案.后来发现可以通过设置控件的字体来达到预期的效果. 默认的Textbox的Font属性为 “宋体, 9pt”,效果如下 ...

  8. Winform TextBox中只能输入数字的几种常用方法(C#)

    方法一: private void tBox_KeyPress(object sender, KeyPressEventArgs e) { ; //禁止空格键 )) return; //处理负数 if ...

  9. Winform Textbox MultiLine和WordWrap属性的使用

    突然用到,有些不明白,零乱记录下: 1.MultiLine属性为True时,Dock属性Fill值才能达到所需效果 2.MultiLine属性为False时,WordWrap属性也是无效果的,同1,T ...

随机推荐

  1. Vue 父子组件之间的互相调用方法

    第一种方法 直接在子组件中通过this.$parent.event来调用父组件的方法 父组件 <template> <div> <child></child& ...

  2. http接口封装mqtt协议

    前言 .Net Core 3.1 WebApi 列出了mqtt客户端的封装目的是为了了解运作机制 1.封装mqtt客户端 mqtt底层协议基于MQTTnet 版本2.8.5 github地址 实例化[ ...

  3. 菊长说丨一文读懂MySQL4种事务隔离级别

    经常提到数据库的事务,那你知道数据库还有事务隔离的说法吗,事务隔离还有隔离级别,那什么是事务隔离,隔离级别又是什么呢?今天我们就找菊长去,请他帮大家梳理一下这些各具特色的事务隔离级别,咱走着~~~ 点 ...

  4. windows系统下python setup.py install ---出现cl问题,cpp_extension.py:237: UserWarning: Error checking compiler version for cl: 'utf-8' codec can't decode byte 0xd3 in position 0: invalid continuation byte

    将cpp_extension.py文件中的 原始的是   compiler_info.decode() try: if sys.platform.startswith('linux'): minimu ...

  5. 2020-06-01:百万级int数据量的一个array求和。

    福哥答案2020-06-01: fork/join. 对于百万级长度的数组求和,单线程和多线程下区别不大.对于千万级长度的数组求和,多线程明显变快,大概是单线程的2-3倍. go语言测试代码如下: p ...

  6. .NetCore(Avalonia) 项目dll混淆,Ubuntu 或者deepin操作系统 deb安装包解压,重新打包

    .NetCore(Avalonia) 项目dll混淆,deb安装包解压,重新打包 本文分为两部分,一部分是介绍使用 DotNetReactor6.0 及以上版本混淆.netcore项目的dll. 另一 ...

  7. menset与fill

    menset函数一般只对int型数组进行0.-1的赋值.原因:menset对数组是按字节赋值,对每个字节的赋值是相同的,故int的4个字节全部被赋相同的值,而0正好二进制编码全为0,-1的二进制编码全 ...

  8. Python+Pytest+Allure+Git+Jenkins接口自动化框架

    Python+Pytest+Allure+Git+Jenkins接口自动化框架 一.接口基础 接口测试是对系统和组件之间的接口进行测试,主要是效验数据的交换,传递和控制管理过程,以及相互逻辑依赖关系. ...

  9. 金题大战Vol.0 C、树上的等差数列

    金题大战Vol.0 C.树上的等差数列 题目描述 给定一棵包含\(N\)个节点的无根树,节点编号\(1-N\).其中每个节点都具有一个权值,第\(i\)个节点的权值是\(A_i\). 小\(Hi\)希 ...

  10. 笔试算法稳了,GitHub 50k Star《labuladong的算法小抄》

    秋招算法有救了!!! 前不久在 GitHub 出现了一个手把手带你刷 LeetCode 的项目:fucking-algorithm. 该项目此前在 GitHub 开源后,连续多次霸榜 GitHub T ...