在WPF(3.5sp1)中以编程方式设置ComboBox的SelectedItem

14

在安装了Net Framework 3.5 sp1的wpf应用程序中,我在编程设置SelectedItem时感到困惑。我已经仔细阅读了大约一百篇帖子/话题,但仍然感到困惑。我的xaml代码:

 <ComboBox name="cbTheme">
    <ComboBoxItem>Sunrise theme</ComboBoxItem>
    <ComboBoxItem>Sunset theme</ComboBoxItem> 
 </ComboBox>

如果我在其中一个项目中添加 IsSelected="True" 属性,它并不会将该项目设置为选定状态。为什么? 我已尝试在代码中尝试不同的方法,但仍无法设置所选项目。
cbTheme.SelectedItem=cbTheme.Items.GetItemAt(1); //dosn't work
cbTheme.Text = "Sunrise theme"; //dosn't work
cbTheme.Text = cbTheme.Items.GetItemAt(1).ToString();//dosn't work
cbTheme.SelectedValue = ...//dosn't work
cbTheme.SelectedValuePath = .. //dosn't work
//and even this dosn't work:
ComboBoxItem selcbi = (ComboBoxItem)cbTheme.Items.GetItemAt(1);//or selcbi = new ComboBoxItem
cbTheme.SelectedItem = selcbi;

SelectedItem 不是只读属性,那么为什么它不能工作呢? 我认为这应该是微软的问题,而不是我的问题。或者我错过了什么???我尝试使用 ListBox 进行操作,所有代码都可以正常工作,我可以设置选择、获取选择等等... 那么我该如何处理 ComboBox 呢?也许有一些诀窍?


嘿,@Victor,你应该选择ihatmash的答案。 - reggaeguitar
6个回答

13

要在ComboBox中选择任何项目并将其设置为默认选定项目,只需使用以下行:

combobox.SelectedIndex = 0; //index should be the index of item which you want to be selected

7

如果我以编程方式添加下拉框和选项,这对我来说是有效的:

ComboBox newCombo = new ComboBox();

ComboBoxItem newitem = new ComboBoxItem();
newitem.Content = "test 1";
newCombo.Items.Add(newitem);
newitem = new ComboBoxItem();
newitem.Content = "test 2";
newCombo.Items.Add(newitem);
newitem = new ComboBoxItem();
newitem.Content = "test 3";
newCombo.Items.Add(newitem);

newCombo.SelectedItem =  ((ComboBoxItem)newCombo.Items[1]);
newCombo.Text = ((ComboBoxItem)newCombo.Items[1]).Content.ToString();

newStack.Children.Add(newCombo);

如果以编程方式设置了ItemSource属性,然后将文本设置为所选值,则它也有效。

6
在您的视图模型中创建一个公共属性,用于主题列表和选定项:
    private IEnumerable<string> _themeList;
    public IEnumerable<string> ThemeList
    {
        get { return _themeList; }
        set
        {
            _themeList = value;
            PropertyChangedEvent.Notify(this, "ThemeList");
        }
    }
    private string _selectedItem;
    public string SelectedItem
    {
        get { return _selectedItem; }
        set
        {
            _selectedItem = value;
            PropertyChangedEvent.Notify(this,"SelectedItem");
        }            
    }

在XAML中将您的ComboBox绑定到属性,如下所示:

    <ComboBox 
        Name="cbTheme" 
        ItemsSource="{Binding ThemeList}"      
        SelectedItem="{Binding SelectedItem}">
    </ComboBox>

现在,您只需向ThemeList添加项目以填充组合框。要在列表中选择项目,请将selected属性设置为所选项目的文本,如下所示:

    var tmpList = new List<string>();
    tmpList.Add("Sunrise theme");
    tmpList.Add("Sunset theme");

    _viewModel.ThemeList = tmpList;
    _viewModel.SelectedItem = "Sunset theme";

如果您想继续使用当前的代码,可以尝试将所选项设置为您希望选择的项目的字符串值 - 不确定是否有效,但可以尝试。


请确保将您的视图的DataContext设置为包含ThemeList和SelectedItem属性的类 - 即您的ViewModel。 - ihatemash
2
这应该是被接受的答案,因为它是唯一可进行单元测试的答案。 - reggaeguitar

2

如果您知道要设置的项目的索引,就像在这种情况下似乎您正在尝试设置索引 1 一样,您只需执行以下操作:

cbTheme.SelectedIndex = 1;

我发现当你不知道索引时,这才是真正的问题。我知道这超出了最初的问题,但对于那些想要知道如何在索引未知但要显示的值已知的情况下设置项目的谷歌用户,如果你正在使用来自DataTableItemSource填充下拉列表,例如,你可以通过执行以下操作获取该索引:

int matchedIndex = 0;
if (dt != null & dt.Rows != null)
{
    if (dt.Rows.Count > 0)
    {
        foreach (DataRow dr in dt.Rows)
        {
            string myRowValue = dr["SOME_COLUMN"] != null ? dr["SOME_COLUMN"].ToString() : String.Empty;
            if (myRowValue == "Value I Want To Set")
                break;
            else
                matchedIndex++;
        }
     }
 }

然后你只需简单地执行 cbTheme.SelectedIndex = matchedIndex;

如果使用 ComboBoxItem 的类似迭代而不是 DataRow,并且以OP显示的方式填充了 ComboBox,也可以产生类似的结果。


0

根据答案4的说法

如果您已经将项目添加到项目源中。 请触发所选值的PropertyChangedEvent。

tmpList.Add("Sunrise theme"); 
    tmpList.Add("Sunset theme");
    PropertyChangedEvent.Notify(this,"SelectedItem");

0

ComboBox是否已绑定数据?

如果是,您最好使用绑定而不是代码来完成....

请参见此问题... WPF ListView Programmatically Select Item

也许创建一个新的SelectableObject {Text = "Abc Theme", IsCurrentlySelected = True},将SelectableObjects集合绑定到ComboBox。

本质上是设置模型中的IsCurrentlySelected属性,并使UI从模型更新。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接