Windows Develop Bookmark and Share   
 index > Windows Forms Data Controls and Databinding > Nullable Int - Databinding to TextBox vs. UserControl
 

Nullable Int - Databinding to TextBox vs. UserControl

Hi, I somehow don't get it and hopefully somebody can explain this to me and/or a solution.

I got a "smart" data source class which implements INotifyPropertyChange and IDataErrorInfo. Just for this test I have two values in this class, an int and an int?.

I validate these values, they cannot be 0 and also not null in the latter case.

So i got several questions now:

1.

- If I do not enable formatting on the DataBinding to the nullable field, I cannot enter any data. The value is reset to null when I leave the field and it should be written back to the underlying data object.

- If I disable formatting on the DataBinding, I can enter data, but cannot leave the control without entering anything.

Why is that behavior like that? I kind of would like to have a mixture of both as the user should be able to leave the control if he does not wish to enter any data, but if he enters something it should be written to the data object.

2. The validation on the UserControl is not triggered when formatting is on. Which would mean I would have to chose right now that either the user cannot enter any data, but I can use the validation to set an error message, or the user can enter data, but validation is not triggered. What am I doing wrong here?

 

What I want to achieve is simply to bind the nullable int to the TextBox and allow the user to enter data (if he wants) and to be able to validate it at some point in my application to show him with an ErrorProvider what he did wrong at which field - like it works with the non nullable int.

 

Below is the source code of this example:

Create a form with a dummy TextBox on top which will have the focus on startup. Otherwise you won't be able to press the button to trigger validation, because none of the controls will allow you to leave it without entering data (part of the questions above). One TextBox and one of the UserControl described below.

 

The little data source class:

    public class Test : System.ComponentModel.INotifyPropertyChanged, System.ComponentModel.IDataErrorInfo
    {
        private int val1 = 0;
        private int? val2 = null;

        public int Val1
        {
            get { return this.val1; }
            set { this.val1 = value; }
        }

        public int? Val2
        {
            get { return this.val2; }
            set { this.val2 = value; }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        #region IDataErrorInfo Members

        public string Error
        {
            get { return String.Empty; }
        }

        public string this[string columnName]
        {
            get 
            {
                if ((columnName == "Val1") && (val1 == 0))
                    return "Val1 cannot be 0";
                if ((columnName == "Val2") && ( (val2 == null) || (val2 == 0) ))
                    return "Val1 cannot be null or 0";
                return String.Empty;
            }
        }

        #endregion
    }
 

The user control just contains a TextBox and an ErrorProvider:

    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
            this.errorProvider1.SetIconAlignment(this.textBox1, ErrorIconAlignment.MiddleRight);
            this.errorProvider1.SetIconPadding(this.textBox1, 2);
            this.errorProvider1.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.BlinkIfDifferentError;
        }

        public string Value
        {
            get { return this.textBox1.Text; }
            set { this.textBox1.Text = value; }
        }

        protected override void OnValidated(EventArgs e)
        {
            MessageBox.Show("!");
            IDataErrorInfo dataErrorInfo = (this.DataBindings["Value"].DataSource as IDataErrorInfo);
            this.errorProvider1.SetError(this.textBox1, dataErrorInfo[this.DataBindings["Value"].BindingMemberInfo.BindingField]);
//            base.OnValidated(e);
        }
 

The Form, as described, one dummy TextBox, one TextBox and one UserControl plus one Button to test Validation by triggering it manually:

    public partial class Form1 : Form
    {
        private Test test = new Test();
        public Form1()
        {
            InitializeComponent();

            this.userControl11.DataBindings.Add("Value", test, "Val2", true);

            this.errorProvider1.SetIconAlignment(this.textBox1, ErrorIconAlignment.MiddleRight);
            this.errorProvider1.SetIconPadding(this.textBox1, 2);
            this.errorProvider1.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.BlinkIfDifferentError;
            this.textBox1.DataBindings.Add("Text", test, "Val2", true);
            this.textBox1.Validated += new EventHandler(textBox1_Validated);
        }

        void textBox1_Validated(object sender, EventArgs e)
        {
            IDataErrorInfo dataErrorInfo = (this.textBox1.DataBindings["Text"].DataSource as IDataErrorInfo);
            this.errorProvider1.SetError(this.textBox1, dataErrorInfo[this.textBox1.DataBindings["Text"].BindingMemberInfo.BindingField]);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.ValidateChildren(ValidationConstraints.Visible);
            MessageBox.Show("Val1: " + test.Val1 + "  Val2: " + test.Val2);
        }
    }
John.Doe  Sunday, December 18, 2005 9:41 PM

Just like usual in Murphy's law... I seemed to have found the right way to bind the value directly after posting here:

new Binding("Text",test, "Val2", true, DataSourceUpdateMode.OnValidation, String.Empty);

It seems to work....

John.Doe  Sunday, December 18, 2005 9:46 PM

Yes, formatingEnable must be at true to allow correct conversion of null value.

The nullValue param is the value you want to be put when it's effectivly null.

OrlanduMike  Tuesday, May 22, 2007 9:35 PM

You can use google to search for other answers

Custom Search

More Threads

• DataGridViewImageCell and Default Error Image
• DataBinding to all values in column of a DataGridView
• DataGridView - Prevent row from being selected at start
• Formatting cells
• Problem with DataGridView Cell Focus
• combobox databinding to display more than one values
• Problems while navigating with a DataGridView
• HOW TO INSERT,DELETE AND UPDATE IN DATABSE THROUTH DATAGRIDVIEW (VISUAL BASIC 2005)
• DataGridView BindingSource filter using a timestamp
• Updating bound Custom entity properties only if the user clicks Ok