XAML Winui TabView根据选项卡类型更改选项卡视图模型(和布局)

qf9go6mv  于 2023-06-03  发布在  其他
关注(0)|答案(1)|浏览(290)

我有一个选项卡视图和多个选项卡视图可以显示的视图模型,每个选项卡可以是一种类型,比如ViewModel1和ViewModel2,它们也会有自己的布局,这取决于模型的类型。我面临的问题是,我不能让视图更改和加载正确的模型,它WPF这是相当直接的,我可以写一些像下面的数据模板,它会呈现正确的视图:

<TabControl.Resources><DataTemplate DataType="{x:Type tab:ViewModel}">

    </DataTemplate>
    
        <DataTemplate DataType="{x:Type tab:ViewModel2}">
    
    </DataTemplate>

</TabControl.Resources>

但是,在winui中,I x:Type不再可用,我正在努力寻找一种动态更改视图和模型的方法。
当前我有一个名为ITab的接口,该接口存储TabName和TabType(Model1或2)

string Name { get; set; } 
TabType TabType { get; }

任何想要成为选项卡集合一部分的视图模型都必须实现这个接口。在父视图模型中,我有一个可观察的ITab集合,它绑定到Tabs ItemsSource。
在XAML中,我有以下代码(其中一些将从旧的WPF项目中复制)

<TabView.Resources>
    <DataTemplate x:DataType="model:Model1" x:Key="model1">
        <Grid> <!--VIEW FOR MODEL 1--> </Grid>
    </DataTemplate>
    <DataTemplate x:DataType="model:Model1" x:Key="model2"> <!--VIEW FOR MODEL 2--> </DataTemplate>
</TabView.Resources>

<TabView.TabItemTemplate>
    <DataTemplate x:DataType="itab:ITab">
        <TabViewItem Header="{Binding Name}">
            <TextBlock>Text</TextBlock>
        </TabViewItem>
    </DataTemplate>
</TabView.TabItemTemplate>

这将渲染选项卡并显示选项卡名称,但是,这只会发生在一个视图模型上,如果选项卡类型是Model2,否则是Model1,我如何指定使用Model2?
我确实尝试过创建一个自定义的TabItemTemplateSelector

<TabView.TabItems>
    <DataTemplate x:DataType="itab:ITab">
        <TabViewItem Header="{Binding Name}">
            <templates:TabItemTemplateSelector Model1="{StaticResource model1}" Model2="{StaticResource model2}" />
        </TabViewItem>
    </DataTemplate>
</TabView.TabItems>
public class TabItemTemplateSelector : DataTemplateSelector { private DataTemplate _model1; private DataTemplate _model2;

    public DataTemplate Model1
    {
        get { return _model1; }
        set { _model1 = value; }
    }
    
    public DataTemplate Model2
    {
        get { return _model2; }
        set { _model2 = value; }
    }
    
    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
    {
        if (item != null)
        {
            var tab = (ITab)item;
    
            switch (tab.TabType)
            {
                case TabType.Model1:
                    return _model1;
                case TabType.Model2:
                    return _model2;
                default:
                    throw new InvalidOperationException("Uknown tab type");
            }
        }
    
        return base.SelectTemplateCore(item, container);
    }
    
    }

然而,当它被渲染时,它显示类名,例如。MyApp.Models.TabItemSelector

rfbsl7qr

rfbsl7qr1#

你可以参考这个帖子。<templates:TabItemTemplateSelector Model1="{S...应用作TabView属性TabView.TabItemTemplateSelector,而不是在DataTemplate中。
所以需要在TabView的上层容器中定义DataTemplateSelector资源,使用TabItemTemplateSelector来使用DataTemplateSelector。

<Grid>
    <Grid.Resources>
        <DataTemplate x:DataType="model:Model1" x:Key="model1">
            <Grid>
                <!--VIEW FOR MODEL 1-->
            </Grid>
        </DataTemplate>
        <DataTemplate x:DataType="model:Model1" x:Key="model2">
            <!--VIEW FOR MODEL 2-->
        </DataTemplate>

        <local:TabItemTemplateSelector x:Key="MyDataTemplateSelector" Model1="{StaticResource model1}" Model2="{StaticResource model2}" />
    </Grid.Resources>

    <TabView TabItemsSource="{x:Bind TabList}" TabItemTemplateSelector="{StaticResource MyDataTemplateSelector}">
        
    </TabView>
    
</Grid>

相关问题