使用ViewModel的WPF TabControl启用了TabItem内容创建

时间:2016-10-02 15:29:49

标签: wpf data-binding viewmodel tabcontrol tabitem

我想创建一个TabControl,其中TabItem将在运行时动态创建。 TabItem应与ViewModel相关联。此视图模型支持一个知道如何在TabItem中创建内容的接口。所以TabItems基本上可以在运行时接受视图模型决定的任何内容控件。我尝试过使用TabControl.ContentTemplate或ControlTemplate和ItemTemplate的不同方法,但它们都不起作用。似乎模板方法需要在设计时知道TabItem内部的内容类型,以便能够呈现自己。对关联数据上下文中的属性的绑定工作正常,但不显示内容控件。 我们可以只导出一个新类MyTabItem:TabItem并创建一个自定义内容并将其与MyTabItem的内容相关联。 需要任何可以允许视图模型创建TabItems内容的通用方法。

1 个答案:

答案 0 :(得分:0)

您是否可以为可能动态添加到DataTemplate的每种类型指定TabControl?如果是这样,这样的事情对你有用吗?

(请注意,TabControlDataTemplate(标签页的模板)和ItemTemplate(显示在其中的模板)找到相同的ContentTemplate所选标签的内容)。这是因为我们都没有指定,所以WPF只是走在树上并从我们的Grid.Resources找到两者的相同模板。如果你想为每一个使用不同的模板你可以明确指定用于ItemTemplate的模板(如果适用于您),或使用DataTemplateSelector或类似的模板。)

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <Grid.Resources>
        <DataTemplate DataType="{x:Type local:DescribableOne}">
            <Grid Background="Red">
                <TextBlock Text="{Binding Description}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center"/>
            </Grid>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:DescribableTwo}">
            <Grid Background="Blue">
                <TextBlock Text="{Binding Description}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center"/>
            </Grid>
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:DescribableThree}">
            <Grid Background="Green">
                <TextBlock Text="{Binding Description}" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center"/>
            </Grid>
        </DataTemplate>
    </Grid.Resources>

    <StackPanel Orientation="Horizontal">
        <Button Command="{Binding AddOne}">Add One</Button>
        <Button Command="{Binding AddTwo}">Add Two</Button>
        <Button Command="{Binding AddThree}">Add Three</Button>
    </StackPanel>

    <TabControl Grid.Row="1" ItemsSource="{Binding DynamicallyGeneratedTabs}"/>

</Grid>

视图模型:

public class TabControlViewModel
{
    public TabControlViewModel()
    {
        AddOne = new RelayCommand(DoAddOne);
        AddTwo = new RelayCommand(DoAddTwo);
        AddThree = new RelayCommand(DoAddThree);
        DynamicallyGeneratedTabs = new ObservableCollection<IDescribable>();
    }

    public ICommand AddOne { get; }
    public ICommand AddTwo { get; }
    public ICommand AddThree { get; }

    public ObservableCollection<IDescribable> DynamicallyGeneratedTabs { get; }

    private void DoAddOne()
    {
        DynamicallyGeneratedTabs.Add(new DescribableOne());
    }

    private void DoAddTwo()
    {
        DynamicallyGeneratedTabs.Add(new DescribableTwo());
    }

    private void DoAddThree()
    {
        DynamicallyGeneratedTabs.Add(new DescribableThree());
    }
}

public interface IDescribable
{
    string Description { get; }
}

public class DescribableOne : IDescribable
{
    public DescribableOne()
    {
        Description = "One";
    }

    public string Description { get; }
}

public class DescribableTwo : IDescribable
{
    public DescribableTwo()
    {
        Description = "Two";
    }

    public string Description { get; }
}

public class DescribableThree : IDescribable
{
    public DescribableThree()
    {
        Description = "Three";
    }

    public string Description { get; }
}