Событие ComboBox - SelectionChanged имеет старое значение, а не новое значение - PullRequest
81 голосов
/ 02 июня 2010

C #, .NET 4.0, VS2010.

Новое в WPF. У меня есть ComboBox на моем MainWindow. Я подключил событие SelectionChanged указанного поля со списком. Однако, если я проверю значение поля со списком в обработчике событий, оно будет иметь старое значение. Это больше похоже на событие «SelectionChanging», чем событие SelectionChanged.

Как получить новое значение ComboBox после того, как выбор действительно произошел?

В настоящее время:

this.MyComboBox.SelectionChanged += new SelectionChangedEventHandler(OnMyComboBoxChanged);

...
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string text = this.MyComboBox.Text;
}

Обратите внимание, я получаю то же поведение, если использую объект, передаваемый в аргументах события, например e.OriginalSource.

Ответы [ 15 ]

95 голосов
/ 02 июня 2010

По данным MSDN, e.AddedItems:

Получает список, содержащий элементы, которые были выбраны.

Чтобы вы могли использовать:

private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string text = (e.AddedItems[0] as ComboBoxItem).Content as string;
}

Вы также можете использовать SelectedItem, если используете string значения для Items из sender:

private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string text = (sender as ComboBox).SelectedItem as string;
}

или

private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string text = ((sender as ComboBox).SelectedItem as ComboBoxItem).Content as string;
}

Поскольку Content и SelectedItem являются объектами, более безопасный подход - использовать .ToString() вместо as string

49 голосов
/ 23 июля 2015

Правильное значение для проверки здесь - это свойство SelectedItem .

ComboBox - это составной элемент управления, две части которого:

  1. Текстовая часть : значение в этой части соответствует свойству Text ComboBox.
  2. Селекторная часть (т.е. «раскрывающаяся» часть): выбранный элемент в этой части соответствует свойству SelectedItem .

Expanded ComboBox Parts

Изображение выше было снято сразу после расширения ComboBox (т.е. до выбора нового значения). На этом этапе и Text и SelectedItem являются "Info", предполагая, что элементы ComboBox были строками. Если бы элементы ComboBox были вместо всех значений Enum с именем «LogLevel», SelectedItem в настоящее время будет LogLevel.Info .

Если щелкнуть элемент в раскрывающемся списке, значение SelectedItem изменяется и возникает событие SelectionChanged . Свойство Text еще не обновлено, поскольку Текстовая часть не обновляется до тех пор, пока не закончится обработчик SelectionChanged , Это можно увидеть, поставив точку останова в обработчике и посмотрев на элемент управления:

ComboBox at breakpoint in SelectionChanged handler

Поскольку текстовая часть на данный момент не обновлена, свойство Text возвращает ранее выбранное значение.

46 голосов
/ 27 апреля 2011

Используйте событие DropDownClosed вместо selectionChanged, если требуется текущее значение поля со списком.

private void comboBox_DropDownClosed(object sender, EventArgs e)
{
   MessageBox.Show(comboBox.Text) 
}

Это действительно так просто.

10 голосов
/ 17 ноября 2010

Это сработало для меня:

private void AppName_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
   ComboBoxItem cbi = (ComboBoxItem)AppName.SelectedItem;
   string selectedText = cbi.Content.ToString();
}
5 голосов
/ 13 октября 2015

Это сработало для меня:

private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    var text = ((sender as ComboBox).SelectedItem as ComboBoxItem).Content as string;            
}
2 голосов
/ 27 марта 2017

Следующее событие вызывается для любого изменения текста в ComboBox (когда изменяется выбранный индекс и когда текст также изменяется путем редактирования).

<ComboBox IsEditable="True" TextBoxBase.TextChanged="cbx_TextChanged" />
1 голос
/ 17 апреля 2011
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string newItem = ((DataRowView) e.AddedItems[0]).Row.ItemArray[0].ToString();
}
1 голос
/ 25 августа 2010

Второй вариант не работал для меня, потому что элемент .Text был вне области видимости (C # 4.0 VS2008) Это было мое решение ...

string test = null;
foreach (ComboBoxItem item in e.AddedItems)
{
   test = item.Content.ToString();
   break;
}
0 голосов
/ 07 января 2019

Не усложняйте вещи без причины. Используя свойство SelectedValue, вы можете легко получить выбранное значение ComboBox, например: YourComboBoxName.SelectedValue.ToString ().

За сценой свойство SelectedValue определяется как: SelectedValue {get; set;} это означает, что вы можете использовать его для получения или установки значения ComboBox.

Использование SelectedItem не является эффективным способом получения значения ComboBox, так как требует много разветвлений.

0 голосов
/ 21 апреля 2016
private void indBoxProject_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    int NewProjID = (e.AddedItems[0] as kProject).ProjectID;
    this.MyProject = new kProject(NewProjID);
    LoadWorkPhase();
}

Использование e.AddedItems[0] as kProject, где kProject - это класс, в котором хранятся данные, сработало для меня, поскольку оно по умолчанию использовало RemovedItems [0] до того, как я сделал это явное различие. Спасибо SwDevMan81 за первоначальную информацию, которая ответила на этот вопрос для меня.

...