Аккордеон
31 мая 2011 - 23:54
Недавно мне пришла в голову мысль, что такой контрол, как Аккордеон(Accordion) в своём классическом варианте с одним активным pane-ом, функционально является полным аналогом TabControl-а, просто в другом визуальном оформлении. И я решил реализовать стиль для TabControl-а, который бы превращал его в аккордеон.
Итак, сначала я создал в главном окне TabControl с несколькими табами содержащими разноветные Rectangle-ы:
Теперь я создам стиль TabControl-а:
Этот стиль представляет собой простую вертикальную StackPanel, которая будет являться ItemsHost-ом для содержимого аккордеона. Для большей универсальности стиля можно добавить изменение ориентации StackPanel-и используя, например, свойство TabStripPlacement у TabControl-а, но я не буду этого делать, чтобы не усложнять пример.
После я создал стиль для TabItem-ов:
Этот стиль представляет собой Grid с двумя строками: в верхней находится заголовок, а в нижней - содержимое pane-а. В невыделенном состоянии содержимое pane-а не отображается, а при выделении появляется, с помощью триггера на IsSelected. Так же сделан триггер на IsMouseOver для большей визуальной привлекательности стиля.
Таким образом стилизуя TabControl я смог получить аккордеон, не написав не строчки кода. Конечно такой аккордеон по функциональности уступает тому, что есть в WPF Toolkit-е, но если вам нужен простой аккордеон с одним активным pane-ом, то стилизированный TabControl будет вполне эффективным решением.
Скачать исходники:
Итак, сначала я создал в главном окне TabControl с несколькими табами содержащими разноветные Rectangle-ы:
<TabControl Width="Auto" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <TabItem Header="1"> <Rectangle Height="150" Fill="Red"/> </TabItem> <TabItem Header="2"> <Rectangle Height="150" Fill="Orange"/> </TabItem> <TabItem Header="3"> <Rectangle Height="150" Fill="Yellow"/> </TabItem> <TabItem Header="4"> <Rectangle Height="150" Fill="Green"/> </TabItem> <TabItem Header="5"> <Rectangle Height="150" Fill="LightBlue"/> </TabItem> <TabItem Header="6"> <Rectangle Height="150" Fill="Blue"/> </TabItem> <TabItem Header="7"> <Rectangle Height="150" Fill="Purple"/> </TabItem> </TabControl>
<Style TargetType="TabControl"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="TabControl"> <StackPanel IsItemsHost="True" Orientation="Vertical"/> </ControlTemplate> </Setter.Value> </Setter> </Style>
После я создал стиль для TabItem-ов:
<Style TargetType="TabItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="TabItem"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="25"/> <RowDefinition/> </Grid.RowDefinitions> <Border Margin="0,1,0,0" x:Name="outterHeaderBorder" BorderThickness="1" CornerRadius="2" BorderBrush="#AACCCCCC"> <Border x:Name="innerHeaderBorder" BorderThickness="1" CornerRadius="1"> <ContentPresenter ContentSource="Header" Margin="2"/> </Border> </Border> <Border x:Name="contentBorder" Visibility="Collapsed" Grid.Row="1" BorderBrush="#FFA0A0A0" BorderThickness="1,0,1,1" CornerRadius="0,0,2,2"> <ContentPresenter ContentSource="Content" Margin="0"/> </Border> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="Visibility" Value="Visible" TargetName="contentBorder"/> <Setter Property="Background" TargetName="innerHeaderBorder"> <Setter.Value> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFCACACA" Offset="0"/> <GradientStop Color="#FFEEEEEE" Offset="0.352"/> <GradientStop Color="#FFC1C1C1" Offset="1"/> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property="BorderBrush" TargetName="innerHeaderBorder" Value="#FFDDDADA"/> <Setter Property="BorderBrush" TargetName="outterHeaderBorder" Value="#FFA0A0A0"/> <Setter Property="CornerRadius" TargetName="outterHeaderBorder" Value="2,2,0,0"/> </Trigger> <Trigger Property="IsMouseOver" Value="True" SourceName="outterHeaderBorder"> <Setter Property="Background" TargetName="innerHeaderBorder"> <Setter.Value> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFF4F4F4" Offset="0"/> <GradientStop Color="White" Offset="0.352"/> <GradientStop Color="#FFCFCFCF" Offset="1"/> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property="BorderBrush" TargetName="innerHeaderBorder" Value="Gainsboro"/> <Setter Property="BorderBrush" TargetName="outterHeaderBorder" Value="#FFB7B7B7"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
Таким образом стилизуя TabControl я смог получить аккордеон, не написав не строчки кода. Конечно такой аккордеон по функциональности уступает тому, что есть в WPF Toolkit-е, но если вам нужен простой аккордеон с одним активным pane-ом, то стилизированный TabControl будет вполне эффективным решением.
Скачать исходники: