导航返回& MVVM - 如何刷新WP8页面数据绑定

时间:2013-10-18 06:24:57

标签: c# xaml data-binding mvvm windows-phone-8

我正在做一个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:

DataContext = App.ViewModel;

按钮:

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

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

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

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

2 个答案:

答案 0 :(得分:4)

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

问题

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

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

按钮/文本块的内容会粘贴在旧值上,即使您将其更改为新值。

解决方案

重写OnNavigatedTo方法,并在contructor中设置数据绑定。这样你可以肯定,数据绑定总是“新鲜”并且更新。

在代码隐藏中的page类内部(.xaml.cs文件贴在您的.xaml页面上)写下:

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的同一个对象,则不会发生任何事情。

答案 1 :(得分:2)

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

在您的视图模型中

 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");
  }