开发者

Winforms databinding and validation, why is datasource updated when validation fails?

The code below illustrates some unexpected (for me!) behaviour when combining data binding and validation in winforms. Can anyone tell me how I can prevent the datasource from being updated when validation fails?

Many thanks.

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.EnablePreventFocu开发者_如何学JAVAsChange;

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


I tend to "brute force" my code - could you set an initial value to your private string _field, perhaps in a constructor?

Also, are you sure that setting your CancelEventHandler's Cancel property to TRUE marks your data as invalid?

You may even want to add a private bool _valid field to your Data class that only returns values if it is 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);
            }
        }
    }

Just some ideas to look into.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜