WinUI3 XAML 不同类型的主从视图绑定

WinUI3 XAML Master-Detail View Binding for Different Types

我无法在 WinUI 3 中创建 Master/Detail 视图。

screenshot

我有一个树视图作为我的主列表,其中包含两种不同的项目类型 ExplorerItemTypeA 和 ExplorerItemTypeA 每个都是基础 ExplorerItem

的一部分 class

我希望详细视图显示不同类型 (A&B) 的正确模板,以便我可以绑定和编辑等。

Treeview 数据模板工作正常。这是详细信息视图的 XAML:

<Page.Resources>

    <DataTemplate x:Key="ContentTypeATemplate" x:DataType="local:ExplorerItemTypeA">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="A Template"/>
            <TextBlock Text="{x:Bind Name}"/>
            </StackPanel>
    </DataTemplate>

    <DataTemplate x:Key="ContentTypeBTemplate" x:DataType="local:ExplorerItemTypeB">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="B Template"/>
            <TextBlock Text="{x:Bind Name}"/>
        </StackPanel>
    </DataTemplate>

    <ExplorerContentTemplateSelector x:Key="ExplorerContentTemplateSelector" 
                                        TreeItemTypeATemplate="{StaticResource ContentTypeATemplate}" 
                                        TreeItemTypeBTemplate="{StaticResource ContentTypeBTemplate}"/>
</Page.Resources>

如果先尝试框架,但现在尝试使用内容展示器显示详细信息视图。

     <TreeView x:Name="MasterListView" 
        Grid.Column="0" 
        ItemsSource="{x:Bind ViewModel.TemplateItems}"
        SelectedItem="{x:Bind ViewModel.SelectedItem,Mode=TwoWay}"
        ItemTemplateSelector="{StaticResource ExplorerItemTemplateSelector}"/>

    <ContentPresenter
        x:Name="DetailContentPresenter"
        Grid.Column="1"
        Content="{x:Bind MasterListView.SelectedItem, Mode=OneWay}"
        ContentTemplateSelector="{StaticResource ExplorerContentTemplateSelector}" />

        

选择器是

    public class ExplorerContentTemplateSelector : DataTemplateSelector
{
    public DataTemplate TreeItemTypeATemplate { get; set; }
    public DataTemplate TreeItemTypeBTemplate { get; set; }

    protected override DataTemplate SelectTemplateCore(object item)
    {
        var explorerItem = (ExplorerItem)item;
        switch (explorerItem.Type)
        {
            case ExplorerItem.ExplorerItemType.A:
                return TreeItemTypeATemplate;
            case ExplorerItem.ExplorerItemType.B:
                return TreeItemTypeBTemplate;
            default:
                Console.WriteLine("Default case");
                return TreeItemTypeATemplate;
        }

    }
}

我觉得答案很明显而且很优雅,但是尽管搜索了线索和方法,这个 c# 初学者还是一无所获。 我被困在这个简单问题上的时间比我愿意承认的要长得多。

感谢所有愿意付出时间的人。

在您的 XAML 标记中将 ContentPresenter 替换为 ContentControl

<ContentControl
    x:Name="DetailContentPresenter"
    Grid.Column="1"
    Content="{x:Bind MasterListView.SelectedItem, Mode=OneWay}"
    ContentTemplateSelector="{StaticResource ExplorerContentTemplateSelector}" />

在您的 DataTemplateSelector 中,您还应该覆盖接受 DependencyObject 参数的 SelectTemplateCore 重载:

public class ExplorerContentTemplateSelector : DataTemplateSelector
{
    public DataTemplate TreeItemTypeATemplate { get; set; }
    public DataTemplate TreeItemTypeBTemplate { get; set; }

    protected override DataTemplate SelectTemplateCore(object item) =>
        SelectTemplateCore(item, null);

    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
    {
        var explorerItem = item as ExplorerItem;
        switch (explorerItem?.Type)
        {
            case ExplorerItem.ExplorerItemType.A:
                return TreeItemTypeATemplate;
            case ExplorerItem.ExplorerItemType.B:
                return TreeItemTypeBTemplate;
            default:
                Console.WriteLine("Default case");
                return TreeItemTypeATemplate;
        }
    }
}