2016-10-02 33 views
-1

我想創建一個TabControl,其中TabItem將在運行時動態創建。 TabItem應該與ViewModel相關聯。此視圖模型支持知道如何在TabItem內創建內容的接口。所以基本上TabItems可以在運行時採用由視圖模型決定的任何內容控件。我嘗試過使用TabControl.ContentTemplate或ControlTemplate和ItemTemplate的不同方法,但它們都不起作用。看來模板方法需要在設計時知道TabItem內部的內容的類型以便能夠呈現它自己。綁定到關聯的數據上下文中的屬性可以正常工作,但不顯示內容控制。 我們是否可以派生一個新的類MyTabItem:TabItem並創建一個自定義內容並將其與MyTabItem的內容關聯起來。 任何可能允許視圖模型創建TabItems內容的通用方法都是需要的。啓用ViewModel的WPF TabControl啓用TabItem內容創建

+0

好的..我可以派生我的CustomTabItem:TabItem並通過傳遞視圖模型在構造函數中創建其內容。 ViewModel創建內容元素並將其分配給tabitem的內容。這種方法有什麼優點和缺點?我沒有看到這種方法在stackoverflow上的任何答案。允許viewModel創建tabItems內容似乎是一個非常標準的問題。 –

回答

0

您是否可以爲每種類型指定DataTemplate,這些類型可能會動態添加到您的TabControl?如果是這樣,這樣的事情會爲你工作嗎?

(注意TabControl是找到兩個相同的DataTemplateItemTemplate(該選項卡頭的模板)和所選選項卡的內容裏面顯示的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; } 
} 
+0

謝謝@simon的答案。在您發佈的示例中,我們知道設計時數據模板中的內容類型(TextBlock)。在哪裏,我不是類型。好的更具體一點,我的標籤項目需要顯示圖形和一些其他的子控件,如表格。但是我不知道在設計時會顯示多少個圖,這取決於ViewModel。我想指定一個ContentControl而不是TextBlock,但我想這是行不通的。例如像這樣