private object data_source;
private string data_member;
- private string row_name;
- private string col_name;
-
private BindingMemberInfo binding_member_info;
private Control control;
private BindingManagerBase manager;
- private PropertyDescriptor prop_desc;
+ private PropertyDescriptor control_property;
private PropertyDescriptor is_null_desc;
- private EventDescriptor changed_event;
- private EventHandler property_value_changed_handler;
- private object event_current; // The manager.Current as far as the changed_event knows
-
private object data;
private Type data_type;
data_source = dataSource;
data_member = dataMember;
binding_member_info = new BindingMemberInfo (dataMember);
-
- int sp = data_member.IndexOf ('.');
- if (sp != -1) {
- row_name = data_member.Substring (0, sp);
- col_name = data_member.Substring (sp + 1, data_member.Length - sp - 1);
- }
}
#endregion // Public Constructors
if (control == this.control)
return;
- prop_desc = TypeDescriptor.GetProperties (control).Find (property_name, true);
-
- if (prop_desc == null)
+ control_property = TypeDescriptor.GetProperties (control).Find (property_name, true);
+
+ if (control_property == null)
throw new ArgumentException (String.Concat ("Cannot bind to property '", property_name, "' on target control."));
- if (prop_desc.IsReadOnly)
+ if (control_property.IsReadOnly)
throw new ArgumentException (String.Concat ("Cannot bind to property '", property_name, "' because it is read only."));
- data_type = prop_desc.PropertyType; // Getting the PropertyType is kinda slow and it should never change, so it is cached
+ data_type = control_property.PropertyType; // Getting the PropertyType is kinda slow and it should never change, so it is cached
control.Validating += new CancelEventHandler (ControlValidatingHandler);
this.control = control;
- control.DataBindings.Add (this);
}
internal void Check (BindingContext binding_context)
if (control == null || control.BindingContext == null)
return;
- string member_name = data_member;
- if (row_name != null)
- member_name = row_name;
-
- Console.WriteLine ("data source {0} member name: {1}",
- data_source, member_name);
- manager = control.BindingContext [data_source, member_name];
+ manager = control.BindingContext [data_source, data_member];
manager.AddBinding (this);
manager.PositionChanged += new EventHandler (PositionChangedHandler);
-
- WirePropertyValueChangedEvent ();
+ manager.CurrentChanged += new EventHandler (CurrentChangedHandler);
is_null_desc = TypeDescriptor.GetProperties (manager.Current).Find (property_name + "IsNull", false);
- PullData ();
+ PushData ();
}
- internal void PushData ()
+ internal void PullData ()
{
- if (IsBinding == false)
+ if (IsBinding == false || manager.Current == null)
return;
- data = prop_desc.GetValue (control);
- data = FormatData (data);
+ data = control_property.GetValue (control);
SetPropertyValue (data);
}
- internal void PullData ()
+ internal void PushData ()
{
- if (IsBinding == false || manager.Current == null)
+ if (manager == null || manager.IsSuspended || manager.Current == null)
return;
if (is_null_desc != null) {
}
}
- if (row_name != null && col_name != null) {
- PropertyDescriptor pd = TypeDescriptor.GetProperties (manager.Current).Find (col_name, true);
- object pulled = pd.GetValue (manager.Current);
- data = ParseData (pulled, pd.PropertyType);
- } else if (data_member != null) {
- PropertyDescriptor pd = TypeDescriptor.GetProperties (manager.Current).Find (data_member, true);
- object pulled = pd.GetValue (manager.Current);
- data = ParseData (pulled, pd.PropertyType);
+ PropertyDescriptor pd = TypeDescriptor.GetProperties (manager.Current).Find (binding_member_info.BindingField, true);
+ if (pd == null) {
+ data = ParseData (manager.Current, manager.Current.GetType ());
} else {
- object pulled = manager.Current;
- data = ParseData (pulled, pulled.GetType ());
+ data = ParseData (pd.GetValue (manager.Current), pd.PropertyType);
}
data = FormatData (data);
internal void UpdateIsBinding ()
{
- PullData ();
+ PushData ();
}
private void SetControlValue (object data)
{
- prop_desc.SetValue (control, data);
+ control_property.SetValue (control, data);
}
private void SetPropertyValue (object data)
{
- string member_name = data_member;
- if (col_name != null)
- member_name = col_name;
- PropertyDescriptor pd = TypeDescriptor.GetProperties (manager.Current).Find (member_name, true);
+ PropertyDescriptor pd = TypeDescriptor.GetProperties (manager.Current).Find (binding_member_info.BindingField, true);
if (pd.IsReadOnly)
return;
+ data = ParseData (data, pd.PropertyType);
pd.SetValue (manager.Current, data);
}
- private void CurrentChangedHandler ()
- {
- if (changed_event != null) {
- changed_event.RemoveEventHandler (event_current, property_value_changed_handler);
- WirePropertyValueChangedEvent ();
- }
- }
-
- private void WirePropertyValueChangedEvent ()
- {
- if (manager.Current == null)
- return;
- EventDescriptor changed_event = TypeDescriptor.GetEvents (manager.Current).Find (property_name + "Changed", false);
- if (changed_event == null)
- return;
- property_value_changed_handler = new EventHandler (PropertyValueChanged);
- changed_event.AddEventHandler (manager.Current, property_value_changed_handler);
-
- event_current = manager.Current;
- }
-
- private void PropertyValueChanged (object sender, EventArgs e)
+ private void CurrentChangedHandler (object sender, EventArgs e)
{
- PullData ();
+ PushData ();
}
private void ControlValidatingHandler (object sender, CancelEventArgs e)
{
- PullData ();
+ object old_data = data;
+
+ // If the data doesn't seem to be valid (it can't be converted,
+ // is the wrong type, etc, we reset to the old data value.
+ try {
+ PullData ();
+ } catch {
+ data = old_data;
+ SetControlValue (data);
+ }
}
private void PositionChangedHandler (object sender, EventArgs e)
{
- PullData ();
+ PushData ();
}
private object ParseData (object data, Type data_type)