2010-11-15 2 views
2

Le code ci-dessous illustre un comportement inattendu (pour moi!) Lors de la combinaison de la liaison de données et de la validation dans Winforms. Quelqu'un peut-il me dire comment je peux empêcher la mise à jour de la source de données lorsque la validation échoue?Winforms DataBinding et validation, pourquoi la source de données est-elle mise à jour lorsque la validation échoue?

Merci beaucoup.

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)); 
     } 
    } 
} 

Répondre

-1

I ont tendance à « force brute » mon code - pouvez-vous définir une valeur initiale à votre private string _field, peut-être dans un constructeur? En outre, êtes-vous sûr que la définition de la propriété Cancel de votre CancelEventHandler sur TRUE marque l'invalidité de vos données?

Vous pouvez même ajouter un champ private bool _valid à votre classe de données qui ne renvoie des valeurs que si elle est valide.

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); 
      } 
     } 
    } 

Juste quelques idées à examiner.

Questions connexes