Monday, August 3, 2009

Using Yes/No or OK/Cancel Buttons

I see a great many people mistakenly using MessageBoxButtons.YesNo buttons when they are prompting the user for confirmation. In that case you should be using MessageBoxButtons.OKCancel buttons. Think of it like this: if the user asked you to do something and you're asking for confirmation then you should always use OKCancel.

To show the difference, consider the situation where the user closes a form with unsaved changes pending. You might use the following code to prompt the user to either close the form and lose the changes or keep the form open:

C#

if (MessageBox.Show("Are you sure you want to close?  " +
                    "If you do so will lose any pending changes",
                    "Confirm Close",
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Warning) == DialogResult.No)
{
    // Cancel close here.
}

VB

If MessageBox.Show("Are you sure you want to close?  " & _
                   "If you do so you will lose any pending changes", _
                   "Confirm Close", _
                   MessageBoxButtons.YesNo, _
                   MessageBoxIcon.Warning) = Windows.Forms.DialogResult.No Then
    'Cancel close here.
End If
That would be incorrect though. The correct code would be:

C#

if (MessageBox.Show("Are you sure you want to close?  " +
                    "If you do so will lose any pending changes",
                    "Confirm Close",
                    MessageBoxButtons.OKCancel,
                    MessageBoxIcon.Warning) == DialogResult.Cancel)
{
    // Cancel close here.
}

VB

If MessageBox.Show("Are you sure you want to close?  " & _
                   "If you do so you will lose any pending changes", _
                   "Confirm Close", _
                   MessageBoxButtons.OKCancel, _
                   MessageBoxIcon.Warning) = Windows.Forms.DialogResult.Cancel Then
    'Cancel close here.
End If
To see why, consider what would happen if you wanted to expand the choices and prompt the user to either save and close, close without saving or not close at all. In that case you'd use this code:

C#

switch (MessageBox.Show("Are you sure you want to close?  " +
                        "If you do so will lose any pending changes",
                        "Confirm Close",
                        MessageBoxButtons.YesNoCancel,
                        MessageBoxIcon.Warning))
{
    case DialogResult.Yes:
        // Save changes and allow close.
        break;
    case DialogResult.No:
        // Allow close.
        break;
    case DialogResult.Cancel:
        // Cancel close here.
        break;
}

VB

Select Case MessageBox.Show("Are you sure you want to close?  " & _
                            "If you do so you will lose any pending changes", _
                            "Confirm Close", _
                            MessageBoxButtons.YesNoCancel, _
                            MessageBoxIcon.Warning)
    Case Windows.Forms.DialogResult.Yes
        'Save changes and allow close.
    Case Windows.Forms.DialogResult.No
        'Allow close.
    Case Windows.Forms.DialogResult.Cancel
        'Cancel close here.
End Select
Comparing that to the first code example, notice that the meanings of the Yes and No buttons have now changed. Previously Yes meant close without saving and now it means save and close. Previously No meant don't close and now it means close without saving, which is what Yes meant before. Now Cancel means don't close, which is what No meant before. Do you see the inconsistency?

Now, consider the third case compared to the second. Previously Cancel meant don't close and it still does. Previously the OK option meant close and now it has been replaced by two new options, Yes and No, both of which still mean close but add the option of either saving first or not saving.

To generalise, if you are asking the user "do you really want to do what you just asked for" then you use an OK button and if you're asking "would you rather not do what you just asked for" then you use a Cancel button, hence MessageBoxButtons.OKCancel is the correct choice when asking for straight confirmation. When you want to break that first question into two: "do you want to do what you asked for and do this extra thing as well" and "do you want to do just what you asked and not anything extra", then you would use MessageBoxButtons.YesNoCancel. There are plenty of situations where the use of MessageBoxButtons.YesNo is appropriate but confirming an action is not one of them.

2 comments:

Anonymous said...

I think you have spell error in above example (Using Yes/No or OK/Cancel Buttons):
c#
msgbox...OKCancel => If DialogResult.No?
Error= NO on OK&CANCEL msgbox.

Zeljko from vbforums.com

jmcilhinney said...

Thanks Zeljko. Fixed that.