104

C#、.NET 4.0、VS2010。

WPF 的新手。我的 MainWindow 上有一个 ComboBox。我挂钩了所述组合框的 SelectionChanged 事件。但是,如果我检查事件处理程序中组合框的值,它具有旧值。这听起来更像是“SelectionChanged”事件,而不是 SelectionChanged 事件。

选择实际发生后,如何获得 ComboBox 的新值?

目前:

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

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

请注意,如果我使用在事件 args 中传递的对象 egeOriginalSource,我会得到相同的行为。

4

17 回答 17

117

根据 MSDN e.AddedItems,:

获取包含已选择项目的列表。

所以你可以使用:

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

SelectedItem如果您使用from 的string值,您也可以使用:Itemssender

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

于 2010-06-02T19:57:20.983 回答
73

此处要检查的正确值是SelectedItem属性。

ComboBox 是一个复合控件,它的两个部分是:

  1. 文本部分:这部分中的值对应于组合框的文本属性。
  2. Selector Part(即“下拉”部分):该部分中的选中项对应SelectedItem属性。

扩展的 ComboBox 部件

上图是在 ComboBox 展开后立即拍摄的(即在选择新值之前)。此时TextSelectedItem都是“Info”,假设 ComboBox 项是字符串。如果 ComboBox 项是名为“LogLevel”的枚举的所有值,则SelectedItem当前将为LogLevel.Info

当单击下拉列表中的某个项目时,SelectedItem的值会发生更改并引发SelectionChanged事件。但是,Text属性尚未更新,因为Text Part直到SelectionChanged处理程序完成后才更新。这可以通过在处理程序中放置一个断点并查看控件来观察:

SelectionChanged 处理程序中断点处的 ComboBox

由于此时Text Part尚未更新,因此Text属性返回先前选择的值。

于 2015-07-22T21:43:02.053 回答
52

如果您想要组合框的当前值,请使用 DropDownClosed 事件而不是 selectionChanged。

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

真的就这么简单。

于 2011-04-26T21:08:47.170 回答
10

这对我有用:

private void AppName_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
   ComboBoxItem cbi = (ComboBoxItem)AppName.SelectedItem;
   string selectedText = cbi.Content.ToString();
}
于 2010-11-17T16:48:32.607 回答
9

这对我有用:

private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    var text = ((sender as ComboBox).SelectedItem as ComboBoxItem).Content as string;            
}
于 2015-10-13T11:45:08.623 回答
6

Following event is fired for any change of the text in the ComboBox (when the selected index is changed and when the text is changed by editing too).

<ComboBox IsEditable="True" TextBoxBase.TextChanged="cbx_TextChanged" />
于 2017-03-27T09:02:01.317 回答
1

第二个选项对我不起作用,因为 .Text 元素超出了范围(C# 4.0 VS2008)。这是我的解决方案...

string test = null;
foreach (ComboBoxItem item in e.AddedItems)
{
   test = item.Content.ToString();
   break;
}
于 2010-08-24T21:52:14.423 回答
1
private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    string newItem = ((DataRowView) e.AddedItems[0]).Row.ItemArray[0].ToString();
}
于 2011-04-17T12:59:31.923 回答
1

如果你真的需要这个SelectionChanged活动,那么最好的答案是 SwDevMan81 的答案。但是,如果您从 WPF 开始,那么您可能想学习如何以 WPF 方式做事,这与过去依赖于SelectionChangedWPF 和模型视图 ViewModel 模式等事件的旧 Windows 窗体时代不同,您应该使用绑定。这是一个代码示例:

// In the Views folder: /Views/MyWindow.xaml:
// ...
<ComboBox ItemsSource="{Binding MyViewModel.MyProperties, RelativeSource={RelativeSource AncestorType=Window}}"
         SelectedItem="{Binding MyViewModel.MyProperty  , RelativeSource={RelativeSource AncestorType=Window}}" />
// ...



// In the Views folder: /Views/MyWindow.xaml.cs:
public partial class MyWindow : Window
{
    public  MyViewModelClass MyViewModel {
        get { return _viewModel; }
        private set { _viewModel = value;}
    }

    public MyWindow()
    {
        MyViewModel.PropertyChanged += MyViewModel_PropertyChanged;

    }

    void MyViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "MyProperty")
        {
            // Do Work
            // Put your logic here!
        }
    }
}

using System.ComponentModel;

// In your ViewModel folder: /ViewModels/MyViewModelClass.cs:
public class MyViewModelClass : INotifyPropertyChanged
{
    // INotifyPropertyChanged implementation:
    private void NotifyPropertyChanged(string propertyName = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }
    public event PropertyChangedEventHandler PropertyChanged;

    // Selected option:
    private string _myProperty;
    public  string  MyProperty {
        get { return _myProperty; }
        set { _myProperty = value; NotifyPropertyChanged("MyProperty"); }
    }

    // Available options:
    private List<string> _myProperties;
    public  List<string>  MyProperties {
        get { return _myProperties; }
        set { _myProperties = value; NotifyPropertyChanged("MyProperties"); }
    }

}
于 2015-07-06T15:13:21.810 回答
0

我需要在 VB.NET 中解决这个问题。这是我所拥有的似乎有效的方法:

Private Sub ComboBox1_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles ComboBox_AllSites.SelectionChanged
   Dim cr As System.Windows.Controls.ComboBoxItem = ComboBox1.SelectedValue
   Dim currentText = cr.Content
   MessageBox.Show(currentText)
End Sub
于 2010-11-22T20:17:01.453 回答
0

奇怪的是 SelectedItem 拥有新数据,而 SelectedValue 没有。对我来说听起来像是一个错误。如果您在 Combobox 中的项目是 ComboBoxItems 以外的对象,您将需要这样的东西:(my ComboBoxcontains KeyValuePairs)

var selectedItem = (KeyValuePair<string, string>?)(sender as ComboBox).SelectedItem;
if (!selectedItem.HasValue)
    return;

string selectedValue = selectedItem.Value.Value;  // first .Value gets ref to KVPair

ComboBox.SelectedItem可以为空,而 Visual Studio 一直告诉我 aKeyValuePair不能为空。这就是为什么我将其SelectedItem转换为可空的KeyValuePair<string, string>?. 然后我检查是否selectedItem有一个以外的值null。这种方法应该适用于您选择的项目实际上是什么类型。

于 2014-07-01T13:03:52.227 回答
0
private void indBoxProject_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    int NewProjID = (e.AddedItems[0] as kProject).ProjectID;
    this.MyProject = new kProject(NewProjID);
    LoadWorkPhase();
}

where kProject的使用e.AddedItems[0] as kProject是一个保存数据的类,因为它在我明确区分之前默认为 RemovedItems[0]。感谢 SwDevMan81 为我回答了这个问题的初步信息。

于 2016-04-21T14:10:54.790 回答
0

不要无缘无故地把事情复杂化。使用 SelectedValue 属性,您可以轻松地获得一个选定的 ComboBox 值,如下所示:YourComboBoxName.SelectedValue.ToString()。

在幕后 SelectedValue 属性定义为: SelectedValue{get; set;} 这意味着您可以使用它来获取或设置 ComboBox 的值。

使用 SelectedItem 不是获取 ComboBox 值的有效方法,因为它需要很多分支。

于 2019-01-07T06:32:48.643 回答
0

您可以在 Combobox 控件的 SelectionChanged 事件中检查 SelectedIndex 或 SelectedValue 或 SelectedItem 属性。

于 2019-11-27T02:02:53.813 回答
0

从组合框的 SelectionChanged 事件中,您可以获得所选项目文本,如下所示:

        private void myComboBox_SelectionChanged (object sender, SelectionChangedEventArgs e)
        {
        ComboBoxItem comboBoxItem = (ComboBoxItem) e.AddedItems[0];
        string selectedItemText = comboBoxItem.Content.ToString();
        }
于 2020-12-04T09:24:07.603 回答
-3

这应该对你有用......

int myInt= ((data)(((object[])(e.AddedItems))[0])).kid;
于 2013-10-24T22:32:11.990 回答
-3

我通过使用 DropDownClosed 事件解决了这个问题,因为它在值更改后会稍微触发。

于 2015-06-19T15:45:14.687 回答