In WPF, how to customize the style of ScrollBar in ScrollViewer - wpf

I can add a ScrollBar style as global. But that will alse change all the ScrollBar except in ScrollViewer.
How can I just change the style of ScrollBar in ScrollViewer. Maybe add a style with a Key and specify it to somewhere like a ControlTemplate.
Here is my fully ScrollBar style:
<Style x:Key="ScrollBarThumb" TargetType="{x:Type Thumb}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border x:Name="rectangle"
SnapsToDevicePixels="True"
Background="{StaticResource WordBlueBrush}"
Opacity="0.3"
CornerRadius="4"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}"/>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="rectangle" Property="Opacity" Value="1" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ScrollBar}">
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="false"/>
<Setter Property="Width" Value="14"/>
<Setter Property="Margin" Value="-14 0 0 0" />
<Setter Property="MinWidth" Value="{Binding Height, RelativeSource={RelativeSource Self}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollBar}">
<Grid x:Name="Bg" SnapsToDevicePixels="true">
<Border Padding="0 4">
<Track x:Name="PART_Track"
IsDirectionReversed="true"
IsEnabled="{TemplateBinding IsMouseOver}"
Width="8"
HorizontalAlignment="Center"
>
<Track.DecreaseRepeatButton>
<RepeatButton Opacity="0" Command="{x:Static ScrollBar.PageUpCommand}" />
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Opacity="0" Command="{x:Static ScrollBar.PageDownCommand}" />
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource ScrollBarThumb }" />
</Track.Thumb>
</Track>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Finally, I got my solution.
1st, add a key to the ScrollBar style:
<Style x:Key="ViewerScrollBar" TargetType="{x:Type ScrollBar}">
2nd, right click the ScrollViewer in Visual Studio XAML Designer. Chose 'Edit Template'->'Edit a Copy':
Add ControlTemplate for ScrollViewer
3rd, in the 'Create Style Resource' dialog, specify a key for the ScrollViewer style and click 'OK':
Create Style Resource Dialog
4th, Visual Studio will automatically create the ControlTemplate for my ScrollViewer. Now, add Style="{StaticResource ViewerScrollBar}" for the horizontal ScrollBar and verticalScrollBar:
<ControlTemplate x:Key="ScrollViewerControlTemplate" TargetType="{x:Type ScrollViewer}">
<Grid x:Name="Grid" Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Rectangle x:Name="Corner" Grid.Column="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Row="1"/>
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0"/>
<ScrollBar Style="{StaticResource ViewerScrollBar}" x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
<ScrollBar Style="{StaticResource ViewerScrollBar}" x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
</Grid>
</ControlTemplate>

Related

WPF List View Grouping Scroll Offset with Headers

I have an odd issue with a WPF listview:
Background
Using WPF ListView
Using Grid View to add columns
Virtualizing
Using 4 layers of groups to group the data into expanders in a hierarchical structure
Binding to CollectionViewSource defined in window.resources
Due to indentation of the data (the data is contained in expanders) the headers are offset from the column data so I use TranslateTransform to offset the headers by a small amount
Problem
Everything displays correctly and in the perfect hierarchical structure, however when I scroll to the right, there comes a point when the data keeps scrolling but the headers stop, which results in an offset between the headers and the data columns.
I am sure this has something to do with the way I am offsetting the headers, and the length of the headers compared to the data but I cant seem to find the reason for this problem.
List View Scrolled to just before the offset point
List View Scrolled to the end
Code
nb. I have omitted some style stuff as there is a limit on characters for answers here
<!-- The main grid -->
<ListView x:Name="DataGrid"
Margin="0"
Background="{StaticResource MainBackgroundBrush}"
BorderThickness="0"
Foreground="{StaticResource LightBackgroundBrush}"
ItemsSource="{Binding Source={StaticResource DataCollectionView}}"
ScrollViewer.IsDeferredScrollingEnabled="False"
SelectionMode="Single"
VirtualizingPanel.CacheLength="1,2"
VirtualizingStackPanel.IsContainerVirtualizable="True"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.IsVirtualizingWhenGrouping="True"
VirtualizingStackPanel.ScrollUnit="Pixel"
VirtualizingStackPanel.VirtualizationMode="Recycling">
<!-- Some styles and resources exclusive to this list view -->
<ListView.Resources>
<Setter Property="IsExpanded" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<DockPanel>
<ToggleButton x:Name="HeaderSite"
Width="600"
MinWidth="0"
MinHeight="0"
Margin="1"
Padding="{TemplateBinding Padding}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Background="{TemplateBinding Background}"
Content="{TemplateBinding Header}"
ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
DockPanel.Dock="Top"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontStretch="{TemplateBinding FontStretch}"
FontStyle="{TemplateBinding FontStyle}"
FontWeight="{TemplateBinding FontWeight}"
Foreground="{TemplateBinding Foreground}"
IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
Template="{StaticResource AnimatedExpanderButton}" />
<ContentPresenter x:Name="ExpandSite"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
DockPanel.Dock="Bottom"
Focusable="false"
Visibility="Collapsed" />
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="true">
<Setter TargetName="ExpandSite" Property="Visibility" Value="Visible" />
</Trigger>
<Trigger Property="ExpandDirection" Value="Up">
<Setter TargetName="HeaderSite" Property="Background" Value="Red" />
<Setter TargetName="ExpandSite" Property="DockPanel.Dock" Value="Top" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Name}" Value="Title">
<Setter Property="IsEnabled" Value="False" />
<Setter Property="IsExpanded" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
<!-- Styles the column headers -->
<Style TargetType="{x:Type GridViewColumnHeader}">
<!-- Add the event handler for a right click on the header -->
<EventSetter Event="MouseRightButtonUp" Handler="GridViewColumnHeader_MouseRightButtonUp" />
<Setter Property="Background" Value="{StaticResource GradientBrush}" />
<Setter Property="ClickMode" Value="Press" />
<Setter Property="FontSize" Value="12" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="{StaticResource LightBackgroundBrush}" />
<Setter Property="Height" Value="30" />
<Setter Property="MinWidth" Value="20" />
<!-- Offset the column headers to match the column data as the expanders will have offset the data -->
<Setter Property="RenderTransform">
<Setter.Value>
<TranslateTransform X="13" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GridViewColumnHeader}">
<Border BorderBrush="Black" BorderThickness="1,0,0,1">
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- The two column re sizers -->
<Thumb x:Name="PART_HeaderGripper"
Width="18"
Margin="0,0,-10,0"
HorizontalAlignment="Right"
Background="Black"
Cursor="SizeWE">
<Thumb.Template>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Padding="{TemplateBinding Padding}" Background="Transparent">
<Rectangle Width="1"
HorizontalAlignment="Center"
Fill="{TemplateBinding Background}" />
</Border>
</ControlTemplate>
</Thumb.Template>
</Thumb>
<!-- The main content of the header -->
<ContentPresenter Name="HeaderContent"
Grid.Column="0"
Margin="5"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.Resources>
<!-- Templates each level -->
<ListView.GroupStyle>
<!-- Style for groups at the top level. this level is equivalent to a single database -->
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Margin" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Border Margin="1"
Background="{StaticResource FandFBrush}"
BorderBrush="Black"
BorderThickness="2"
CornerRadius="3">
<Expander Margin="0"
FontSize="12"
FontWeight="Bold"
Foreground="{StaticResource LightBackgroundBrush}"
Header="{Binding Name}"
IsExpanded="True">
<ItemsPresenter x:Name="IP"
Margin="0"
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
VirtualizingPanel.ScrollUnit="Item"
VirtualizingPanel.VirtualizationMode="Recycling" />
</Expander>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
<!-- Style for groups at the second level. this level is equivalent to a single case -->
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Margin" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Border Margin="0"
Background="{StaticResource MainBackgroundBrush}"
BorderBrush="Black"
BorderThickness="2"
CornerRadius="3">
<Expander Margin="0"
FontSize="12"
FontWeight="Bold"
Foreground="{StaticResource LightBackgroundBrush}"
Header="{Binding Name}"
IsExpanded="True">
<ItemsPresenter x:Name="IP"
Margin="0"
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
VirtualizingPanel.ScrollUnit="Item"
VirtualizingPanel.VirtualizationMode="Recycling" />
</Expander>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
<!-- Style for groups at the third level. this level is equivalent to a single sample type -->
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Margin" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Border Margin="1"
BorderBrush="Black"
BorderThickness="0"
CornerRadius="3">
<ItemsPresenter x:Name="IP"
Margin="0"
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
VirtualizingPanel.ScrollUnit="Item"
VirtualizingPanel.VirtualizationMode="Recycling" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
<!-- Style for groups at the fourth level. this level is equivalent to a single sample -->
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Margin" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Border Margin="0,0,0,1"
Background="Transparent"
BorderBrush="Black"
BorderThickness="2,2,2,2"
CornerRadius="3,3,0,0"
Visibility="{Binding Items[0].Fragment.Sample.IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}">
<Expander Margin="0"
FontSize="12"
FontWeight="Bold"
Foreground="Black"
IsExpanded="True">
<Border Grid.Row="0"
Margin="1,0,1,1"
Background="{StaticResource MainBackgroundBrush}"
BorderBrush="Black"
BorderThickness="2,1,2,2"
CornerRadius="2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- The measurements themselves -->
<Border Grid.Row="0"
Margin="0"
Background="{StaticResource MainBackgroundBrush}"
BorderBrush="Black"
BorderThickness="0,0,0,1"
CornerRadius="0">
<ItemsPresenter x:Name="IP"
Margin="0"
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
VirtualizingPanel.ScrollUnit="Item"
VirtualizingPanel.VirtualizationMode="Recycling" />
</Border> </Grid>
</Border>
</Expander>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>

WPF Scrollbar over content

I am working on a custom style for the scrollbar on the scrollviewer. It is working fine but I want the scrollbar to be on top of the content so my controls width won't break because of the scrollbar.
As you can see here the control on top breaks because of the scrollbar. Do you guys know how to make my scrollbars background some kind of transparent so my control will be behind the scrollbar?
Resource
<Window.Resources>
<Style x:Key="ListboxStyle" TargetType="ListBox">
<Style.Resources>
<Style x:Key="ScrollBarThumbVertical" TargetType="{x:Type Thumb}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Rectangle x:Name="rectangle" Fill="#CDCDCD" Height="{TemplateBinding Height}" SnapsToDevicePixels="True" Width="{TemplateBinding Width}"/>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Fill" TargetName="rectangle" Value="#A6A6A6"/>
</Trigger>
<Trigger Property="IsDragging" Value="true">
<Setter Property="Fill" TargetName="rectangle" Value="#606060"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="RepeatButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<Grid>
<ContentPresenter></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ScrollBar}">
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="false"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="false"/>
<Setter Property="BorderThickness" Value="1,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollBar}">
<Grid x:Name="Bg" Width="8" Margin="0,15,0,15" Background="Transparent" SnapsToDevicePixels="true">
<Grid.RowDefinitions>
<RowDefinition MaxHeight="0"/>
<RowDefinition Height="0.00001*"/>
<RowDefinition Height="0"/>
</Grid.RowDefinitions>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0" Background="Transparent" Grid.Row="1"/>
<RepeatButton Height="0" Width="0" x:Name="PART_LineUpButton" Command="{x:Static ScrollBar.LineUpCommand}" IsEnabled="{TemplateBinding IsMouseOver}"/>
<Track x:Name="PART_Track" IsDirectionReversed="true" IsEnabled="{TemplateBinding IsMouseOver}" Grid.Row="1">
<Track.DecreaseRepeatButton>
<RepeatButton Command="{x:Static ScrollBar.PageUpCommand}" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" />
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Command="{x:Static ScrollBar.PageDownCommand}" Background="Transparent" BorderBrush="Transparent" BorderThickness="0" />
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource ScrollBarThumbVertical}"/>
</Track.Thumb>
</Track>
<RepeatButton x:Name="PART_LineDownButton" Height="0" Width="0" Command="{x:Static ScrollBar.LineDownCommand}" IsEnabled="{TemplateBinding IsMouseOver}" Grid.Row="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ScrollViewer}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid x:Name="Grid" HorizontalAlignment="Right">
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Margin="{TemplateBinding Padding}" />
<ScrollBar x:Name="PART_VerticalScrollBar" HorizontalAlignment="Right" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
</Style>
</Window.Resources>
Xaml
<ListBox Style="{StaticResource ListboxStyle}" Height="400" Width="150" ScrollViewer.HorizontalScrollBarVisibility="Hidden">
<TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
<TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
<TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
<TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
<TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
<TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
<TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
<TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
<TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
<TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
<TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
<TextBlock Text="29/6/2014 9:58:00 Datetime value" Margin="10"></TextBlock>
</ListBox>
Result
The ScrollBar is placed in a Grid by the parent ScrollViewer, so you'll need to provide a new ControlTemplate for that. You can use the Grid.RowSpan and Grid.ColumnSpan to make the ScrollViewer content stretch to fill the available space. Try something like this:
<Style TargetType="{x:Type ScrollViewer}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollContentPresenter Grid.ColumnSpan="2" Grid.RowSpan="2" />
<ScrollBar Grid.Column="1" x:Name="PART_VerticalScrollBar"
Value="{TemplateBinding VerticalOffset}" Maximum="{
TemplateBinding ScrollableHeight}" ViewportSize="{
TemplateBinding ViewportHeight}" Background="Transparent" />
<ScrollBar Grid.Row="1" x:Name="PART_HorizontalScrollBar"
Orientation="Horizontal" Value="{TemplateBinding
HorizontalOffset}" Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Background="Transparent" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

WPF Expander control dropdown panel

I would like to style my expander control in such way that it can have a drop down panel like that of combobox control.
Drop down panel should be like it can overlay above other items like that of combobox.
Here's the XAML style for expander which i'm using :
<Style TargetType="{x:Type Expander}">
<Setter Property="Background" Value="{StaticResource Brush_ButtonFill}"/>
<Setter Property="BorderBrush" Value="{StaticResource Brush_ContainerButtonBorder}"/>
<Setter Property="Foreground" Value="{StaticResource Brush_FontReadonly}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" x:Name="ContentRow"/>
</Grid.RowDefinitions>
<Border Visibility="Collapsed" Grid.Row="1" x:Name="ExpandSite" Background="{StaticResource BrushTransparent}" BorderBrush="{StaticResource Brush_DropdownShadow}">
<ContentPresenter Focusable="false"/>
</Border>
<Border Grid.Row="0" x:Name="Border" Background="{StaticResource Brush_ButtonBorder}" Visibility="Collapsed" BorderThickness="1"/>
<ToggleButton Template="{StaticResource ExpanderToggleButtonControlTemplate}" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" OverridesDefaultStyle="True" Background="{StaticResource Brush_ButtonFill}" BorderBrush="{StaticResource Brush_ButtonBorder}" BorderThickness="{TemplateBinding BorderThickness}" Foreground="{StaticResource Brush_ButtonBorder}" d:LayoutOverrides="VerticalAlignment" />
<ContentPresenter Margin="15,2,2,2" RecognizesAccessKey="True" ContentSource="Header" VerticalAlignment="Center" HorizontalAlignment="Left" IsHitTestVisible="False"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter Property="Visibility" Value="Visible" TargetName="ExpandSite"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderStyle_Dropdown" TargetType="{x:Type Expander}" BasedOn="{StaticResource TextStyle_BaseControl}">
<Setter Property="Background" Value="{StaticResource Brush_ButtonFill}"/>
<Setter Property="BorderBrush" Value="{StaticResource Brush_ButtonBorder}"/>
<Setter Property="Foreground" Value="Black"/>
<!--<Setter Property="Foreground" Value="{StaticResource Brush_FontReadonly}"/>-->
<Setter Property="FontSize" Value="{StaticResource FontSizeMedium}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="54"/>
<RowDefinition Height="*" x:Name="ContentRow"/>
</Grid.RowDefinitions>
<Border Visibility="Collapsed" Grid.Row="1" x:Name="ExpandSite" Background="{StaticResource Brush_ButtonShadow}" CornerRadius="0,0,5,5" Margin="0,-5,0,0" Panel.ZIndex="1000">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Focusable="false" Margin="5,10,5,5" Panel.ZIndex="1000"/>
</Border>
<Border Grid.Row="0" x:Name="Border" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="7" Padding="5" Background="{StaticResource Brush_CZBlueSelected}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Border Grid.Row="0" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="5,0,0,5" Padding="5" Grid.ColumnSpan="1" Margin="0,0,1,0"/>
<Border x:Name="Shadow" CornerRadius="5" Padding="5" Grid.ColumnSpan="2" BorderBrush="{StaticResource Brush_SearchinputBorder}" BorderThickness="0,0,0,2" Margin="0,0,0,-2"/>
<ToggleButton Template="{StaticResource ExpanderToggleButtonControlTemplate_DropDown}" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" OverridesDefaultStyle="True" Background="{StaticResource Brush_ButtonFill}" BorderBrush="{StaticResource Brush_ButtonBorder}" Grid.Column="1" BorderThickness="{TemplateBinding BorderThickness}" Foreground="{StaticResource Brush_ButtonBorder}" Margin="1,0,0,0" Height="44" />
<ContentPresenter Margin="4" RecognizesAccessKey="True" ContentSource="Header" VerticalAlignment="Center" HorizontalAlignment="Center" IsHitTestVisible="False"/>
</Grid>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter Property="Visibility" Value="Visible" TargetName="ExpandSite"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now using the same in XAML screen as:
<Expander Name="expanderNextScan" Header="{Binding ElementName=listBoxExpander,Path=SelectedItem.Content}" ExpandDirection="Up" Grid.Column="3" Height="54" Width="Auto" Style="{DynamicResource ExpanderStyle_Dropdown}" >
<Grid Background="#FFE5E5E5" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<ListBox x:Name="listBoxExpander" Height="100" Width="{Binding ElementName=expanderNextScan,Path=ActualWidth}" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Visible" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" Margin="0,-10,0,0" Panel.ZIndex="5">
<ListBoxItem Content="Go to Next Scan" FontSize="{StaticResource FontSizeMedium}" IsSelected="True"/>
<ListBoxItem FontSize="{StaticResource FontSizeMedium}" Content="Print with preview" />
<ListBoxItem FontSize="{StaticResource FontSizeMedium}" Content="Export as PDF"/>
<ListBoxItem FontSize="{StaticResource FontSizeMedium}" Content="Export to DICOM"/>
</ListBox>
</Grid>
</Expander>
Now want to style it in such a way that the list box coming in the expander drop down should have a z-index greater than the other controls on the screen such that it can overlay over other controls like that of combobox dropdown.
Please reply ASAP.

WPF Drop Shadow Trigger

I am creating a button style. Paste this into a window to see the idea:
<Style x:Key="SelectionButton3"
TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ClipToBounds="False">
<Grid.RowDefinitions>
<RowDefinition Height="75"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="TheBorder"
BorderThickness="0,1.5,1.5,1.5"
CornerRadius="3"
Background="SteelBlue"
Height="35"
Grid.Column="1"
Grid.Row="0"
Margin="-31"
BorderBrush="DarkSlateBlue">
<Border.BitmapEffect>
<DropShadowBitmapEffect x:Name="BorderShadow"
ShadowDepth="0"/>
</Border.BitmapEffect>
</Border>
<Rectangle Fill="SteelBlue"
Stroke="DarkSlateBlue"
Grid.Row="0"
Grid.Column="0">
<Rectangle.LayoutTransform>
<RotateTransform Angle="-45" />
</Rectangle.LayoutTransform>
<Rectangle.BitmapEffect>
<DropShadowBitmapEffect ShadowDepth="5"/>
</Rectangle.BitmapEffect>
</Rectangle>
<ContentPresenter x:Name="ContentArea"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Content="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground"
Value="LightGray" />
<Setter Property="FontFamily"
Value="Segoe UI" />
</Style>
<Button Click="Button_Click"
Style="{StaticResource SelectionButton3}"
Width="185">
</Button>
What I would like to have happen is for the Borders drop shadow to appear when the mouse is over either the Border or the Rectangle. I know I need a trigger, but I'm not really sure where & how to do it.
Can someone point me in the right direction?
Thanks
<Style x:Key="SelectionButton3"
TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ClipToBounds="False">
<Grid.RowDefinitions>
<RowDefinition Height="75"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="TheBorder"
BorderThickness="0,1.5,1.5,1.5"
CornerRadius="3"
Background="SteelBlue"
Height="35"
Grid.Column="1"
Grid.Row="0"
Margin="-31"
BorderBrush="DarkSlateBlue">
</Border>
<Rectangle Name="rect" Fill="SteelBlue"
Stroke="DarkSlateBlue"
Grid.Row="0"
Grid.Column="0">
<Rectangle.LayoutTransform>
<RotateTransform Angle="-45" />
</Rectangle.LayoutTransform>
</Rectangle>
<ContentPresenter x:Name="ContentArea"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Content="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="TheBorder" Property="BitmapEffect">
<Setter.Value>
<DropShadowBitmapEffect ShadowDepth="0" />
</Setter.Value>
</Setter>
<Setter TargetName="rect" Property="BitmapEffect">
<Setter.Value>
<DropShadowBitmapEffect ShadowDepth="5"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground"
Value="LightGray" />
<Setter Property="FontFamily"
Value="Segoe UI" />
</Style>
Note that unless you're using .NET 3.0 or 3.5 pre SP1, you should use Effect instead of BitmapEffect. The BitmapEffect property has been deprecated in 3.5 SP1

How to make WPF DataGrid scrollbar cover the non-scrollable area as well?

I'm not sure if this is just my machine (WinXP SP3), because I have not seen it in other people's screenshots.
It looks to me that the scrollbars in DataGrid only cover the scrollable area. That means, the column and row header areas and the bottom right corner are shown in background color, which looks ugly to me. How can I make the scrollbar to extend to the edge of the control (like more regular control)? Is there is property in DataGrid for this?
You may not see it if you didn't change the background color of the DataGrid. I have a screenshot here to illustrate this problem.
Okay, after some struggling, I figured it out myself. In case anybody cares...put this style into you App.xaml.
<ControlTemplate x:Key="SelectAllButtonTemplate" TargetType="{x:Type Button}">
<Grid>
<Rectangle x:Name="Border"
Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
SnapsToDevicePixels="True" />
<Polygon x:Name="Arrow"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Margin="8,8,3,3"
Opacity="0.15"
Fill="Black"
Stretch="Uniform"
Points="0,10 10,10 10,0" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Stroke" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Border" Property="Fill" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Arrow" Property="Visibility" Value="Collapsed" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style TargetType="{x:Type DataGrid}">
<Setter Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderBrush" Value="#FF688CAF" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected" />
<Setter Property="ScrollViewer.CanContentScroll"
Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True"
Padding="{TemplateBinding Padding}">
<ScrollViewer Focusable="false"
Name="DG_ScrollViewer">
<ScrollViewer.Template>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!--Left Column Header Corner -->
<Button Command="{x:Static DataGrid.SelectAllCommand}"
Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=CellsPanelHorizontalOffset}"
Template="{StaticResource SelectAllButtonTemplate}"
Focusable="false"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.All}}" />
<!--Column Headers-->
<DataGridColumnHeadersPresenter Grid.Column="1"
x:Name="PART_ColumnHeadersPresenter"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.Column}}"/>
<!--DataGrid content-->
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" Grid.Row="1" Grid.ColumnSpan="2" CanContentScroll="{TemplateBinding CanContentScroll}" />
<!-- Changed Grid.Row="1" to Grid.Row="0" Grid.RowSpan="2" to make the scrollbar start from top -->
<ScrollBar Grid.Row="0" Grid.RowSpan="2" Grid.Column="2" Name="PART_VerticalScrollBar"
Orientation="Vertical"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>
<!--Grid Grid.Row="2" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type dg:DataGrid}}, Path=NonFrozenColumnsViewportHorizontalOffset}"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollBar Grid.Column="1"
Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
</Grid-->
<!-- Make the scrollbar to start from left edge -->
<ScrollBar Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2"
Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
</Style.Triggers>
</Style>

Resources