Is there a BeforeUpdate for a C# ComboBox on a Winform
Asked Answered
A

5

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.

Adown answered 8/1, 2009 at 17:56 Comment(0)
N
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.

Nasser answered 8/1, 2009 at 18:26 Comment(4)
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.Adown
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.Foret
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?Mattheus
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.Rangy
H
12

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;
    }
  }
}
Happy answered 8/1, 2009 at 18:28 Comment(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.Homosexuality
Ditto - liked this approach better.Besant
Best helper class. I wanted mPrevIndex value in 'BeforeUpdate event' so I added a class level method : " public int PrevIndex() { return mPrevIndex; } "Wilbourn
N
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.

Nasser answered 8/1, 2009 at 18:26 Comment(4)
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.Adown
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.Foret
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?Mattheus
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.Rangy
K
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.

Knesset answered 8/1, 2009 at 17:59 Comment(1)
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?Adown
L
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;
        }
Lunsford answered 8/1, 2009 at 18:28 Comment(0)
R
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.

Rangy answered 16/11, 2011 at 0:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.