In WinUI3, TabView has some TabItems. how to make the TabItems load the corresponding page after clicking and selecting them. My codes as following, but they don't work( Just check the second tab).
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="MyTest.TestWindowTabView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyTest" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Orientation="Vertical">
<Button x:Name="AddTab" Click="Add_Click">Add New Tab</Button>
<TabView x:Name="MyTabView" SelectionChanged="TabViewItem_SelectionChanged" >
<TabView.TabItemTemplate>
<DataTemplate x:DataType="local:TabItemViewModel">
<TabViewItem Header="{x:Bind Title}">
<TabViewItem.Content>
<ContentPresenter Content="{x:Bind Content}"/>
</TabViewItem.Content>
</TabViewItem>
</DataTemplate>
</TabView.TabItemTemplate>
</TabView>
</StackPanel>
</Window>
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace MyTest
{
/// <summary>
/// An empty window that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class TestWindowTabView : Window
{
public ObservableCollection<TabItemViewModel> Tabs { get; } = new ObservableCollection<TabItemViewModel>();
public TestWindowTabView()
{
this.InitializeComponent();
Tabs.Add(new TabItemViewModel { Title = "Tab 1", Content = new TextBlock { Text = "Content of Tab1" } });
// Keep the Content as null, I want the content loaded only after the TabItem selected.
// the lazy loading will be done in the SelectionChanged event, but it doesn't work.
Tabs.Add(new TabItemViewModel { Title = "Tab 2" });
Tabs.Add(new TabItemViewModel { Title = "Tab 3", Content = new TextBlock { Text = "Content of Tab3" } });
MyTabView.TabItemsSource = Tabs;
}
private void Add_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
Tabs.Add(new TabItemViewModel { Title = "Tab 3" });
}
private async void TabViewItem_SelectionChanged(Object sender, SelectionChangedEventArgs args)
{
if (MyTabView.SelectedItem is TabItemViewModel selectedItem)
{
if (selectedItem.Content == null)
{
await selectedItem.LoadContentAsync();
}
}
}
}
}
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace MyTest
{
public class TabItemViewModel : INotifyPropertyChanged
{
public string Title { get; set; }
private UIElement _content;
public UIElement Content
{
get => _content;
set
{
_content = value;
OnPropertyChanged(nameof(Content));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public async Task LoadContentAsync()
{
// for example only, just load a simple TextBlock
Content = new TextBlock { Text = $"Content of {Title}" };
}
}
}