简体   繁体   English

TabControl 如何以 MVVM 方式实现?

[英]How to TabControl implement in MVVM ways?

I want to stick to MVVM design patterns, where view model never touch view object directly, but view can touch view model.我想坚持 MVVM 设计模式,其中视图 model 从不直接触摸视图 object,但视图可以触摸视图 model。 in some condition, i allow view call viewmodel method.在某些情况下,我允许视图调用 viewmodel 方法。 but i ended up in call view object inside viewmodel.但我最终在视图模型中调用视图 object。 i already think binding ways but still not get the ways to solve this.我已经想到了绑定方式,但仍然没有找到解决这个问题的方法。

<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# view model C# 查看 model

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; }
}

You can fix this issue like this你可以像这样解决这个问题

Replace代替

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

With

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

So TabHeaderStringToUcConverter will create the appropriate UserControl based on the tab header string.因此TabHeaderStringToUcConverter将根据选项卡 header 字符串创建适当的 UserControl。

Full example:完整示例:

<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>

Where TabHeaderStringToUcConverter is 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();
    }
}

Finally, In ViewModel, comment out Content = new RankView() , and remove Content property from TabItem class.最后,在 ViewModel 中,注释掉Content = new RankView() ,并从TabItem class 中删除Content属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM