Why would I get a format exception when updating a boolean binding with WriteValue?
Asked Answered
H

4

13

I have a bunch of Checkboxes on my form with their Checked properties bound to Boolean properties on the data model:

chk1.DataBindings.Add(new BindingValue(this, "Checked", "MyBooleanProperty1", false))
chk2.DataBindings.Add(new BindingValue(this, "Checked", "MyBooleanProperty2", false))
chk3.DataBindings.Add(new BindingValue(this, "Checked", "MyBooleanProperty3", false))

There is also a shared event handler for all checkboxes on the screen that ensures the databound value is correctly set to the checked value.

private void AllCheckboxes_CheckedChanged(object sender, EventArgs e)
{
    var chk = ((CheckBox)sender);

    var binding = chk.DataBindings["Checked"];
    if (binding != null)
        binding.WriteValue();
}

In some cases, the first time this form and the bindings are loaded, I get an exception :

Cannot format the value to the desired type.

at System.ComponentModel.ReflectPropertyDescriptor.SetValue(Object component, Object value) at System.Windows.Forms.BindToObject.SetValue(Object value) at System.Windows.Forms.Binding.PullData(Boolean reformat, Boolean force) at System.Windows.Forms.Binding.WriteValue()

It works correctly for the first checkbox to process the event, but then the second one will throw this exception.

The data source is an interface of my datamodel

public interface IMyDataModel
{
    bool MyBooleanProperty1 { get; set; }
    bool MyBooleanProperty2 { get; set; }
    bool MyBooleanProperty3 { get; set; }
}

And I can verify that the data model itself is set correctly by setting a breakpoint right before the .WriteValue in the event handler. I can even put a breakpoint in the setter of the bound boolean property, and it is also called correctly.

If I set the FormattingEnabled property of the binding to true, it does fix the issue. But I am wondering why I even have to do that in the first place, since I am binding a System.Boolean property in the UI object to a bool property on the data source.

Why would I be getting this exception in this case?

Hamper answered 19/6, 2015 at 15:46 Comment(6)
have you enabled IsThreeState property?Recountal
No, IsThreeState is not setHamper
I would try to set IsThreeState or make your binding to nullable bool. I understand this doesn't look like a null binding issue, but I expect to have null handling in checkboxes.Recountal
Any real reproducing code? What's BindingValue?Sd
@SimonMourier You're right, I can't reproduce this easily in a test project. I'll work on adding pieces a bit at a time and see if I can identify what's causing this exception. BindingValue is a custom class that contains properties that is used to create the Binding in our code's infrastructure.Hamper
This error can be thrown far from the problem (and with little indication of where to look). The last time I ran into this error was when I was binding a nullable image to a picturebox. This might be relevent - #9885417Bellicose
V
1

It's difficult to say for sure what's going on without a way to reproduce the issue.

But at least I can explain why setting FormattingEnabled makes the exception go away:

http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Binding.cs,853

WriteData calls PullData with reformat = true and force = true.

From your call stack, it looks like you must be making it into this block:

            // Put the value into the data model
            if (!parseFailed) {
                this.bindToObject.SetValue(parsedValue);
            }

Immediately following that, the exception is rethrown unless FormattingEnabled = true. So setting FormattingEnabled here hides the problem, since it seems Binding assumes that you're going to handle any formatting/parsing issues it's found so far yourself.

As for why the exception is thrown in the first place... I don't know. Nothing is obvious looking here:

http://referencesource.microsoft.com/#system/compmod/system/componentmodel/ReflectPropertyDescriptor.cs,1138

I'd be curious to know if your problem persists if you find a way to add your data bindings without your BindingValue custom class. I'd also be curious if you have any listeners wired up in BindingValue.

Velda answered 24/6, 2015 at 23:41 Comment(1)
Thank you for the code links, those help. I have narrowed down the problem to something caused by our internal change notification code in the get/set of the property. Using a regular generic get; set; does not cause the exception. I'm awarding you the bounty because the MSDN code links provide the best explanation as to why I'm getting the error and suggest where it could be from, so I'll continue to debug in that direction later on when I have more time. Thank you.Hamper
P
0

I think it throws an exception if parse/format is not being handled, which is why formattingEnabled seems to work.

Try handling the Binding.Format and Binding.Parse events to verify that the types it sends (and expects) are correct.

Paulo answered 28/6, 2015 at 8:1 Comment(1)
Both those events correctly show the e.DesiredType and e.Value to be a System.Boolean. They also appear to both get hit correctly without any exceptions.Hamper
L
0

This is what I would do. The model should implement the INotifyPropertyChanged interface. Add a BindingSource to your form from the ToolBox. Set the DataSource of it to your model. On each checkbox set the data binding. I'd use the Advanced window and set the Data Source Update Mode to OnPropertyChanged. In this case you do not have to set any event handler for your check boxes.

Lebensraum answered 28/6, 2015 at 23:0 Comment(1)
In a better world I would use INotifyPropertyChanged, however I don't have control over the application infrastructure in this case and cannot change it without a lot of hassle. Also, I'm looking for an answer about why this is occurring, not for potential fixes.Hamper
E
0

Try by enabling the formatting as follows-

this.chk1.DataBindings.Add(new System.Windows.Forms.Binding("EditValue", this.bindingSource1, "MyProperty", true));

You can also go through the following link-

http://msdn.microsoft.com/en-us/library/system.windows.forms.binding.formattingenabled.aspx

Elspet answered 29/6, 2015 at 11:48 Comment(1)
As I already said in my question, I know enabling the formatting will "fix" it, but I want to know what is causing the problem in the first place.Hamper

© 2022 - 2024 — McMap. All rights reserved.