Как программно установить SelectedItem связанного с данными WPF ComboBox? - PullRequest
1 голос
/ 17 августа 2010

Вопрос: Может ли кто-нибудь предоставить пример полного кода, который показывает, как программно изменить SelectedItem связанного с данными WPF ComboBox без использования MyComboBox.SelectedIndex?

Пример кода: Вот то, что у меня сейчас есть.

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 )
  • Программно установить ComboBox SelectedItem в WPF (3.5sp1) ( Переполнение стека )

1 Ответ

1 голос
/ 17 августа 2010

В верхней части моей головы (я могу ошибаться), заставьте окно реализовать 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 , но иногда, чтобы упростить задачу, я помещаю текстовый код данных в код позади):

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 и меньше кода позади (или наоборот), просто используйте метод, который размещает код там, где вам удобно работать.Я думаю, что есть некоторые сценарии, в которых последний предпочтительнее (например, когда вы включаете элементы управления связыванием данных в другие элементы управления), но я просто балуюсь, так что я еще не разобрался с этими частями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...