Im using WinUi 3, Community toolkit mvvm and Net 8.0, with c# as lang. I have a overview page which should display a collection of items in two possible manners. In App.xaml.cs I added following pages to be loaded by DI.
services.AddTransient<OverviewPage>();
// Subpages of OverviewPage
services.AddTransient<Page1>();
services.AddTransient<Page2>();
You should be able to view the items in a listview or a DataGrid. For this, I added the SelectorBar control with a SelectionChanged-Event and a Frame.
OverviewPage.xaml
<Grid x:Name="ContentArea">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="9*" />
</Grid.RowDefinitions>
<SelectorBar Grid.Row="0" SelectionChanged="SelectorBar_OnSelectionChanged">
<SelectorBarItem Text="All" IsSelected="True"/>
<SelectorBarItem Text="Page1" />
<SelectorBarItem Text="Page2" />
</SelectorBar>
<Frame Grid.Row="1" IsNavigationStackEnabled="False" x:Name="ContentFrame"/>
</Grid>
OverviewPage.xaml.cs
private void SelectorBar_OnSelectionChanged(...) {
var currentSelectedItem = sender.SelectedItem;
var currentSelectedIndex = sender.Items.IndexOf(currentSelectedItem);
var pageType = currentSelectedIndex switch {
0 => typeof(Page1),
1 => typeof(Page2),
_ => throw new("invalid page index")
};
var slideNavigationTransitionEffect = currentSelectedIndex - _previousHistorySelectorBarIndex > 0 ? SlideNavigationTransitionEffect.FromRight : SlideNavigationTransitionEffect.FromLeft;
HistoryContentFrame.Navigate(pageType, null, new SlideNavigationTransitionInfo() { Effect = slideNavigationTransitionEffect });
_previousHistorySelectorBarIndex = currentSelectedIndex;
}
The two pages are designed to request the Items via Messenger when theyre loaded and it works.
My Problem here is, that everytime you change the Selection, Page1 and Page2 are created again and again. But I dont want that, I want Page1 and Page2 to be created once and be disposed when OverviewPage is disposed. First I thought I could add the sub pages with AddScoped, but I dont know how to do it. Has anybody a idea how to accomplish this? Is this even possible?
Best regards
You can set the NavigationCacheMode to Required for this:
For example:
<Page
x:Class="SelectorBarExample.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:SelectorBarExample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
NavigationCacheMode="Required"
mc:Ignorable="d">
</Page>
BTW, Frame.Navigate
doesn't use dependency injection for navigation. You should be able to remove these lines:
services.AddTransient<OverviewPage>();
services.AddTransient<Page1>();
services.AddTransient<Page2>();