none
Is binding a CheckBox CheckState property to a nullable boolean typed DbColumn a hack ? RRS feed

  • General discussion

  • I have had some problems binding a CheckBox to a boolean typed DbColumn that is nullable (because of the DBNull value handling). I have asked this question elsewhere and have had a satisfactory answer, but somebody came with a solution that works but seems too much of a hack to me : bind the CheckState property to the boolean typed DbColumn. Which means binding an enumerated value to a boolean. The problem is that it really works !

    So my question is : does it work because it was meant to (and do you have more insight on this feature), or is it just a lucky hack ?
    Friday, August 21, 2009 9:20 AM

All replies

  • Hello

    Thanks for your post.

    As the Binding class's constructor have a argument that allow us to enable or disable formatting. See:

    http://msdn.microsoft.com/en-us/library/38zwt0w0.aspx

    If we enable the formatting(set to true), binding object will format the DBNull when the control(CheckBox) need to read the value. The folllowing is the call stack when the formatting is disable(checkBox.DataBindings.Add("CheckState", table, "MyColumn", false);).

    System.InvalidCastException: Invalid cast from 'System.DBNull' to 'System.Windows.Forms.CheckState'.
       at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
       at System.DBNull.System.IConvertible.ToType(Type type, IFormatProvider provider)
       at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
       at System.Windows.Forms.Binding.FormatObject(Object value)
       at System.Windows.Forms.Binding.PushData(Boolean force)
       at System.Windows.Forms.Binding.UpdateIsBinding()
       at System.Windows.Forms.Binding.CheckBinding()
       at System.Windows.Forms.Binding.SetListManager(BindingManagerBase bindingManagerBase)
       at System.Windows.Forms.ListManagerBindingsCollection.AddCore(Binding dataBinding)
       at System.Windows.Forms.BindingsCollection.Add(Binding binding)
       at System.Windows.Forms.BindingContext.UpdateBinding(BindingContext newBindingContext, Binding binding)
       at System.Windows.Forms.Control.UpdateBindings()
       at System.Windows.Forms.Control.OnBindingContextChanged(EventArgs e)
       at System.Windows.Forms.Control.OnParentBindingContextChanged(EventArgs e)
       at System.Windows.Forms.Control.OnBindingContextChanged(EventArgs e)
       at System.Windows.Forms.Control.set_BindingContextInternal(BindingContext value)
       at System.Windows.Forms.ContainerControl.set_BindingContext(BindingContext value)
       at System.Windows.Forms.ContainerControl.get_BindingContext()
       at System.Windows.Forms.Control.get_BindingContextInternal()
       at System.Windows.Forms.Control.get_BindingContext()
       at System.Windows.Forms.Control.UpdateBindings()
       at System.Windows.Forms.Control.OnBindingContextChanged(EventArgs e)
       at System.Windows.Forms.Control.OnParentBindingContextChanged(EventArgs e)
       at System.Windows.Forms.Control.OnBindingContextChanged(EventArgs e)
       at System.Windows.Forms.ContainerControl.OnCreateControl()
       at System.Windows.Forms.Form.OnCreateControl()
       at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
       at System.Windows.Forms.Control.CreateControl()
       at System.Windows.Forms.Control.WmShowWindow(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       at System.Windows.Forms.ContainerControl.WndProc(Message& m)
       at System.Windows.Forms.Form.WmShowWindow(Message& m)
       at System.Windows.Forms.Form.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


    Thanks
    Rong-Chun Zhang
    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Friday, August 21, 2009 10:57 AM
  • Having a look with .NET Reflector into the Binding class, it seems that at some point some formatting occurs even when formatting is disabled (but of a different kind). The method responible for this is : 
    private object FormatObject(object value)
    For me, the exception thrown when formatting is disabled is what I would expect in any case ! What happens in the formatting process that makes the transition between :
    public enum CheckState
    {
        Unchecked,
        Checked,
        Indeterminate
    }
    and a nullable DbColumn of type System.Boolean possible ? More specifically, why in the world can CheckState.Indeterminate (2 in its underlying type) be mapped to DBNull.Value back and forth when formatting is enabled ?


    As a side note, it seems that when using the designer for databinding (I checked in the generated code), formatting is enabled.
    Friday, August 21, 2009 2:54 PM
  • Delving further into the code (led by Alfred Myers), it appears that formatting involves the internal System.Windows.Forms.Formatter class, or more specifically the FormatObjectInternal static method. This method contains these gems :

    if ((value == DBNull.Value) || (value == null))
    {
        if (targetType == checkStateType)
        {
            return CheckState.Indeterminate;
        }
    }

    and
    if (targetType == checkStateType)
    {
        if (type == booleanType)
        {
            return (((bool) value) ? CheckState.Checked : CheckState.Unchecked);
        }
    }
    

    So it appears that this is a feature : you can specifically bind a CheckState enumeration to a boolean type, as long as formatting is enabled. I believe this this should be documented somewhere...
    Monday, August 24, 2009 6:33 AM
  • Hello Mathieu,

    Thanks for your effort. I will log this into our product database.

    Thanks,
    Rong-Chun Zhang
    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Monday, August 24, 2009 9:37 AM