我想创建一个TabControl,其中TabItem将在运行时动态创建。 TabItem应与ViewModel相关联。此视图模型支持一个知道如何在TabItem中创建内容的接口。所以TabItems基本上可以在运行时接受视图模型决定的任何内容控件。我尝试过使用TabControl.ContentTemplate或ControlTemplate和ItemTemplate的不同方法,但它们都不起作用。似乎模板方法需要在设计时知道TabItem内部的内容类型,以便能够呈现自己。对关联数据上下文中的属性的绑定工作正常,但不显示内容控件。 我们可以只导出一个新类MyTabItem:TabItem并创建一个自定义内容并将其与MyTabItem的内容相关联。 需要任何可以允许视图模型创建TabItems内容的通用方法。
答案 0 :(得分:0)
您是否可以为可能动态添加到DataTemplate
的每种类型指定TabControl
?如果是这样,这样的事情对你有用吗?
(请注意,TabControl
为DataTemplate
(标签页的模板)和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; }
}