如何在导航事件中保留数据上下文?

时间:2016-04-29 18:26:36

标签: c# constructor navigation windows-phone-8.1 lifecycle

我已经设置了一个属性,可以在调用它的setter时触发自定义导航事件(NavigateTo)。到目前为止,导航在第一次尝试时正常工作,即从列表视图中选择一个项目,其中所选项目绑定到属性,然后属性设置器触发,然后导航事件触发。

但是,当我导航回MainPage并从列表视图中选择一个第二时间时,导航事件不会触发。

我调试过“导航”的电话。第二次导航回MainPage并从列表视图中选择时,不会调用它。这告诉我,页面的构造函数没有被调用,并且没有设置VM的数据上下文,这反过来意味着不会调用setter导航事件

问题:

如何在页面之间的导航生命周期中保留数据上下文?

MainViewModel - 导航事件在SelectedCouncilName setter中调用,该setter传递一个int参数进行导航:

    private CouncilName _selectedCouncilName;
    public CouncilName SelectedCouncilName
    {
        get
        {
            return _selectedCouncilName;
        }
        set
        {
            if (_selectedCouncilName != value)
            {
                _selectedCouncilName = value;
                RaisePropertyChanged("SelectedCouncilName");
                _navCallBack.NavigateTo(_selectedCouncilName.ID);            
            }
        }

    }

MainPage.xaml 列表视图 - 所选项目绑定到SelectedCouncilName属性:

<ListView x:Name="ZonesListView"
                      Margin="0,0,-12,0"
                      ItemsSource="{Binding CouncilNameItems}"
                      SelectedItem="{Binding SelectedCouncilName,
                                             Mode=TwoWay}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Margin="0,0,0,17">
                            <TextBlock Style="{ThemeResource ListViewItemTextBlockStyle}"
                                       Text="{Binding CouncilAcronym}"
                                       TextWrapping="Wrap" />
                            <TextBlock Margin="12,-6,12,0"
                                       Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}"
                                       Text="{Binding CouncilFullName}"
                                       TextWrapping="Wrap" />
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

MainPage.xaml.cs - 在SelectedCouncilName属性上触发setter后触发导航事件的代码。 (我已经包含了整个页面代码,以显示数据上下文的设置方式和导航方法):

public sealed partial class MainPage : Page, INavigationCallback
{
    MainViewModel vm;

    private NavigationHelper navigationHelper;

    public MainPage()
    {

        this.navigationHelper = new NavigationHelper(this);
        this.navigationHelper.LoadState += navigationHelper_LoadState;
        this.navigationHelper.SaveState += navigationHelper_SaveState;

        //init data context
        this.NavigationCacheMode = NavigationCacheMode.Required;
        this.InitializeComponent();

        vm = new MainViewModel(this);
        this.DataContext = vm;
        vm.LoadCouncilNamesData();
    }

    private void navigationHelper_SaveState(object sender, SaveStateEventArgs e)
    {
        throw new NotImplementedException();
    }

    void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
    {
        throw new NotImplementedException();
    }

    /// <summary>
    /// Invoked when this page is about to be displayed in a Frame.
    /// </summary>
    /// <param name="e">Event data that describes how this page was reached.
    /// This parameter is typically used to configure the page.</param>
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {


        // TODO: Prepare page for display here.

        // TODO: If your application contains multiple pages, ensure that you are
        // handling the hardware Back button by registering for the
        // Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
        // If you are using the NavigationHelper provided by some templates,
        // this event is handled for you.

    }

    void INavigationCallback.NavigateTo(string ItemID)
    {
        Frame.Navigate(typeof(RequestTagPage), ItemID);
    }
}

2 个答案:

答案 0 :(得分:1)

如果问题是没有调用构造函数,那么我建议您将viewmodel设置为StaticResource或将其放在ViewModel定位器中。当您在XAML中绑定它时,datacontext将保持不变。

然后可以在viewmodel的构造函数中实现填充,因为它将在需要时生成。

答案 1 :(得分:1)

删除this.NavigationCacheMode = NavigationCacheMode.Required 使构造函数在导航回来时被调用