【问题标题】:WPF TabControl with ViewModel enabled TabItem content creation启用 ViewModel 的 WPF TabControl 创建 TabItem 内容
【发布时间】:2017-02-10 15:04:29
【问题描述】:

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

【问题讨论】:

  • ok.. 我可以派生我的 CustomTabItem:TabItem 并通过传入视图模型在构造函数中创建其内容。 ViewModel 创建内容元素并将其分配给 tabitem 的内容。这种方法的优缺点是什么。我在stackoverflow上看不到这种方法的任何答案。允许 viewModel 创建 tabItems 内容似乎是一个非常标准的问题。

标签: wpf data-binding viewmodel tabcontrol tabitem


【解决方案1】:

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

(请注意,TabControlItemTemplate(选项卡标题的模板)和ContentTemplate(显示在所选选项卡内容内的模板)找到相同的DataTemplate。这个是因为我们都没有指定,所以 WPF 只是简单地向上遍历树并从我们的Grid.Resources 中找到相同的模板。如果您想为每个模板使用不同的模板,您可以显式指定要用于@987654328 的模板@ 如果这对您有用,或者使用 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; }
}

【讨论】:

  • 感谢@simon 的回答。在您发布的示例中,我们知道设计时数据模板中的内容类型(TextBlock)。我没有类型。好的,更具体地说,我的选项卡项目需要显示图表和其他一些子控件,如表格。但是我不知道在设计时会显示多少个图形,这取决于 ViewModel。我想指定一个 ContentControl 而不是 TextBlock,但我想这不起作用。例如像这样
猜你喜欢
  • 2015-12-07
  • 2010-11-09
  • 2018-04-21
  • 2012-09-07
  • 2022-12-22
  • 1970-01-01
  • 2011-03-31
  • 1970-01-01
  • 2021-03-30
相关资源
最近更新 更多