Cypher236
Cypher236

Reputation: 527

How are WPF pages held in memory?

So for example in my program I have a window called MainWindow. In this window I have a frame which I load a page into using the mousedown event on the navigation menu.

If I call that Page1, what happens if I decide to load another page, say Page2, into that frame? Does the old Page get held in memory? Or does it get deleted?

Upvotes: 3

Views: 1962

Answers (2)

Andy
Andy

Reputation: 12276

By default the Old page gets held in memory.

A Frame has a journal.

This is a pretty tricky aspect of Frames because it will keep a reference to pages.

Any page you add to a frame is kept alive so long as the journal hangs on to it.

From the docs, there is this rather odd bit in KeepAlive:

"true if the Page instance is retained in navigation history; otherwise, false. The default is false." Which really means the default is true. And the non default is kind of true, as it turns out.

If this is what you want then great.

If this is not what you want then you potentially have a memory hog.

Code demonstrating this:

    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>

Code behind

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

Page 1

  Title="Page1"

  Background="Yellow"
  >

<StackPanel>
    <TextBlock Text="This is Page 1"/>
    <TextBox />
</StackPanel>

Page 2

  Background="Pink"
  >
<StackPanel>
    <TextBlock Text="This is Page 2"/>
    <TextBox />
</StackPanel>

Steps. Click Show Page 1 and type in the box.

enter image description here

Click Show Page 2 and type anything in the box

enter image description here

Notice the navigation bar is there. Click back and you will see the original page 1. Which is in memory. Click forward again. Here we are back with Page 2 again. Click Show Page 1. Type in that enter image description here

Then click the navigate button to go back.

Guess what?

The first instance of Page 1 is still there.

In memory.

Alive.

Even though I didn't set KeepAlive at all.

Here's my solution: Frames Are Evil

If I set the KeepAlive to false then the data I entered disappears.

So that means the memory is freed up?

As it turns out no.

Not always.

You will still find there's memory usage.

Tricky stuff.

Unless you understand exactly how they work and you're good with that, Frames and pages are best avoided.

All substantial projects I've worked on have instead used Contentcontrol and UserControls templated from viewmodels using the viewmodel first pattern.

Upvotes: 2

Marvin
Marvin

Reputation: 14255

By default a page gets deleted, but setting the KeepAlive property to true will keep it in memory.

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    WindowTitle="WillBeKeptInMemory"
    KeepAlive="True"
    >

Upvotes: 3

Related Questions