【发布时间】:2016-10-19 18:07:21
【问题描述】:
我在我的 UWP Windows 10 应用中观察到一个奇怪的行为。即使我从页面导航回来并且页面已卸载,该页面仍会继续发出事件。例如,即使我转到完全不同的页面,我导航的旧页面仍然会发出“LayoutUpdated”事件。
我准备了一个最小的示例来演示这一点(代码如下)。很简单:
-
有 2 个页面:MainPage 和 ExamplePage。您可以从 MainPage 转到 ExamplePage,也可以从 ExamplePage 返回到 MainPage。
-
每次导航到 ExamplePage 时,都会为新创建的页面提供一个新 ID(页面未缓存)。
-
ExamplePage 中的 Grid 发出 LayoutChanged 事件。并且事件处理程序将文本写入调试控制台,例如:“第 0 页上更新的网格布局”。 0 是我为该页面提供的页面 ID。
-
如果你来回几次,你会看到旧页面仍然将布局更新文本写入控制台。例如,如果我转到 ID 为 3 的页面,它会写入控制台:
网格布局在第 0 页更新
第 3 页更新了网格布局
第 1 页上更新了网格布局
第 2 页更新了网格布局
请注意,旧页面仍会更新其布局。旧页面不应再发出任何事件,但它们会继续发出事件,尽管无法再导航到它们并且它们已被卸载。
代码如下,有5个文件,在VS2015新建一个UWP项目然后:
MainPage.xaml
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button x:Name="NavigationButton"
Click="NavigationButton_Click"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Margin="0,20,0,0">Navigate</Button>
</Grid>
MainPage.xaml.cs
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace App7
{
public sealed partial class MainPage : Page
{
private App app;
public MainPage()
{
this.InitializeComponent();
app = (App)Application.Current;
}
private void NavigationButton_Click(object sender, RoutedEventArgs e)
{
var viewModel = new ExamplePageViewModel(app.GetPageId());
Frame.Navigate(typeof(ExamplePage), viewModel);
}
}
}
ExamplePage.xaml
<Grid x:Name="MainGrid"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
LayoutUpdated="MainGrid_LayoutUpdated">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button x:Name="NavigationButton"
Click="NavigationButton_Click" HorizontalAlignment="Center"
Margin="0,20,0,0">Go Back</Button>
<TextBlock Text="{Binding PageId}"
Grid.Row="1"
FontSize="30"
HorizontalAlignment="Center"></TextBlock>
</Grid>
ExamplePage.xaml.cs
using System.Diagnostics;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace App7
{
public sealed partial class ExamplePage : Page
{
private ExamplePageViewModel viewModel;
public ExamplePage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.NavigationMode == NavigationMode.New ||
e.NavigationMode == NavigationMode.Back)
{
viewModel = (ExamplePageViewModel)e.Parameter;
DataContext = viewModel;
}
}
private void NavigationButton_Click(object sender, RoutedEventArgs e)
{
Frame.GoBack();
}
private void MainGrid_LayoutUpdated(object sender, object e)
{
Debug.WriteLine("grid layout updated on page " + viewModel?.PageId.ToString());
}
}
}
ExamplePageViewModel.cs
using System.ComponentModel;
using Windows.UI.Xaml;
namespace App7
{
public class ExamplePageViewModel : INotifyPropertyChanged
{
private App app;
private int pageId;
public event PropertyChangedEventHandler PropertyChanged;
public int PageId
{
get
{
return pageId;
}
}
public ExamplePageViewModel(int pageId)
{
app = (App)Application.Current;
this.pageId = pageId;
}
}
}
注意:视图模型只是为了清楚地看到哪个页面仍在发出事件。您可以删除视图模型,它不会改变问题。
【问题讨论】: