如何在页面导航后刷新PivotItem的DataContext

时间:2013-03-02 00:35:37

标签: windows-phone-7 mvvm windows-phone

在WP 7.1项目中,我有一个MainPage.xaml。在那里,我有一个来自WP Toolkit的Pivot控件,如下所示:

<c:Pivot x:Name="pivot" Title="title">
    <c:PivotItem Header="header" DataContext="{vm:ListViewModel}">
        <v:ListView />
    </c:PivotItem>
    ...
</c:Pivot>

基本上,我将第一个数据透视表项的内容设置为我创建的名为ListView的UserControl,并为其创建了一个名为ListViewModel的视图模型。

使用这样的简单模型类:

public class MyModel {
    public int Id { get; set; }
    public string Name { get; set; }
}

ListView视图的xaml如下所示:

...
<ListBox x:Name="list" ItemsSource="{Binding ModelItems"}>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Name}" />
                <Button Command="{Binding DataContext.EditCommand, ElementName=list}"
                        CommandParameter="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}">
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
...

列表中每个项目只需一个简单的2行条目。名称显示在第一行,按钮用于我们要编辑该项目的时间。此视图的视图模型为:

...
private ObservableCollection<MyModel> modelItems;
public ObservableCollection<MyModel> ModelItems {
    get { return modelItems; }
    set {
        if (modelItems != value) {
            modelItems = value;
            NotifyPropertyChanged(() => this.ModelItems);
        }
    }
}

public ListViewModel() {
    ModelItems = new ObservableCollection<MyModel>(repository.GetAll());
}

public ICommand EditCommand {
    get {
      return new RelayCommand(o => {
          var model = o as MyModel;
          Navigator.Uri<EditView>()
                   .WithParam("id", model.id)
                   .Navigate();
    }
}
...

到目前为止,一切都很好,列表已正确填充。单击该按钮可正确导航到EditView视图,并传递所选模型项的ID。

EditView页面很简单,只是一个文本框和一个保存按钮。该视图模型与此类似:

...
public EditViewModel() { // ctor
    var id = GetQueryString("id");
    Model = repository.Get(id);
}
...

“编辑”页面运行良好,它将更改保存回db。但是,在保存操作之后,我执行Navigator.GoBack()并在那里显示旧数据。我应该如何强制我的列表更新新的更改,同时避免代码隐藏?

我能够使用MainPage代码隐藏中的pivot控件Loaded事件实现这一点,如下所示:

private void pivot_Loaded(object sender, RoutedEventArgs e) {
    var selectedPivotItem = (PivotItem)pivot.SelectedItem;
    ((ListViewModel)selectedPivotItem.DataContext).Rebind();
}

我在ListViewModel中添加了Rebind()方法,基本上与构造函数的方法相同,再次获取所有数据并将其分配给ModelItems

有没有办法实现这一点而无需编写任何代码?

由于

1 个答案:

答案 0 :(得分:0)

我习惯使用单例模式创建一个名为AppLifeService的类。在这个对象中,我存储了各种属性,用于页面之间的导航。

当您进入执行操作的页面(编辑/删除/创建)时,只需将修改后的对象放在AppLifeService中的DeletedComment等属性中。

然后在上一页的OnNavigatedTo方法中,验证它是否导航并搜索您的对象。

    protected override void OnNavigatedTo(NavigationEventArgs e, NavigationContext context, NavigationService navigationService)
    {
        base.OnNavigatedTo(e, context, navigationService);

        // back from other app page
        if (e.NavigationMode == NavigationMode.Back)
        {
            var lifeService = ApplicationServices.Resolve<AppLifeService>();

NT?                 var deletedComment = lifeService.DeletedComment;                 if(deletedComment!= null)                 {                     //删除评论                 }

确保不要存放重物以避免堵塞记忆。并在使用时删除它们。