I've been working on trying to recreate the section header that is used in the Computer section of Windows Explorer in Windows 7.
(This can be found by opening a new Explorer window and selecting Computer. View should be Tiles and Group By should Type. This will give a section for "Hard Disk Drives". I'm trying to recreate that chevron and header
I've created the following resource dictionary:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Framework.Commons.Controls">
<Style x:Key="ChevronBase" TargetType="{x:Type Path}">
<Setter Property="StrokeThickness" Value=".75" />
<Setter Property="Stretch" Value="Fill" />
<Setter Property="RenderTransformOrigin" Value="0,0" />
<Setter Property="Width" Value="6" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Data" Value="M 0 3 L 6 3 L 3 6 Z" />
</Style>
<Style x:Key="ChevronOpen"
BasedOn="{StaticResource ResourceKey=ChevronBase}"
TargetType="{x:Type Path}">
<Setter Property="Fill" Value="Black" />
<Setter Property="LayoutTransform">
<Setter.Value>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform Angle="-45" />
<TranslateTransform />
</TransformGroup>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ChevronClosed"
BasedOn="{StaticResource ResourceKey=ChevronBase}"
TargetType="{x:Type Path}">
<Setter Property="Stroke" Value="#FF808080" />
<Setter Property="Fill" Value="Transparent" />
<Setter Property="LayoutTransform">
<Setter.Value>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform Angle="-90" />
<TranslateTransform />
</TransformGroup>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ChevronCheckBox" TargetType="{x:Type CheckBox}">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="IsChecked" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid Background="Transparent">
<Path x:Name="ChevronOpen"
Style="{StaticResource ResourceKey=ChevronOpen}"
Visibility="Collapsed" />
<Path x:Name="ChevronClosed"
Style="{StaticResource ResourceKey=ChevronClosed}"
Visibility="Collapsed" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ChevronOpen" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ChevronClosed" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
I've added the style to a checkbox as such:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<CheckBox x:Name="Xpander" Style="{DynamicResource ResourceKey=ChevronCheckBox}" />
<ContentPresenter Grid.Column="1"
VerticalAlignment="Center"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}" />
<Separator Grid.Column="2"
Height="12pt"
Margin="7,0,0,0"
VerticalAlignment="Center"
Visibility="{TemplateBinding LineBreakVisibility}" />
<ContentPresenter Grid.Row="1"
Grid.ColumnSpan="3"
Margin="8,5,5,5"
Visibility="{Binding ElementName=Xpander,
Path=IsChecked,
Converter={StaticResource ResourceKey=BooleanToVisibilityConverter}}" />
</Grid>
The problem I am running into is that the chevron always comes out super funky (and not in a good funky).
This is one of the few times I've worked with Path objects. Is there something I'm doing wrong that is making the chevron skew odd when it is placed in the grid along with my other header items?
It currently seems like it's either skewed too wide or the layout rotation isn't correct. I've tried coming up with the correct path in a blank page in Expression Blend 4 but I'm just not understanding on how to come up with a correct path. I can use two different path data sets but I thought just rotating the triangle would work.
BTW, I know I don't have all the styles for the current Explorer behavior. Right now I'm trying to mimic collapse and uncollapsed state. I'm open to taking suggestions if there is a better way to do this than using the CheckBox and overriding it's Template.
EDIT Windows 7 Example:
The left side shows the expanded state of the header and the right collapsed. The top portion is when the chevron is hovered.
My current "super funky" chevron (there is no glory):
The top is expanded and the bottom is collapsed.
A quick elaboration on what my idea was trying to accomplish. I wanted to have path and change its layout rotation, fill, and stroke depending on the visual state of the checkbox (and later the path for the mouse over style).
Another quick note, since this is overriding a checkbox ControlTemplate I'm using the visual state manager for the checked and unchecked states. When the "checkbox" is checked it is expanded. When it is not the header appears collapsed.
Ditch the Path object. Use a RegularPolygon with points set to three. You'll need the Expression Blend SDK to get the RegularPolygon class.