例如,在我的程序中,我有一个称为MainWindow的窗口。在此窗口中,有一个框架,可以使用导航菜单上的mousedown事件将页面加载到其中。
如果我调用那个Page1,如果我决定将另一个页面(例如Page2)加载到该帧中会发生什么?旧页面是否保留在内存中?还是被删除了?
答案 0 :(得分:3)
默认情况下,页面会被删除,但是将KeepAlive
属性设置为true
会将其保留在内存中。
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowTitle="WillBeKeptInMemory"
KeepAlive="True"
>
答案 1 :(得分:1)
默认情况下,旧页保留在内存中。
框架有日记。
这是Frames的一个非常棘手的方面,因为它将保留对页面的引用。
您添加到框架的任何页面都将保持活动状态,只要日记挂在该页面上即可。
在文档中,KeepAlive中有些奇怪的地方:
“如果Page实例保留在导航历史记录中,则为true;否则为false。默认值为false。” 这实际上意味着默认值为true。 事实证明,非默认值是真实的。
如果这是您想要的,那就太好了。
如果这不是您想要的,那么您可能有一个记忆猪。
展示此代码的代码:
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="160"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel>
<Button Name="ShowPage1"
Content="Show Page One"
Tag="{x:Type local:Page1}"
Click="ShowPage_Click"
/>
<Button Name="ShowPage2"
Tag="{x:Type local:Page2}"
Click="ShowPage_Click"
Content="Show Page Two"/>
</StackPanel>
<Frame Grid.Column="1"
Name="TheFrame"
/>
</Grid>
后面的代码
public MainWindow()
{
InitializeComponent();
}
private void ShowPage_Click(object sender, RoutedEventArgs e)
{
Button btn = sender as Button;
Type pageType = btn.Tag as Type;
var pg = Activator.CreateInstance( pageType);
TheFrame.Content = pg;
}
第1页
Title="Page1"
Background="Yellow"
>
<StackPanel>
<TextBlock Text="This is Page 1"/>
<TextBox />
</StackPanel>
第2页
Background="Pink"
>
<StackPanel>
<TextBlock Text="This is Page 2"/>
<TextBox />
</StackPanel>
步骤。 点击“显示第1页”,然后在框中输入内容。
点击“显示第2页”,然后在框中输入任何内容
注意导航栏在那里。 单击返回,您将看到原始页面1。 哪个在内存中。 再次单击前进。 在这里,我们再次回到第2页。 单击显示页面1。 输入
然后单击导航按钮以返回。
猜猜是什么?
第1页的第一个实例仍然存在。
在内存中。
还活着。
即使我根本没有设置KeepAlive。
这是我的解决方案: Frames Are Evil
如果我将KeepAlive设置为false,那么我输入的数据就会消失。
那意味着释放了内存吗?
事实证明不是。
并非总是如此。
您仍然会发现内存使用情况。
棘手的东西。
除非您确切了解它们的工作原理,否则您最好避免使用框架和页面。
我从事的所有重大项目都改用ContentControl和UserControls,它们是使用viewmodel first模式从viewmodels模板化的。