none
Problem with bindable attribute in custom control RRS feed

  • Question

  • I have a class (BindTestClass) that inherits from ComboBox and has a public string as a property of the class (BindableString). This string is bindable, so I can bind it in design time to a datasource.

    public class BindTestClass: ComboBox
      {
        private string _bindableString;
        [Bindable(true)]
        public string BindableString
        {
          get { return _bindableString; }
          set
          {
            if (value != _bindableString)
              _bindableString = value;
              
          }
        }
      }

    This is used as a control inside a form that has some text boxes binded to the same data source, but to different fields. All the controls in the form use a binding source as datasource, and the binding source has the actual dataset and datamember declared on it.

    When I hit save, the first thing to do is call BindingSource.CurrencyManager.EndCurrentEdit(). This is needed to guarantee that all the controls flush their changes before checking if the dataset has changes. There could be a case when the user edits something in one of the controls and, since the save button is a toolbar button, when hitting save, the last control modified never loses focus, then, never flushes the last changes.

    My problem is that right after EndCurrentEdit is called, even if I didn't touched anything, the dataset reports that there are changes. The chages appear to be in the field binded to the BindableString property of BindTestClass. The weird thing is that if instead of binding BindableString to the datasource, I bind the text property that I inherited from ComboBox, when EndCurrentEdit is called with a form with no changes, the dataset doesn't report any changes.

    So, my theory is that inside of ComboBox, something is done besides declaring the text property as Bindable. And that something is missing from my class, but I just can't find what that is.

    All help will be greatly appreciated.
    Thursday, September 28, 2006 3:55 AM

Answers

  • Figured myself. It was pretty simple

    The only thing that needs to be done is implement the interface INotifyChanges and raise the event PropertyChanged. Below is the solution, compare it to the previous post to see the differences

     

        public class BindTestClass: ComboBox , INotifyPropertyChanged
        {
            private string _bindableString;
            [Bindable(true)]
            public string BindableString
            {
                get { return _bindableString; }
                set
                {
                    if (value != _bindableString)
                    {
                        _bindableString = value;
                        Notifychanges("BindableString");
                    }                   
                }
            }

            public event PropertyChangedEventHandler PropertyChanged;

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

    Friday, September 29, 2006 2:44 PM