Странное поведение WPF ComboBox MVVM

У меня странное поведение, когда я связываю и выпадаю со списком свою модель представления. Поведение следующее: когда я изменяю выбранное значение комбо, я проверяю новое значение, и если это новое значение недействительно, я сохраняю старое значение и отбрасываю новое, таким образом, я не повышаю Inotifypropertychanged, но в любом случае вызывается геттер из свойства, связанного с полем со списком, это получает старое значение, которое я хочу показать, но вместо этого поле со списком показывает новое значение, даже если выбранное значение комбо как старое и правильное значение, Проверял в режиме отладки. Я не знаю, как я могу решить эту проблему, потому что я никогда не видел такого поведения, любые предложения будут высоко оценены.

Это код XAML

<ComboBox Height="23" Name="cbxStatus" HorizontalAlignment="Left"
          ItemsSource="{Binding Path=Status, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
          SelectedItem="{Binding Path=SelectedStatus, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
          DisplayMemberPath="Value" Width="130" VerticalAlignment="Center"
          IsEnabled="{Binding Path=StatusEnable, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 

это код модели представления, свойство

public Config SelectedStatus
{
    get
    {
        if (ApplicationAction == ApplicationAction.Add)
        {
            base.Object.State = configManager.BudgetInitStatus();
            StatusEnable = false;
        }
        else
        {
            StatusEnable = true;
        }
        return base.Object.State;
    }
    set
    {
        if (base.Service.CanChangeBudgetStatus(base.Object, value))
        {
            base.Object.State = value;
            base.Object.IsDirty = true;
        }
        RaiseOnPropertyChanged("SelectedStatus");
        RaiseOnPropertyChanged("AssociateOrderButtonVisibility");
    }
}

Спасибо за помощь


person Ruben Monteiro    schedule 10.05.2011    source источник


Ответы (3)


Настройка привязки к

IsAsync=True

буду работать.

person Jay    schedule 11.05.2011
comment
Привет, спасибо обоим за ответы, я попробовал обе возможности, а также объединил обе, но в моем случае сработала именно эта, хотя я думаю, что обе немного хакерские, я не понимаю, почему эта работает, потому что от того, что я читайте в msdn, это просто, так сказать, получить свойство позже в процессе привязки. Я думаю, что поле со списком должно быть достаточно умным, чтобы видеть, что при уведомлении свойства selecteditem должно отображаться это значение, а не то, которое было выбрано ранее... но это мое мнение. Спасибо еще раз за помощь - person Ruben Monteiro; 11.05.2011

Как указано в моем комментарии Джею, проблема здесь в том, что WPF устанавливает значение и не слушает ваше уведомление об изменении (чего он, в конце концов, ожидает). Что вам нужно сделать, так это поднять уведомление об изменении свойства вне контекста текущего сообщения. Вы можете сделать это с помощью диспетчера, например:

set
{
    if (!valid)
    {
        // value is unchanged
        Dispatcher.BeginInvoke(delegate { this.OnPropertyChanged(...) });
        return;
    }

    // value is changed here
}

Это обеспечит выполнение текущего сообщения привязки данных, а затем отдельное сообщение сообщает WPF, что «на самом деле значение, которое вы только что предоставили моему установщику, больше не является текущим значением».

Вы также можете использовать SynchronizationContext, если хотите. В любом случае, я признаю, что это немного взломано. К сожалению, я не знаю хорошего способа обойти это. Дело в том, что WPF предполагает, что значение, которое он передает вашему сеттеру, является эффективным значением свойства. Никакое количество уведомлений об изменении свойств в контексте операции привязки не убедит его в обратном.

person Kent Boogaart    schedule 10.05.2011
comment
Кент, каковы потенциальные недостатки использования Async=True для достижения этой цели? - person Jay; 11.05.2011

Когда пользователь изменяет значение в поле со списком, оно изменяется в поле со списком, независимо от вашей модели представления.

Если вы измените это значение обратно и не поднимете уведомление об изменении свойства, ваша модель представления и представление будут рассинхронизированы.

Короче говоря, когда вы отклоняете выбранное значение, вам все равно нужно уведомление об изменении свойства.

person Jay    schedule 10.05.2011
comment
Даже с уведомлением об изменении (которое у него есть) WPF проигнорирует изменение, потому что оно ожидает уведомления об изменении в этот момент времени. Чего он не ожидает, так это того, что значение будет отличаться от того, которое оно предоставляет установщику свойства. - person Kent Boogaart; 10.05.2011