2010-04-14 13 views
12

Tengo que desarrollar un control de pestañas personalizado y decidí crearlo con WPF/XAML, porque planeé aprenderlo de todos modos. Se debe tener este aspecto cuando esté terminado:WPF TabControl personalizado

Target

he hecho un buen progreso hasta ahora, pero hay dos cuestiones a la izquierda:

  1. Sólo el primer artículo/última pestaña debe tener una redondeada esquina superior izquierda/inferior izquierda. ¿Es posible modificar el estilo de estos elementos, de forma similar a como lo hice con el elemento de pestaña seleccionado?

  2. El elemento de pestaña seleccionado no debe tener un borde en su lado derecho. Traté de lograr esto con z-index y superposición, pero los resultados fueron bastante decepcionantes. Hay alguna otra manera de hacer esto?

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> 

Editar: Gracias a Vlad, pude fijar el segundo problema con un borde en cepillo del gradiente. Ver actualizaciones XAML para la solución.

Editar: Vlad ha solucionado el primer problema.

Respuesta

9

Para el segundo problema, quizás debería intentar remove the clipping? Sin embargo, ten cuidado con el possible issues.

Para el primer problema, debe intentar style trigger en la propiedad IsSelected. (Editar: Veo, lo está haciendo exactamente de esta manera.) Mire cómo se implementa esto en la plantilla predeterminada at MSDN. Tenga en cuenta que también están usando ZIndex.

Editar:
he encontrado una solución para su primer/último problema pestaña. Es necesario utilizar las propiedades asociadas a designar a la primera/última pestaña:

En su clase de TestWindow definir bien embargado:

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)); 

Luego, en su primera pestaña establece esta propiedad:

<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> 

Entonces, usted debe definir un disparador para ello:

<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> 

Esto debe ayudar.

El mismo truco funcionaría con la última pestaña. O puede tener un número en lugar de bool como propiedad adjunta.

+1

Gracias. Me ayudaste mucho. – xsl

+2

@xsl: ¡de nada! – Vlad

+2

REALMENTE buen uso de accesorios adjuntos Vlad. ¡Bien hecho! – Stimul8d