Search code examples
c#messagebox

MessageBox without a default button


I have a form in my application where users can enter a list of serial numbers, each to be subjected to a quick check and then added to a list (this is for a stock take module). So the users typically use barcode scanners to scan the serial numbers from a pile of stock items.

I'm handling the KeyPress event of the TextBox that has focus while the users are scanning items and look for e.KeyChar == 13 (the enter key). Whenever enter is pressed, I know that I have a complete serial number which I can then validate before adding it to the list.

Here's where my problem occurs; Under certain conditions, I have to prompt the user at this point on whether he really wants the stock item added to the list or not. I'm using a MessageBox for that, like so:

if (MessageBox.Show("This is a special stock item.\r\nDo you want to add it to the list?", "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
   // Add item to list
else
   // Do not add item to list

But because this is something that only happens occasionally, the users often don't even see the MessageBox and simply scans the next serial number, which gets lost of course but which ends with an enter key, which fires the default button on the MessageBox and without having intended to do so, and sometimes not even aware that it's happened, the user adds an item to the list and misses a subsequent item.

Is there a way I can prevent the MessageBox from firing any buttons if enter is pressed? I don't mind if the user goes on scanning barcode after barcode and losing them all, as long as the MessageBox remains on screen until he realises his attention is required and deliberately select one of the two options.


Solution

  • Is there a way I can prevent the MessageBox from firing any buttons if enter is pressed?

    No.

    I don't mind if the user goes on scanning barcode after barcode and losing them all, as long as the MessageBox remains on screen until he realises his attention is required and deliberately select one of the two options.

    Use the YesNoCancel option, and set the default to Button3, which will be the Cancel button. Now keep looping while the result is Cancel. When the loop drops out, the user will have selected either Yes or No:

            DialogResult result;
            do
            {
                result = MessageBox.Show("This is a special stock item.\r\nDo you want to add it to the list?", "Confirmation", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button3);
            } while (result == DialogResult.Cancel);
    
            if (result == DialogResult.Yes)
            {
                // yes
    
            }
            else
            {
                // no
    
            }
    

    ---------- Edit ----------

    I'm not overly fond of the idea of having a button on the dialog that means nothing other than for some obscure application logic (from the user's perspective).

    Agreed...having a "noop" button isn't optimal. The solution above is a quick and dirty "fix".

    When you get around to implementing your own custom MessageBox Form, here's an easy way to make it ignore the Enter key whenever a Button is currently focused:

    public partial class frmVerify : Form
    {
    
        public frmVerify()
        {
            InitializeComponent();
        }
    
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Enter && this.ActiveControl is Button)
            {
                return true; // suppress the keystroke
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }
    
        // ... more code ...
    
    }