2011-10-09 48 views
2

我有CloseableTabItems我想要動態添加CloseableTabControl:WPF的選項卡項:指定的元素已經是另一個元素的邏輯子元素。斷開它首先

public class CloseableTabControl : TabControl 
{ 
    protected override DependencyObject GetContainerForItemOverride() 
    { 
     return new CloseableTabItem(); 
    } 
} 


public class CloseableTabItem : TabItem 
{ 
    public static readonly RoutedEvent CloseTabEvent = 
     EventManager.RegisterRoutedEvent("CloseTab", RoutingStrategy.Bubble, 
     typeof(RoutedEventHandler), typeof(CloseableTabItem)); 

    public event RoutedEventHandler CloseTab 
    { 
     add { AddHandler(CloseTabEvent, value); } 
     remove { RemoveHandler(CloseTabEvent, value); } 
    } 

    public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 

     var closeButton = Template.FindName("closeButton", this) as Button; 
     if (closeButton != null) 
     closeButton.Click += CloseButtonClick; 
    } 

    void CloseButtonClick(object sender, RoutedEventArgs e) 
    { 
     RaiseEvent(new RoutedEventArgs(CloseTabEvent, this)); 
    } 
} 

和XAML如下:

<local:CloseableTabControl Grid.Column="2" Grid.Row="1" SelectedIndex="{Binding SelectedTabIndex}" ItemsSource="{Binding TabItems}"> 
    <local:CloseableTabControl.Resources> 
     <DataTemplate DataType="{x:Type TestEditor:TestEditorViewModel}"> 
      <TestEditor:TestEditorView/> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type TestParameterEditor:TestParameterEditorViewModel}"> 
      <TestParameterEditor:TestParameterEditorView/> 
     </DataTemplate> 
    </local:CloseableTabControl.Resources> 
    <local:CloseableTabControl.ItemContainerStyle> 
     <Style TargetType="local:CloseableTabItem"> 
      <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type TabItem}"> 
        <Grid> 
         <Border Name="Border" Background="{DynamicResource Brush2}" BorderBrush="{DynamicResource Brush5}" BorderThickness="1,1,1,1" CornerRadius="6,6,0,0" > 
          <DockPanel> 
           <ContentPresenter x:Name="ContentSite" 
            VerticalAlignment="Center" 
            HorizontalAlignment="Center" 
            ContentSource="Header" 
            Margin="12,2,12,2"/> 
           <Button Name="closeButton" 
            HorizontalAlignment="Center" 
            Margin="3,0,3,0" 
            VerticalAlignment="Center" 
            Width="16" 
            Height="16" 
            DockPanel.Dock="Right" 
            Style="{DynamicResource CloseableTabItemButtonStyle}" 
            ToolTip="Close Tab"> 
            <Path Stretch="Fill" StrokeThickness="0.5" Stroke="#FF333333" Fill="#FF969696" Data="F1 M 2.28484e-007,1.33331L 1.33333,0L 4.00001,2.66669L 6.66667,6.10352e-005L 8,1.33331L 5.33334,4L 8,6.66669L 6.66667,8L 4,5.33331L 1.33333,8L 1.086e-007,6.66669L 2.66667,4L 2.28484e-007,1.33331 Z " HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> 
           </Button> 
          </DockPanel> 
         </Border> 
         </Grid> 
         <ControlTemplate.Triggers> 
          <Trigger Property="IsSelected" Value="True"> 
           <Setter TargetName="Border" Property="Background" Value="{DynamicResource lightBrush}" /> 
          </Trigger> 
          <Trigger Property="IsSelected" Value="False"> 
           <Setter TargetName="Border" Property="Background" Value="{DynamicResource Brush1}" /> 
          </Trigger> 
         </ControlTemplate.Triggers> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
      <Setter Property="Header"> 
       <Setter.Value> 
        <StackPanel Orientation="Horizontal" ToolTip="{Binding Caption}"> 
         <Image Height="18" Source="{Binding ImageName}"/> 
         <TextBlock Text="{Binding Title}" Margin="2,0,0,0"/> 
        </StackPanel> 
       </Setter.Value> 
      </Setter> 
     </Style> 
     </local:CloseableTabControl.ItemContainerStyle> 
    </local:CloseableTabControl> 

一切都很好,當我將只有一個標籤在此窗口中的視圖模型的構造函數:

TabItems.Add(TestEditorViewModel); 

,但是當我加入一個以上的,我發現了提到例外。
我試着按照說明here並將XAML分隔爲ItemTemplateContentTemplate,但是這導致了StackOverFlowException(這是由ContentPresenter部分模板引起的,我不知道爲什麼)。
任何想法我應該如何處理這個?
感謝

回答

4

問題在於您的SetterHeader屬性。當第一個TabItem應用Style時,將創建一個新的StackPanel。當第二個TabItem創建並且已應用Style相同StackPanel將被分配到其Header屬性。在WPF中,一個視覺只能有一個父對象,所以你會收到上面說明的異常。相反,您應該定義一個HeaderTemplate,其中包含StackPanel,以便每次應用StyleTabItem a StackPanel是在WPF充氣HeaderTemplate時生成的。

請參閱此相關的帖子:

WTF WPF TabControl?

乾杯!

+0

我認爲我們大約在同一時間回覆:) –

+2

我一直認爲這個錯誤就像給多個人一樣的cookie吃。它只是不起作用。你需要給他們每個餅乾配方(模板)讓他們去做自己的餅乾:) – Rachel

+0

偉大的比喻,希望你不介意,如果我借它! –

2

問題是

<Setter Property="Header"> 
    <Setter.Value> 
     <StackPanel Orientation="Horizontal" ToolTip="{Binding Caption}"> 
      <Image Height="18" Source="{Binding ImageName}"/> 
      <TextBlock Text="{Binding Title}" Margin="2,0,0,0"/> 
     </StackPanel> 
    </Setter.Value> 
</Setter> 

風格里面。我不知道是什麼原因導致它到底,我覺得它的內容因爲某些原因被設置了兩次,但解決方案是使用

<local:CloseableTabControl.ItemTemplate> 
    <DataTemplate> 
     <StackPanel Orientation="Horizontal" ToolTip="{Binding Caption}"> 
       <Image Height="18" Source="{Binding ImageName}"/> 
       <TextBlock Text="{Binding Title}" Margin="2,0,0,0"/> 
     </StackPanel> 
    </DataTemplate> 
</local:CloseableTabControl.ItemTemplate> 

任何解釋,究竟是什麼問題將是最歡迎的。

相關問題