如何以编程方式设置数据绑定的WPF ComboBox的SelectedItem?

时间:2010-08-17 09:45:09

标签: c# wpf data-binding combobox

问题:任何人都可以提供完整的代码示例,说明如何在不使用MyComboBox.SelectedIndex的情况下以编程方式更改数据绑定的WPF ComboBox的SelectedItem吗?

代码示例:以下是我目前的情况。

XAML:

<Window x:Class="Wpf.ComboBoxDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ComboBox Name="MyComboBox" DisplayMemberPath="LastName" SelectedIndex="0"/>
    </Grid>
</Window>

代码隐藏:

using System.Collections.ObjectModel;
using System.Windows;

namespace Wpf.ComboBoxDemo
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            ObservableCollection<Person> myPersonList = new ObservableCollection<Person>();

            Person personJobs = new Person("Steve", "Jobs");
            Person personGates = new Person("Bill", "Gates");

            myPersonList.Add(personJobs);
            myPersonList.Add(personGates);

            MyComboBox.ItemsSource = myPersonList;

            // How do I programmatically select the second Person, i.e. "Gates"?
            // The best pratice must be to somehow to set something like IsCurrentlySelected on the model, so the view update automatically. But how?
            MyComboBox.SelectedIndex = 1; // This works, but is there no way without using the index?

        }

        private class Person
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }

            public Person(string firstName, string lastName)
            {
                FirstName = firstName;
                LastName = lastName;
            }
        }
    }
}

类似的问题:我当然首先搜索了互联网,但没有找到任何帮助我。

  • 在ViewModel(MSDN)中更改枚举组合框的SelectedItem
  • 以编程方式在WPF中设置ComboBox SelectedItem(3.5sp1)(Stack Overflow

1 个答案:

答案 0 :(得分:1)

在我的头顶(我可能错了),使窗口工具INotifyPropertyChanged并添加事件:

namespace Wpf.ComboBoxDemo
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public MainWindow()
        {

然后为当前所选项目添加一个属性,通知更改:

        private Person _selected;
        public Person MySelected
        {
            get { return _selected; }
            set
            {
                if (value != _selected)
                {
                    _selected = value;            
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this,
                            new PropertyChangedEventArgs("MySelected"));
                    }
                }
            }
        }

现在绑定组合框(使用FindAncestor绑定可能更高级,但有时为了简单起见我将datacontext放在代码后面):

<强> XAML

        <ComboBox
            Name="MyComboBox"
            DisplayMemberPath="LastName"
            SelectedItem="{Binding MySelected}" />

代码

    public MainWindow()
    {
        InitializeComponent();
        // ...

        // this will cause the "MySelected" binding to target the correct property on this object
        MyComboBox.DataContext = this;
    }

我认为它就是这样的。我现在无法测试它,但希望它会在正确的方向上推动你。

编辑:如果你想尝试绑定的“其他方式”,那么如何。展开SelectedItem绑定,如下所示:

        <ComboBox
            Name="MyComboBox"
            DisplayMemberPath="LastName"
            SelectedItem="{Binding MySelected,
                RelativeSource={RelativeSource FindAncestor,
                    AncestorType={x:Type Window}}}" />

您现在可以跳过设置代码中的DataContext

    public MainWindow()
    {
        InitializeComponent();
        // ...

        // this will cause the "MySelected" binding to target the correct property on this object
        //MyComboBox.DataContext = this;
    }

这是因为FindAncestor模式使ComboBox本身找到了应该绑定属性的对象,而不是你具体说明。

办公室目前的热门话题是这两种方式中哪一种最好。对我来说,它只是更多的XAML和更少的代码(或者反过来),只需使用将代码放在舒适的工作区域的方法。我认为有些情况下后者是首选的(比如当你在其他控件中包含数据绑定控件时),但我只是涉足所以我还没有真正想出那些部分。