2010-11-15 30 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); 
      } 
     } 
    } 

只是一些想法,看看。