2010-04-14 4 views
12

Ich muss ein benutzerdefiniertes Tab-Steuerelement entwickeln und entschied, es mit WPF/XAML zu erstellen, weil ich es sowieso lernen wollte. Es sollte so aussehen, wenn es fertig ist:WPF Customized TabControl

Target

ich bisher gute Fortschritte gemacht, aber es gibt zwei Fragen übrig:

  1. Nur die erste/letzte Registerkarte Element ein abgerundetes haben sollte obere linke/untere linke Ecke. Ist es möglich, den Stil dieser Elemente ähnlich wie bei dem ausgewählten Tab-Element zu ändern?

  2. Der ausgewählte Tab-Eintrag sollte keinen Rand auf der rechten Seite haben. Ich habe versucht, dies mit Z-Index und Überlappung zu erreichen, aber die Ergebnisse waren eher enttäuschend. Gibt es einen anderen Weg, dies zu tun?

Current

XAML:

<Window x:Class="MyProject.TestWindow" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="TestWindow" Height="350" Width="500" Margin="5" Background="LightGray"> 
<Window.Resources> 
    <LinearGradientBrush x:Key="SelectedBorderBrush" StartPoint="0,0" EndPoint="1,0"> 
     <GradientBrush.GradientStops> 
      <GradientStopCollection> 
       <GradientStop Color="Gray" Offset="0.965"/> 
       <GradientStop Color="WhiteSmoke" Offset="1.0"/> 
      </GradientStopCollection> 
     </GradientBrush.GradientStops> 
    </LinearGradientBrush> 
    <Style TargetType="{x:Type TabControl}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type TabControl}"> 
        <DockPanel> 
         <Border 
          Panel.ZIndex="50" 
          Margin="0,100,-1,0" 
          Background="#FFAAAAAA" 
          BorderBrush="Gray" 
          CornerRadius="7,0,0,7" 
          BorderThickness="1"> 
          <TabPanel 
           Margin="0,0,0,0" 
           IsItemsHost="True" /> 
         </Border> 
         <Border 
          Background="WhiteSmoke" 
          BorderBrush="Gray" 
          BorderThickness="1" 
          CornerRadius="7,7,7,0" > 
          <ContentPresenter 
           ContentSource="SelectedContent" /> 
         </Border> 
        </DockPanel> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
    <Style TargetType="{x:Type TabItem}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type TabItem}"> 
        <Grid> 
         <Border Name="Border" 
          Background="#FFAAAAAA" 
          CornerRadius="7,0,0,0" 
          BorderBrush="Gray" 
          BorderThickness="0,0,0,1" 
          Panel.ZIndex="50" 
          Margin="0,0,0,0" 
           > 

          <ContentPresenter x:Name="ContentSite"    
           VerticalAlignment="Center" 
           HorizontalAlignment="Left" 
           ContentSource="Header" 
           Margin="10,10,10,10"/> 
         </Border> 
        </Grid> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsSelected" Value="True"> 
          <Setter Property="Panel.ZIndex" Value="100" /> 
          <Setter Property="Margin" Value="0,0,-2,0" /> 
          <Setter TargetName="Border" 
            Property="BorderBrush" 
            Value="{StaticResource SelectedBorderBrush}"/> 
          <Setter TargetName="Border" 
           Property="Background" 
           Value="WhiteSmoke" /> 
          <Setter TargetName="Border" 
           Property="CornerRadius" 
           Value="0,0,0,0" /> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Window.Resources> 
<Grid> 
    <TabControl Name="_menuTabControl" TabStripPlacement="Left" Margin="5"> 
     <TabItem Name="_tabItem1" Header="First Tab Item" ></TabItem> 

     <TabItem Name="_tabItem2" Header="Second Tab Item" > 
      <Grid /> 
     </TabItem> 
     <TabItem Name="_tabItem3" Header="Third Tab Item" > 
      <Grid /> 
     </TabItem> 
    </TabControl> 
</Grid> 

Edit: Dank Vlad, konnte ich das zweite Problem mit einem Gradienten Grenze Pinsel fixieren. Siehe Updates XAML für die Lösung.

Edit: Vlad das erste Problem behoben.

Antwort

9

Für das zweite Problem sollten Sie vielleicht versuchen, remove the clipping? Beachten Sie jedoch die possible issues. Für das erste Problem sollten Sie versuchen style trigger auf Eigenschaft IsSelected. (Edit: Ich sehe, Sie machen es genau so.) Sehen Sie sich an, wie das bei der Standardvorlage at MSDN implementiert ist. Beachten Sie, dass sie auch ZIndex verwenden.

bearbeiten:
fand ich eine Lösung für Ihre erste/letzte Registerkarte Problem. Sie müssen angefügten Eigenschaften verwenden, um das erste/letzte Register zu benennen:

In Ihrer TestWindow Klasse, die Sie definieren angefügten Eigenschaft:

public static bool GetIsFirstTab(DependencyObject obj) 
{ 
    return (bool)obj.GetValue(IsFirstTabProperty); 
} 

public static void SetIsFirstTab(DependencyObject obj, bool value) 
{ 
    obj.SetValue(IsFirstTabProperty, value); 
} 

public static readonly DependencyProperty IsFirstTabProperty = 
     DependencyProperty.RegisterAttached("IsFirstTab", typeof(bool), 
       typeof(TestWindow), new UIPropertyMetadata(false)); 

Dann in Ihrem ersten Registerkarte setzen Sie diese Eigenschaft:

<Window x:Class="MyProject.TestWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:MyProject" 
     ... 
/> 
    ... 
    <TabItem Name="_tabItem1" Header="First Tab Item" 
      local:TestWindow.IsFirstTab="true"> 
    </TabItem> 

Dann sollten Sie einen Trigger für sie definieren:

<Trigger Property="IsSelected" Value="True"> 
    <Setter TargetName="Border" 
      Property="Background" 
      Value="WhiteSmoke" /> 
</Trigger> 
<Trigger Property="local:Window1.IsFirstTab" Value="True"> 
    <Setter TargetName="Border" 
      Property="Background" 
      Value="Red" /> 
</Trigger> 

Diese helfen muss.

Der gleiche Trick würde mit letzter Registerkarte funktionieren. Oder Sie können eine Nummer anstelle von Bool als angehängte Eigenschaft haben.

+1

Vielen Dank. Sie haben mir sehr geholfen. – xsl

+2

@xsl: Sie sind willkommen! – Vlad

+2

WIRKLICH nette Verwendung von angebrachten Requisiten Vlad. Gut gemacht, wirklich! – Stimul8d