­

Winform TextBox 數據綁定空值校驗問題

問題:

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(16)]
        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 賦值到模型數據,所以這裡需要添加轉換的方法。

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

//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 綁定可空類型遇見的問題。