3

I come from the VBA world, and remember there was a BeforeUpdate call I could make on a combobox. Now I am in C# (and loving it) and I was wondering is there a BeforeUpdate call for a ComboBox on a Winform?

I can make an invisible textbox and store the info I need there and after the update, look at that box for what I need, but I was hoping there was a simplier solution.

Jeff Yates
  • 61,417
  • 20
  • 137
  • 189
Matt
  • 1,862
  • 2
  • 17
  • 19

5 Answers5

11

One of the goodies of WF is that you can easily make your own. Add a new class to your project and paste the code below. Compile. Drop the new control from the top of the toolbox onto your form. Implement the BeforeUpdate event.

using System;
using System.ComponentModel;
using System.Windows.Forms;

public class MyComboBox : ComboBox {
  public event CancelEventHandler BeforeUpdate;

  public MyComboBox() {
    this.DropDownStyle = ComboBoxStyle.DropDownList;
  }

  private bool mBusy;
  private int mPrevIndex = -1;

  protected virtual void OnBeforeUpdate(CancelEventArgs cea) {
    if (BeforeUpdate != null) BeforeUpdate(this, cea);
  }

  protected override void OnSelectedIndexChanged(EventArgs e) {
    if (mBusy) return;
    mBusy = true;
    try {
      CancelEventArgs cea = new CancelEventArgs();
      OnBeforeUpdate(cea);
      if (cea.Cancel) {
        // Restore previous index
        this.SelectedIndex = mPrevIndex;
        return;
      }
      mPrevIndex = this.SelectedIndex;
      base.OnSelectedIndexChanged(e);
    }
    finally {
      mBusy = false;
    }
  }
}
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 3
    NICE. This helper class has not gotten enough attention. Canceling the event works great. You can also literally copy and paste this code into a blank code file, build the project, and it will show up as a control in the toolbox. – oscilatingcretin May 31 '11 at 17:27
  • Ditto - liked this approach better. – Samik R Oct 02 '12 at 22:26
5

You may consider SelectionChangeCommited.

From MSDN:

SelectionChangeCommitted is raised only when the user changes the combo box selection. Do not use SelectedIndexChanged or SelectedValueChanged to capture user changes, because those events are also raised when the selection changes programmatically.

This won't work when you have set your combobox to allow the user to type in the textbox though. Also, it won't tell you what the 'last' selected item was. You will have to cache this information. However, you don't need to store your information in a textbox. You can use a string.

Matt Brunell
  • 10,141
  • 3
  • 34
  • 46
  • In this particular combobox I do want to run the event when it is progrmatically changed, but I do have other spots where I don't so I am grateful for you pointing me to SelectionChangeCommited. It will really help me. – Matt Jan 08 '09 at 18:34
  • There is an issue with SelectionChangeCommitted. If you dropdown the list, mouse over or mouse to a different selection, and use Tab to make the selection, SelectionChangeCommitted will not be called. This could cause problems if you don't also catch the change in the Validated event. – Chris Porter Apr 22 '09 at 14:35
  • Just checked for that issue in VS2005 WinForm and found that tabbing does not make the selection at all, in which case it makes sense that SelectionChangeCommitted would not fire. Is this behaviour consistent? – G-. Apr 28 '09 at 13:14
  • If you drop down the list, change the selection with the cursor/arrow keys, and then click elsewhere, the list is no longer dropped down, but SelectionChangeCommitted does not get called. – Jeff Roe Nov 15 '11 at 23:50
1

You could try ValueMemberChanged, Validating, SelectedIndexChanged, or TextChanged. They don't fire like the BeforeUpdate, but you can look at what will be updated and handle the updated, or refuse it.

Jeff Yates
  • 61,417
  • 20
  • 137
  • 189
Malfist
  • 31,179
  • 61
  • 182
  • 269
  • Will it tell me what the value was before the update happened? Or is there a call I can make to find that info out? – Matt Jan 08 '09 at 18:06
1

Out of the box, there's nothing like that. All of the events that deal with change in the combo box happen after the new value is already selected. At that point there's no way to tell what the value USED to be. You're best bet is what you eluded to. As soon as your ComboBox is populated save the SelectedItem to a temporary variable. Then, hook into the SelectedValueChanged event. At that point, your temporary variable will be your old value, and the SelectedItem will be your current value.

private object oldItem = new object();

        private void button3_Click(object sender, EventArgs e)
        {
            DateTime date = DateTime.Now;
            for (int i = 1; i <= 10; i++)
            {
                this.comboBox1.Items.Add(date.AddDays(i));
            }

            oldItem = this.comboBox1.SelectedItem;
        }

        private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
        {
            //do what you need with the oldItem variable
            if (oldItem != null)
            {
                MessageBox.Show(oldItem.ToString());
            }

            this.oldItem = this.comboBox1.SelectedItem;
        }
BFree
  • 102,548
  • 21
  • 159
  • 201
0

I think what you wanted was the DropDown event. It will tell you what the value is before the user changes it. However, the user may end up not changing anything, so it's not exactly the same as BeforeUpdate.

Jeff Roe
  • 3,147
  • 32
  • 45