BUG: Binding My.Settings property to ToolStripMenuItem.Checked fails

Found a Visual Studio 2005 designer bug today, which prevents you from binding the ToolStripMenuItem.Checked property to an Application Setting.

Apologies in advance if someone's already reported this, but I couldn't find any info on the web (though I did find a few posts from confused programmers suffering from its symptoms!)

Below is more information and detailed steps to reproduce the bug.

Description:

If you try to bind to ToolStripMenuItem.Checked, and set the default value for this binding to True, then any changes made to the value at runtime will not persist.

The result is that you can only bind to a ToolStripMenuItem's Checked property if you leave its default value at False during the design time (in both the Properties window and the Application's "Settings" page).

Reproducing:

1) Create a ToolStripMenuItem
a) Open a new standard WindowsApplication project.
b) Drag a ToolStrip control onto the form.
c) Add a DropDownButton
d) Underneath it, add a MenuItem (called ToolStripMenuItem1)

2) Bind the Checked property to a new Application Setting
a) Right-click ToolStripMenuItem1, click Properties.
b) In the properties window, open (ApplicationSettings) - it's under Data if you're in Categorized view - then select (PropertyBinding) and hit the ellipsis (...) button.
c) Scroll up to and select Checked, then press the dropdown and click New.
d) Give the new setting a name, e.g. TestSetting
e) Change the default value to True.
f) Press Ok twice.

3) Allow toggle checkmark to be toggled
a) In the properties for ToolStripMenuItem1, set CheckOnClick to True.  (Alternatively, you could add code in the click handler to do this manually - it doesn't make a difference for our purposes)

4) Run the program.
a) Run the program (F5).
b) Drop down the menu and click the item to uncheck the box.  You can drop down the menu again to confirm its been unchecked.
c) Close the program and run it again.
d) You'll see the change was not persisted!

Cause:

If you look in the code-behind file for your form (i.e. open Form1.Designer.vb), you'll see that something like the following has been generated:

'ToolStripMenuItem1
'
Me.ToolStripMenuItem1.Checked = Global
.WindowsApplication2.My.MySettings.Default.TestSetting

Me.ToolStripMenuItem1.CheckState = System.Windows.Forms.CheckState.Checked

The first line sets the ToolStripMenuItem's Checked property according to your settings file, the way we want it to.

However, the next line overwrites this value.

The offending second line was put in by the designer when we changed the default for the Checked property to true - because doing so resulted in the CheckState property being set to a non-default value.

Workaround:

Probably the easiest way to workround the problem is simply to avoid binding to the Checked property.  You can acheive the same effect by manually controlling the setting, with code like the following:

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e _
    
As System.EventArgs) Handles MyBase.Load
        ToolStripMenuItem1.Checked =
My.Settings.TestSetting
    End Sub

    Private Sub ToolStripMenuItem1_Click(ByVal sender _
    As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem1.Click
        ToolStripMenuItem1.Checked = Not ToolStripMenuItem1.Checked
        My.Settings.TestSetting = ToolStripMenuItem1.Checked
   
End Sub

You can listen on the CheckedChanged event instead, but it's a little bit more complicated (since this property can change during initialization, and you want to avoid saving the setting before you've loaded it at least once).

Conclusion:

This is what happens when you let computers generate code, and form complex systems without thinking everything through from 10 different directions.  It's a classic case of the left hand not knowing what the right hand is doing.

-Richardk

(p.s. Off-topic rant: I wish this forum would adopt a decent rich text editor, like FCKeditor.  Those letters aren't a swearword, they're the initials of the authour.  I tried a lot of RTE's and it's certainly the best - a lot more robust than this P.O.S!)




Answer this question

BUG: Binding My.Settings property to ToolStripMenuItem.Checked fails

  • Mani Govindan

    It's funny. I'm using VB.2005 Express, and Mine doesn't create the second line in the designer, it just doesn't work.
    The workaround of course does. Thanks.



  • Glenn Davis

    Richardk wrote:

    If you look in the code-behind file for your form (i.e. open Form1.Designer.vb), you'll see that something like the following has been generated:

    'ToolStripMenuItem1
    '
    Me.ToolStripMenuItem1.Checked = Global
    .WindowsApplication2.My.MySettings.Default.TestSetting

    This code will load the setting, but what is missing is the code to load the setting. The regular version of the ToolStrip item controls (Button, TextBox....) have a DataBindings property (they impliment IBinding). The ToolStrip items do not.
    If you PropertyBind a regular TextBox, or in your case, a CheckBox, it will work as expected. But as you've pointed out, the ToolStrip variety does not.
    Although your fix works, I have found another that I think is a little better. In the dispose method of the code-behind file there is no generated code to save the ToolStrip items settings. All you need to do is add the code to save the settings and everything will work fine.

  • BUG: Binding My.Settings property to ToolStripMenuItem.Checked fails