2009-07-01 14 views
1

Я ищу помощь с проблемой WPF, с которой я боролся некоторое время. Я разработал представление вкладки, перемещая вкладки слева и отображая их по вертикали. Эти вкладки располагаются внутри границы с закругленными углами вверху и внизу слева.Прокрутка содержимого внутри рамки с помощью CornerRadius

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

Я бегу в проблему, когда вкладки прокручиваются. Вместо того, чтобы закругленные углы отсечением прокручивать содержание, содержание на самом деле едет сверху по углам, как показано здесь:

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

Вот 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> 

Любые идеи на пути Я мог бы выполнить то, что я ищу? Я пробовал некоторые трюки ZIndex, но это, похоже, не сработало.

ответ

1

Чтобы выполнить то, что я искал, я использовал решение here и модифицировал его в соответствии с моими потребностями. Вот что я закончил с:

<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: Я нашел решение проблемы подрезки с первым TabItem. Вставка ScrollView внутри второй границы и применение OpacityMask к этой границе, а не ScrollView устраняет проблему. Кроме того, я должен был явно установить Background = «Transparent» на границу, где применяется OpacityMask, чтобы клип не был преждевременным.

3

Вы можете установить Clip на закругленной границе с геометрией, соответствующей контуру границы.

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

Обратите внимание, что - как вы, вероятно, нашли - ClipToBounds на Border не будет работать, потому что область между углом и закругленным краем находится в пределах от Border, так что не будет обрезается.

+0

Спасибо за помощь. Хотя я не использовал ваше решение (поскольку размер не фиксирован), он указал мне в правильном направлении для поиска ответа. Я разместил решение ниже. –

+0

Почему вы не можете просто привязать свойства RectangleGeometry к соответствующим свойствам на границе? –

+0

Вы должны извинить мое невежество с этим вопросом, так как я довольно новичок в XAML и WPF, но с какими свойствами я буду привязываться? Я предполагаю, что RadiusX и RadiusY не нуждаются в привязке, но я не могу найти свойство на границе для привязки Rect to. –