wpf 如何以MVVM方式实现TabControl?

bzzcjhmw  于 2022-11-18  发布在  其他
关注(0)|答案(1)|浏览(416)

我想坚持MVVM的设计模式,视图模型不直接接触视图对象,但视图可以接触视图模型。在某些情况下,我允许视图调用视图模型方法。但我最终在视图模型内部调用视图对象。我已经想到了绑定的方法,但仍然没有找到解决这个问题的方法。

<TabControl
        TabStripPlacement="Left"
        ItemsSource="{Binding Menu}">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Header}" />
            </DataTemplate>
        </TabControl.ItemTemplate>
         <TabControl.ContentTemplate>
            <DataTemplate>
                <ContentControl Content="{Binding Content}" />
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>

C#检视模型

public class DashboardViewModel
{
    public IndexViewModel()
    {
        Menu = new ObservableCollection<TabItem>();
        Menu.Add( 
            new TabItem 
            { 
                Header = "Campaign",
                Content = new RankView()
            } 
        );
        Menu.Add( new TabItem { Header = "Configuration" } );
    }

    public ObservableCollection<TabItem> Menu { get; set; }
}

public sealed class TabItem
{
    public string Header { get; set; } = string.Empty;
    public UserControl Content { get; set; }
}
krcsximq

krcsximq1#

您可以像这样修复此问题
替换

<ContentControl Content="{Binding Content}" />

<ContentControl Content="{Binding Header, Converter={StaticResource TabHeaderStringToUcConverter}}" />

因此,TabHeaderStringToUcConverter将根据选项卡标题字符串创建适当的UserControl。
完整示例:

<StackPanel>
    <StackPanel.Resources>
        <converters:TabHeaderStringToUcConverter 
            xmlns:converters="clr-namespace:Namespace.Where.This.Converter.Live"
            x:Key="TabHeaderStringToUcConverter" />
    </StackPanel.Resources>

    <TabControl
        TabStripPlacement="Left"
        ItemsSource="{Binding Menu}">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Header}" />
            </DataTemplate>
        </TabControl.ItemTemplate>
         <TabControl.ContentTemplate>
            <DataTemplate>
                <ContentControl Content="{Binding Header, Converter={StaticResource TabHeaderStringToUcConverter}}" />
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>
</StackPanel>

其中TabHeaderStringToUcConverter

public class TabHeaderStringToUcConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is string str)
        {
            switch (str)
            {
                case "Campaign":
                    return new RankView();
                // other cases..
            }
        }

        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

最后,在ViewModel中,注解掉Content = new RankView(),并从TabItem类中删除Content属性。

相关问题