views:

1992

answers:

4

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.

+1  A: 

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.

Malfist
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
I don't know, probably not.
Malfist
+4  A: 

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
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
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
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-
+2  A: 

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
+1  A: 

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