Recent explorations of WPF have caused me to revisit things I used to avoid in .NET. I’ve spent a lot of time over the past week or so working with the TableLayoutPanel
and FlowLayoutPanel
, and I never really realized how much I dislike the designer for some nitpicky alignment things. I made a relatively complicated application to test myself, and though there’s some lingering issues in Windows Forms 2.0 it looks like WPF solves most of them.
The big thing that has been bugging me is I made a dialog to edit program settings, and when I added the “OK” and “Cancel” buttons I set the form’s AcceptButton
and CancelButton
properties appropriately. However, when I tried the form out, I found that the cancel button worked perfectly but the OK button did nothing. I decided that perhaps I had left something out of my layout logic, so I started a new project and used the designer to set up a simple dialog with a text box and the two buttons; this dialog worked so I figured I’d done something wrong. I decided I’d just make the button’s click event set DialogResult
and left the issue alone.
Then today, someone on the VB .NET forum I frequent posted a problem with the AcceptButton
property that was exactly opposite of mine: they didn’t want the button to respond to the Enter key or close the dialog. I decided that the answer to his question was probably pertinent to mine, so I revisited the example. This time, I managed to do something in the designer that caused the OK button to not work properly. I was mystified, so I asked the guy on the forums to post some of his code so I could try to figure out what was different. The answer turns out to be a combination of the Button
class’s DialogResult
property and an oversight on the part of Microsoft.
I wrote a test program to examine the DialogResult
property before and after assigning buttons to a form’s AcceptButton
and CancelButton
properties. CancelButton
worked exactly as I expected and changed the button’s DialogResult
property to DialogResult.Cancel
. However, AcceptButton
did not alter the button’s DialogResult
property at all. I double-checked this in Reflector and found that the property set method for AcceptButton
doesn’t do anything at all with the button’s DialogResult
property.
So if you are having trouble with getting the OK button of a dialog to work, and the only step you are taking is to set the form’s AcceptButton
property, be sure to always manually set the button’s DialogResult
property. AcceptButton
‘s property set method does call UpdateDefaultButton
, a protected method of Form
with no default implementation. It’s possible you could override this method and add the line:
this.AcceptButton.DialogResult = DialogResult.OK
However, since it’s a protected method that is used by the default implementations of the Form
class it’s probably a bad idea to assume this will always work. In particular, if they swap the order of the lines of code it will fail. Perhaps you could override the AcceptButton
property and call the base implementation, but that’s still kind of icky. I have not tested this in .NET versions later than 2.0, but I doubt it has been fixed.