2010-11-15 47 views
2

下面的代码演示了在winforms中组合数据绑定和验证时的一些意外情况(对我来说)的行为。任何人都可以告诉我如何防止验证失败时更新数据源?Winforms数据绑定和验证,为什么数据源在验证失败时更新?

非常感谢。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace ValidationBug 
{ 
    /// <summary> 
    /// This illustrates some unexpected behaviour with winforms validation and binding 
    /// 
    /// To reproduce: Run the program, enter a value into the textbox, click the X to close the form. 
    /// 
    /// Expected behaviour: validation of textbox fails so data source is not updated. 
    /// 
    /// Observed behaviour: data source is updated. 
    /// </summary> 
    public class Form1 : Form 
    { 
     private class Data 
     { 
      private string _field; 
      public string Field 
      { 
       get { return _field; } 
       set 
       { 
        // this should never be called, but it is. 
        _field = value; 
       } 
      } 
     } 

     private System.ComponentModel.IContainer components = null; 

     public Form1() 
     { 
      this.Load += new System.EventHandler(this.Form1_Load); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      AutoValidate = System.Windows.Forms.AutoValidate.EnablePreventFocusChange; 

      var txt = new TextBox(); 

      // validation always fails. 
      txt.Validating += new CancelEventHandler((s, ev) => ev.Cancel = true); 
      Controls.Add(txt); 

      var data = new Data(); 

      this.components = new System.ComponentModel.Container(); 
      BindingSource bs = new BindingSource(this.components); 
      bs.DataSource = typeof(Data); 

      // only update datasource on succesful validation. 
      txt.DataBindings.Add(new Binding("Text", data, "Field", false, DataSourceUpdateMode.OnValidation)); 
     } 
    } 
} 

回答

-1

我倾向于“蛮力”我的代码 - 你能初始值设置为private string _field,或许在构造函数?

此外,您确定将您的CancelEventHandler的取消属性设置为TRUE会将您的数据标记为无效吗?

您甚至可能希望为您的Data类添加一个private bool _valid字段,该字段只在有效时返回值。

private class Data 
    { 
     private bool _valid; 
     private string _field; 

     public Data() 
     { 
      _field = null; 
      _valid = false; 
     } 

     public string Field 
     { 
      get 
      { 
       if (_valid) 
       { 
        return _field; 
       } else { 
        return null; 
       } 
      set 
      { 
       // this should never be called, but it is. 
       _field = value; 
       _valid = !String.IsNullOrEmpty(_field); 
      } 
     } 
    } 

只是一些想法,看看。