2009-07-01 5 views
1

Ich suche nach Hilfe mit einem WPF-Problem, mit dem ich seit einer Weile gerungen habe. Ich habe eine Tab-Ansicht entworfen, indem ich die Tabs nach links verschiebe und sie vertikal darstelle. Diese Registerkarten befinden sich innerhalb einer Umrandung mit abgerundeten Ecken oben und unten links.Inhalt scrollen innerhalb einer Grenze mit CornerRadius

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

Ich laufe in ein Problem, wenn die Tabs gescrollt werden. Anstelle der abgerundeten Ecken der gescrollt Inhalt Ausschnitt, der Inhalt reitet tatsächlich auf der Oberseite der Ecken nach oben, wie hier zu sehen:

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

Hier ist der 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> 

Irgendwelche Ideen auf einem Weg Ich könnte erreichen, wonach ich suche? Ich habe einige ZIndex-Tricks ausprobiert, aber das schien nicht zu funktionieren.

Antwort

1

Um das zu erreichen, wonach ich gesucht habe, habe ich die gefundene Lösung here verwendet und sie an meine Bedürfnisse angepasst. Hier ist, was ich am Ende mit:

<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: fand ich die Lösung für das Clipping-Problem mit dem ersten TabItem. Verschachteln der ScrollView innerhalb eines zweiten Rahmens und Anwenden der OpacityMask auf diesen Rahmen und nicht der ScrollView behob das Problem. Außerdem musste ich Background = "Transparent" explizit auf den Rand setzen, an dem die OpacityMask angewendet wurde, damit der Clip nicht vorzeitig ausgelöst wurde.

3

Sie könnten eine Clip auf der abgerundeten Grenze mit einer Geometrie festlegen, die der Umrandung der Umrandung entspricht.

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

Beachten Sie, dass - wie Sie wahrscheinlich gefunden haben - ClipToBounds auf der Border wird nicht funktionieren, weil der Bereich zwischen der Ecke und der abgerundeten Kante in den Grenzen des Border ist, so wird nicht abgeschnitten.

+0

Danke für die Hilfe. Obwohl ich Ihre Lösung nicht verwendet habe (weil die Größe nicht festgelegt ist), hat sie mich in die richtige Richtung geleitet, um nach einer Antwort zu suchen. Ich habe die folgende Lösung veröffentlicht. –

+0

Warum können Sie nicht einfach die Eigenschaften von RectangleGeometry an die entsprechenden Eigenschaften des Borders binden? –

+0

Sie müssen meine Unwissenheit mit dieser Frage entschuldigen, da ich zu XAML & WPF ziemlich neu bin, aber für welche Eigenschaften bin ich verbindlich? Ich gehe davon aus, dass RadiusX und RadiusY nicht gebunden werden müssen, aber ich kann die Eigenschaft an der Grenze nicht finden, an die das Rect gebunden werden soll. –

Verwandte Themen