Привязка выбранного элемента WPF ComboBox

У меня есть WPF ComboBox, и я использую MVVM для привязки свойств ItemsSource и SelectedItem. В основном то, что я хочу сделать, - это когда пользователь выбирает определенный элемент в поле со списком, поле со списком вместо этого выбирает другой элемент.

<ComboBox ItemsSource="{Binding TestComboItemsSource}" SelectedItem="{Binding TestComboItemsSourceSelected}"></ComboBox>

В демонстрационных целях у меня также есть кнопка для обновления SelectedItem.

<Button Command="{Binding DoStuffCommand}">Do stuff</Button>

У меня это в моей viewModel:

    public ObservableCollection<string> TestComboItemsSource { get; private set; }

    public MyConstructor()
    {
        TestComboItemsSource = new ObservableCollection<string>(new []{ "items", "all", "umbrella", "watch", "coat" });
    }

    private string _testComboItemsSourceSelected;
    public string TestComboItemsSourceSelected
    {
        get { return _testComboItemsSourceSelected; }
        set
        {
            if (value == "all")
            {
                TestComboItemsSourceSelected = "items";
                return;
            }

            _testComboItemsSourceSelected = value;
            PropertyChanged(this, new PropertyChangedEventArgs(TestComboItemsSourceSelected))
        }
    }

    private ICommand _doStuffCommand;

    public ICommand DoStuffCommand
    {
        get
        {
            return _doStuffCommand ?? (_doStuffCommand = new RelayCommand(p =>
                                                                              {
                                                                                  TestComboItemsSourceSelected = "items";
                                                                              })); }
    }

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

У меня есть аналогичная логика для обновления viewModel в моем установщике свойства TestComboItemsSourceSelected. Если пользователь выбирает «все», вместо этого установите для SelectedItem значение «items». Таким образом, с точки зрения кода свойство viewmodel изменяется, но по какой-то причине это не отражается в пользовательском интерфейсе. Я что-то упускаю? Есть ли какой-то побочный эффект от того, как я это реализовал?


person user832747    schedule 23.08.2011    source источник


Ответы (2)


Это потому, что вы меняете свойство, пока выполняется другое изменение. WPF не будет прослушивать событие PropertyChanged для этого свойства при его установке.

Чтобы обойти это, вы можете «запланировать» новое изменение с помощью диспетчера, чтобы оно было выполнено после того, как будет выполнено с текущим изменением:

public string TestComboItemsSourceSelected
{
    get { return _testComboItemsSourceSelected; }
    set
    {
        if (value == "all")
        {
            Application.Current.Dispatcher.BeginInvoke(new Action(() => {
               TestComboItemsSourceSelected = "items";
            }));
            return;
        }

        _testComboItemsSourceSelected = value;
        PropertyChanged(this, new PropertyChangedEventArgs(TestComboItemsSourceSelected))
    }
}
person Pavlo Glazkov    schedule 23.08.2011
comment
Спасибо! Я подумал, что может быть что-то в этом роде. - person user832747; 23.08.2011

Поведение, которое вы описываете, кажется мне очень странным, но если вам нужна функция «Выбрать все», стандартным способом является создание поля со списком, в котором элементы имеют флажок.

Каждый элемент представлен небольшой ViewModel (обычно со свойствами Id, Name и IsChecked), и вы вручную создаете «выбрать весь элемент», который добавляется первым в ObservableCollection, и подписываетесь на его PropertyChanged, чтобы установить остальные элементы. IsChecked значение true.

person JoanComasFdz    schedule 28.03.2012