导航后退和MVVM - 如何刷新WP8页面数据绑定

本文关键字:刷新 WP8 数据绑定 何刷新 MVVM 导航 | 更新日期: 2023-09-27 18:35:49

>我正在做一个WP8应用程序(C#/XAML)。

在我看来,我指定了一个按钮,该按钮是通过与回调绑定来设置的,用于在 VM 未完全加载时启动应用程序。

MVVM 如下所示:

ViewModel
---------
 + Model
   -----
    +Property

并且是这样用App.xaml.cs创建的:

public static MainViewModel ViewModel
    {
        get
        {
            if (viewModel == null)
            {
                viewModel = new MainViewModel();
            }
            return viewModel;
        }
    }

并在页面构造器中设置为页面的数据上下文:

DataContext = App.ViewModel;

和按钮:

<Button x:Name="btn" Content="{Binding Model.Property, FallBackValue='click to load'}" .../>
  • 一开始,btn没有要放入其内容的值,因为模型是空的。

  • 单击btn时,它将加载模型。它用数据填充模型并导航到显示该数据的另一个页面。

  • 当我向后导航(通过硬件后退按钮)时,我希望btn使用绑定中的值而不是回退,因为该值已经设置。但它不使用它,仍然使用绑定的回退值参数提供的那个。

如何确保页面"刷新"并使用 ViewModel 提供的实际值?

导航后退和MVVM - 如何刷新WP8页面数据绑定

啊,好吧,我自己找到了解决问题的方法。

问题所在

如果您使用的是静态 Datacontext(如果您使用的 Viewmodel 类被创建为静态),那么当您导航回页面时,数据绑定不会更新(至少在我的情况下是这样)。

我对多个页面使用相同的数据上下文(包含多个模型的 ViewModel 以及一些集合和属性)。但是当我通过硬件后退按钮导航回页面时,数据绑定没有更新。

按钮/文本块的内容卡在旧值上,即使您将其更改为某个新值也是如此。

溶液

重写 OnNavigatedTo 方法,并在构造器中设置数据绑定。这样,您可以确定数据绑定始终是"新鲜"和更新的。

在代码隐藏的page类(粘在.xaml页上的.xaml.cs文件)中,编写以下内容:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
   base.OnNavigatedTo(e);        //can be left out, base method is empty
   DataContext = null;           //setting datacontext empty at first
   DataContext = App.ViewModel;  //and setting it to the static ViewModel i created
}

这样,当我来到页面时,DataContext总是首先设置为 null (以便旧值干净并且没有要绑定的内容)。

不久之后,我把原来的DataContext放了回去,所以它又有了一些东西可以绑定。

带有 null 的步骤是必要的,因为我需要更改 datacontext 属性,否则如果我再次指向已经设置为 dataContext 的同一对象,则不会发生任何事情。

我想你的ViewModel将实现INotifyPropertyChanged。若要刷新数据绑定,只需引发模型中实现的属性更改事件。在页面的OnNavigatedTo事件中,检查模型是否为空。如果不提高财产变更

在您的视图模型中

 public class ViewModel:INotifyPropertyChanged
 {   
    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion
  }

在您的页面中

  protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
  {
        if (App.ViewModel != null)
            App.ViewModel.NotifyPropertyChanged("Name of property");
  }