Связывание данных WPF MVVM прервано после навигации по страницам - PullRequest
5 голосов
/ 02 сентября 2010

У меня есть страница в приложении в стиле навигации WPF, которая отображает результаты поиска.Страница содержит несколько связанных с данными элементов управления.Сама страница работает нормально;выполняет поиск и возвращает результаты.Элементы управления CheckBox с привязкой к данным работают правильно.

Но если я щелкну ссылку на результат, а затем нажму кнопку "Назад", чтобы вернуться к списку результатов, все мои CheckBox.IsChecked привязки данных будут нарушены.Другие связанные с данными элементы управления (ComboBoxes, DatePickers и т. Д.) Продолжают работать как положено.Привязка к другим свойствам элемента управления CheckBox, например IsEnabled, работает правильно.Но привязка IsChecked остается нарушенной до тех пор, пока я не обновлю страницу.

Вот XAML, использованный для одного из моих элементов управления CheckBox:

<CheckBox IsChecked="{Binding IncludeNote}" Content="Note" IsEnabled="{Binding IsBusy, Converter={StaticResource boolNot}}" />

Как видите, ничего сложного не происходитВот.Но после перехода приложения WPF вперед или назад к странице привязка IsChecked будет нарушена, а свойство IsEnabled продолжит работать.

Что здесь происходит?Это ошибка?

ОБНОВЛЕНИЕ: Изучив некоторые альтернативы, я обнаружил, что эта проблема также влияет на элемент управления ToggleButton, из которого происходит CheckBox.

UPDATE2: И он также не работает для свойства TextBox.Text.

Есть ли способ «обновить» привязки данных для этих элементов управления?Или я должен использовать какой-то другой подход для устранения этой проблемы?

Ответы [ 2 ]

5 голосов
/ 24 сентября 2010

Видимо, это это ошибка.Вот отчет об ошибке в Microsoft Connect: Привязка не работает после навигации назад / вперед .

Пользователь, который сообщил об ошибке, RQDQ , также упомянул свой подход кРешение проблемы:

Обходной путь, который я нашел, - это вручную вызвать BindingOperations.SetBinding для всех привязок на странице во время события Loaded.Похоже, что это работает, будь то навигация явно или через историю (операции назад / вперед).

Это только проблема в WPF4.Привязка данных работает, как и ожидалось, в .NET 3.5.

Я надеюсь, что Microsoft исправит это быстро.Это серьезная проблема для приложений WPF в стиле навигации.

0 голосов
/ 11 января 2012

Простой обходной путь - установить для KeepAlive значение true, а затем, чтобы избежать проблем с плохим состоянием VIewModel при загрузке предыдущей страницы, DataContext каждый раз устанавливается в новом экземпляре в событии Loaded (т.е. не связываться к экземпляру ViewModel в вашем словаре Page.Resources, например, так как он будет сохранен).

Стандартный подход, который мы используем для привязки страницы к модели представления, заключается в простом поведении, прикрепленном к странице.

public sealed class PageViewModelBehavior : Behavior<Page>
{
    public Type DataType { get; set; }

    protected override void OnAttached()
    {
        this.AssociatedObject.KeepAlive = true;
        this.AssociatedObject.Loaded += this.AssociatedObjectLoaded;
        this.AssociatedObject.Unloaded += this.AssociatedObjectUnloaded;
        base.OnAttached();
    }

    protected override void OnDetaching()
    {
        this.AssociatedObject.Unloaded -= this.AssociatedObjectUnloaded;
        this.AssociatedObject.Loaded -= this.AssociatedObjectLoaded;
        base.OnDetaching();
    }

    private void AssociatedObjectLoaded(object sender, RoutedEventArgs e)
    {
        if (this.DataType == null || !typeof(IPageViewModel).IsAssignableFrom(this.DataType))
        {
            throw new InvalidOperationException("PageViewModelBehavior.DataType is not set. Page: " + this.AssociatedObject.GetType().Name);
        }

        this.AssociatedObject.DataContext = Activator.CreateInstance(this.DataType);

        // TODO: Call load on your page view model etc.
    }


    private void AssociatedObjectUnloaded(object sender, RoutedEventArgs e)
    {
        // TODO: Call unload on your page view model etc.

        // Allow the throw-away view model to be GC'd
        this.AssociatedObject.DataContext = null;
    }
}

Это обеспечивает повторное связывание страницы при каждом переходе пользователя на страницу. Это также позволяет вам использовать ваш любимый контейнер IOC для создания ViewModel.

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