2009-07-01 8 views
1

Je suis à la recherche d'aide pour un problème WPF avec lequel je me bats depuis un moment. J'ai créé un onglet, déplaçant les onglets vers la gauche et les affichant verticalement. Ces onglets sont placés à l'intérieur d'une bordure avec des coins arrondis en haut et en bas à gauche.Défilement de contenu à l'intérieur d'une bordure avec CornerRadius

Normal Tab http://gallery.me.com/theplatz/100006/TabGood.png?derivative=medium&source=web.png&type=medium&ver=12464623560001

Je suis en cours d'exécution dans un problème lorsque les onglets défilent. Au lieu des coins arrondis clipping le contenu défile, le contenu monte réellement au-dessus des coins, comme on le voit ici:

Overlapping Tab http://gallery.me.com/theplatz/100006/TabBad/web.png?ver=12464623500001

Voici le XAML:

<Style x:Key="SidebarTabControl" TargetType="TabControl"> 
    <Setter Property="Background" Value="#FFC6D3DE" /> 
    <Setter Property="Padding" Value="0,20,0,0" /> 
    <Setter Property="TabStripPlacement" Value="Left" /> 
    <Setter Property="IsSynchronizedWithCurrentItem" Value="True" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type TabControl}"> 
       <Grid KeyboardNavigation.TabNavigation="Local"> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="200" MinWidth="150" MaxWidth="400" /> 
         <ColumnDefinition /> 
        </Grid.ColumnDefinitions> 

       <Border 
        CornerRadius="10,0,0,10" 
        Background="{TemplateBinding Background}"> 
        <ScrollViewer Grid.Column="0" 
         VerticalScrollBarVisibility="Auto" 
         HorizontalScrollBarVisibility="Disabled" 
         ClipToBounds="True"> 
         <Border Padding="{TemplateBinding Padding}">   
         <TabPanel 
          IsItemsHost="True" 
          KeyboardNavigation.TabIndex="1" 
          Background="Transparent"> 
         </TabPanel> 
         </Border> 
        </ScrollViewer> 
       </Border> 

       <ContentPresenter 
        Grid.Column="1" 
        Margin="0" 
        ContentSource="SelectedContent" /> 

       <GridSplitter Grid.Column="0" 
        HorizontalAlignment="Right" 
        VerticalAlignment="Stretch" 
        Background="{StaticResource SplitterBrush}" 
        ShowsPreview="True" 
        Width="1" /> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

<Style x:Key="SidebarTab" TargetType="TabItem"> 
    <Setter Property="Padding" Value="10,12,2,12" /> 
    <Setter Property="BorderThickness" Value="0,1,0,1" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type TabItem}"> 
       <Border Padding="{TemplateBinding Padding}" 
        Name="tab" 
        BorderThickness="{TemplateBinding BorderThickness}" 
        BorderBrush="{StaticResource SidebarTabBorderBrush}"> 
        <ContentPresenter Style="{StaticResource SidebarTabForegroundStyle}" Name="content" ContentSource="Header" /> 
       </Border> 

       <ControlTemplate.Triggers> 
        <Trigger Property="IsSelected" Value="True"> 
         <Setter TargetName="tab" Property="Background" Value="{StaticResource SidebarTabBackgroundBrushSelected}" /> 
         <Setter TargetName="tab" Property="BorderBrush" Value="{StaticResource SidebarTabBorderBrushSelected}" /> 
         <Setter TargetName="content" Property="Style" Value="{StaticResource SidebarTabForegroundStyleSelected}" /> 
        </Trigger> 
        <Trigger Property="IsSelected" Value="False"> 
         <Setter TargetName="tab" Property="Background" Value="{StaticResource SidebarTabBackgroundBrush}" /> 
         <Setter TargetName="tab" Property="BorderBrush" Value="{StaticResource SidebarTabBorderBrush}" /> 
         <Setter TargetName="content" Property="Style" Value="{StaticResource SidebarTabForegroundStyle}" /> 
        </Trigger> 
       </ControlTemplate.Triggers> 

      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Toutes les idées sur une façon Je pourrais accomplir ce que je cherche? J'ai essayé quelques trucs de ZIndex, mais ça n'a pas l'air de marcher.

Répondre

1

Pour accomplir ce que je cherchais, j'ai utilisé la solution trouvée here, et l'ai modifiée pour répondre à mes besoins. Voici ce que j'ai fini avec:

<Style x:Key="SidebarTabControl" TargetType="TabControl"> 
    <Setter Property="Background" Value="#FFC6D3DE" /> 
    <Setter Property="Padding" Value="0,20,0,20" /> 
    <Setter Property="TabStripPlacement" Value="Left" /> 
    <Setter Property="IsSynchronizedWithCurrentItem" Value="True" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type TabControl}"> 
       <Grid KeyboardNavigation.TabNavigation="Local"> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="200" MinWidth="150" MaxWidth="400" /> 
         <ColumnDefinition /> 
        </Grid.ColumnDefinitions> 

      <!-- Background of the sidebar and our clipping bounds --> 
      <Border Grid.Column="0" 
       CornerRadius="10,0,0,10" 
        Background="{TemplateBinding Background}" 
       Name="mask" /> 

      <!-- Border necessary so that the top tab does not get clipped prematurely --> 
      <Border Grid.Column="0" Background="Transparent"> 
       <!-- Add opacity mask to clip contents as they're scrolled --> 
       <Border.OpacityMask> 
         <VisualBrush Visual="{Binding ElementName=mask}"/> 
       </Border.OpacityMask> 
       <ScrollViewer 
       VerticalScrollBarVisibility="Visible" 
       HorizontalScrollBarVisibility="Disabled"> 
       <Border Padding="{TemplateBinding Padding}">   
         <TabPanel 
         IsItemsHost="True" 
         KeyboardNavigation.TabIndex="1" 
         Background="Transparent"> 
        </TabPanel> 
       </Border> 
       </ScrollViewer> 
      </Border> 

      <ContentPresenter 
       Grid.Column="1" 
         Margin="0" 
         ContentSource="SelectedContent" /> 

      <GridSplitter Grid.Column="0" 
         HorizontalAlignment="Right" 
         VerticalAlignment="Stretch" 
         Background="{StaticResource SplitterBrush}" 
         ShowsPreview="True" 
         Width="1" /> 
       </Grid> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

Edit: J'ai trouvé la solution au problème de coupure avec le premier TabItem. L'imbrication de ScrollView à l'intérieur d'une deuxième bordure et l'application de l'OpacityMask à cette bordure, et non le ScrollView a résolu le problème. De plus, j'ai dû définir explicitement Background = "Transparent" sur la Bordure où le Masque d'Opacité était appliqué afin que le clip ne se produise pas prématurément.

3

Vous pouvez définir un Clip sur la bordure arrondie avec une géométrie correspondant au contour de la bordure.

<Border> 
    <Border.Clip> 
     <RectangleGeometry Rect="..." RadiusX="..." RadiusY="..."/> 
    </Border.Clip> 
</Border> 

Notez que - comme vous avez probablement trouvé - ClipToBounds sur le Border ne fonctionnera pas parce que la zone située entre le coin et le bord arrondi est dans les limites de la Border, ne sera donc pas coupé.

+0

Merci pour l'aide. Même si je n'ai pas utilisé votre solution (parce que la taille n'est pas fixe), cela m'a orienté dans la bonne direction pour chercher une réponse. J'ai posté la solution ci-dessous. –

+0

Pourquoi ne pas simplement lier les propriétés de RectangleGeometry aux propriétés correspondantes sur la bordure? –

+0

Vous devrez excuser mon ignorance avec cette question, car je suis assez nouveau pour XAML et WPF, mais à quelles propriétés devrais-je me lier? Je suppose que RadiusX et RadiusY n'ont pas besoin de bound, mais je ne peux pas trouver la propriété sur la bordure pour lier le Rect à. –

Questions connexes