如何解决在 WinUI 3 中使用 TabItemTemplateSelector 和 TemplateSelector 导致奇怪的嵌套控件
简介:
我目前正在开发一个应用程序,其中数据应显示在 TabView 中。默认情况下,将打开一个“主页”选项卡,显示一个列表框。单击此框中的条目后,将在新选项卡中打开详细信息视图。
该应用程序是在 MVVM 架构中创建的。 “Mainviewmodel”包含一个集合,其中包含填充 TabView 的 viewmodel。我正在尝试使用 DataTemplateSelector 基于 viewmodel 类切换 DataTemplates。
该项目正在使用以下依赖项:
<packagereference Include="CommunityToolkit.Mvvm" Version="7.0.2" />
<packagereference Include="CommunityToolkit.WinUI.UI.Controls" Version="7.0.2" />
<packagereference Include="Microsoft.ProjectReunion" Version="0.5.7" />
<packagereference Include="Microsoft.ProjectReunion.Foundation" Version="0.5.7" />
<packagereference Include="Microsoft.ProjectReunion.WinUI" Version="0.5.7" />
示例代码
MainWindow.xaml.cs 包含 viewmodel 和模板选择器
using CommunityToolkit.Mvvm.ComponentModel;
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;
namespace TestingApp
{
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
}
}
public class TabItemDataTemplateSelector : DataTemplateSelector
{
public DataTemplate HomeTemplate { get; set; }
public DataTemplate DetailTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item,DependencyObject container)
{
switch (item)
{
case HoMetabviewmodel:
return HomeTemplate;
case DetailTabviewmodel:
return DetailTemplate;
default:
throw new ArgumentException("Invalid viewmodel type supplied as item");
}
}
}
public class MainWindowviewmodel : ObservableObject
{
private ObservableCollection<ObservableObject> tabItems;
public ObservableCollection<ObservableObject> TabItems { get => tabItems; set => SetProperty(ref tabItems,value); }
public MainWindowviewmodel()
{
TabItems = new ObservableCollection<ObservableObject>();
TabItems.Add(new HoMetabviewmodel());
TabItems.Add(new DetailTabviewmodel());
TabItems.Add(new DetailTabviewmodel());
}
}
public class HoMetabviewmodel : ObservableObject
{
public string Header { get; set; } = "Home";
public string Detail { get; set; } = "I'm the HomeView";
}
public class DetailTabviewmodel : ObservableObject
{
public string Title { get; set; } = "Detail"; // Different Name to make the classes a bit different
public string Detail { get; set; } = "Hello from the Details!";
}
}
MainWindow.xaml 只包含一个 TabView
<Window
x:Class="TestingApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestingApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<Grid.DataContext>
<local:MainWindowviewmodel />
</Grid.DataContext>
<Grid.Resources>
<DataTemplate x:Key="HomeTemplate">
<TabViewItem Header="{Binding Header}" />
</DataTemplate>
<DataTemplate x:Key="DetailTemplate">
<TabViewItem Header="{Binding Title}" />
</DataTemplate>
<local:TabItemDataTemplateSelector x:Key="TemplateSelector" DetailTemplate="{StaticResource DetailTemplate}" HomeTemplate="{StaticResource HomeTemplate}" />
</Grid.Resources>
<TabView TabItemsSource="{Binding TabItems}" TabItemTemplateSelector="{StaticResource TemplateSelector}">
</TabView>
</Grid>
</Window>
结果
上面的代码创建了一个奇怪的嵌套结果,看起来模板被多次应用于标题和内容,导致TabViewItems到处都是:
想要的结果
对我来说奇怪的是,当我使用“内联”TabItemTemplate 时,结果很好,绑定有效。
<Grid>
<Grid.DataContext>
<local:MainWindowviewmodel />
</Grid.DataContext>
<TabView TabItemsSource="{Binding TabItems}">
<TabView.TabItemTemplate>
<DataTemplate>
<TabViewItem Header="Tab">
<TextBlock Text="{Binding Detail}" />
</TabViewItem>
</DataTemplate>
</TabView.TabItemTemplate>
</TabView>
</Grid
问题
如何使用 TemplateSelector 正确创建 TabViewItem,其中 Header 和 Content 基于 DataTemplate?在搜索类似问题时,我找到了旧项目的解决方案,当简单地在 DataTemplate 中嵌套 TabViewItem 时,这些解决方案似乎可以正常工作,而这里显然不是这种情况。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。