Why is my style in Generic.xaml not working? - wpf

I'm cleaning up App.xaml and moved some styles into Generic.xaml. But then, these styles don't have any effect. Why? Is this correct thing to do to make App.xaml tidy?
EDIT (to include some source code):
The goal is to restyle WPF DataGrid to make the scrollbars run from top to bottom and from left to right (default style excludes row and column header).
The style is working when I put it in App.xaml. Because it's a big chunk of code, I'd like to move it out of App.xaml into /Themes/DataGridEx.xaml. By the way, DataGridEx is my extended class derived from WPF DataGrid.
This is my DataGrid.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 local:DataGridEx}" x:Key="{x:Type local:DataGridEx}">
<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 local:DataGridEx}">
<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 local:DataGridEx.SelectAllCommand}"
Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:DataGridEx}}, Path=CellsPanelHorizontalOffset}"
Template="{StaticResource SelectAllButtonTemplate}"
Focusable="false"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:DataGridEx}}, Path=HeadersVisibility, Converter={x:Static local:DataGridEx.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.All}}" />
<!--Column Headers-->
<DataGridColumnHeadersPresenter Grid.Column="1"
x:Name="PART_ColumnHeadersPresenter"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:DataGridEx}}, 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>
This is my Themes/Generic.xaml:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes/DataGridEx.xaml"/>
<ResourceDictionary Source="/Themes/GridComboBox.xaml"/>
</ResourceDictionary.MergedDictionaries>
This is my App.xaml:
<Application x:Class="MyApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyApp.Common"
DispatcherUnhandledException="Application_DispatcherUnhandledException">
<!--StartupUri="MainWindow.xaml"-->
<Application.Resources>
<ResourceDictionary x:Key="rd">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes/Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
....
</Application.Resources>
</Application>
With this code, I got a run-time XamlParseException: "Failed to create a 'Type' from the text 'local:DataGridEx'". However, if I comment out the MergedDictionaries in App.xaml, it doesn't complain, but the style doesn't take effect either.
Another interesting thing is that, in this generic.xaml I have two dictionaries. If I remove the ResourceDictionary from App.xaml, GridComboBox.xaml is working fine, but DataGridEx.xaml is not.

You need to merge it into App.xaml like this:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
If you are already doing that, you need to post your code to give more info.
EDIT:
Try following the instructions here. Particularly, the parts about having to set your dictionaries to Resource and using the full path in Source.

I encountered this issue and the simplest fix for this is to remove the x:Key property of the style to be used in the ResourceDictionary.
<ControlTemplate TargetType="{x:Type Button}">

Related

How can I set ScrollContentPresenter a backgroundcolor?

How can I give ScrollContentPresenter a backgroundcolor? is the same question, but I set the Background on the Parent of the ScrollContentPresenter. It is the Grid and it does not work for me. I can not change the background.
<Style x:Key="ScrollViewerStyle" TargetType="{x:Type ScrollViewer}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Border x:Name="border" BorderBrush="{Binding L1, Source={x:Static color:DesignBrushCollection.DesignColors}}" BorderThickness="1">
<Grid x:Name="Grid" Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid Background="Red">
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" />
</Grid>
<ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"
Style="{DynamicResource ScrollBarStyle}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border"
Value="{Binding AC3, Source={x:Static color:DesignBrushCollection.DesignColors}}"/>
</Trigger>
<Trigger Property="IsFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border"
Value="{Binding AC3, Source={x:Static color:DesignBrushCollection.DesignColors}}"/>
<Setter Property="Background" TargetName="border"
Value="{Binding BG1, Source={x:Static color:DesignBrushCollection.DesignColors}}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" TargetName="border" Value="0.5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid Width="auto" Height="auto">
<Grid.RowDefinitions>
<RowDefinition Height="15" />
<RowDefinition Height="3" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions >
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<local:CommonLabel RequiredMark="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type local:CommonComboBox}},Path=RequiredMark}"
FontSize="13" Padding="0"
Content="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type local:CommonComboBox}},Path=Content}"
Grid.Row="0" Height="16" Width="139"
Margin="0,0,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Grid.ColumnSpan="2" />
<ScrollViewer Style="{StaticResource ScrollViewerStyle}" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Grid.Row="2">
<TextBox x:Name="TextField" TextWrapping="Wrap" BorderThickness="0" CaretBrush="{Binding AC3, Source={x:Static color:DesignBrushCollection.DesignColors}}"
Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:CommonTextField}},Path=Content,Mode=OneWay}" >
</TextBox>
</ScrollViewer>
</Grid>
</UserControl>
TextBox.Background does override the ScrollViewer.Background. If you set TextBox.Background = "Transparent" or TextBox.Background = "{x:Null}" you will see ScrollViewer.Background.
<TextBox x:Name="TextField" Background="Transparent" ... />
Be aware, that ScrollViewer.IsFocused set to true if you click the border of ScrollViewer or set the focus in code behind, not if you input a text in the TextBox.

Format the HierachicalDatatemplate for a TreeView

I am trying to make a TreeView in XAML and it works well.
1) I have a Class containing a Name and a list of Children
<TreeView x:Name="TreeViewOffset" ItemsSource="{Binding OffsetsCollection}" VM:TreeViewHelper.SelectedItem="{Binding MyCollection, Mode=TwoWay}" Margin="19,32,59,33" AutomationProperties.IsColumnHeader="True">
<TreeViewContainer>Some Properties</TreeViewContainer>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type VM:ParentViewModel}" ItemsSource="{Binding Children}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Reference"
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition SharedSizeGroup="Ref"/>
<RowDefinition SharedSizeGroup="Value"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Text="{Binding MyName}" Margin="10, 10, 10,10 "/>
</Grid>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type VM:ChildrenViewModel}">
<Grid >
<Grid.ColumnDefinitions>
<!--Placeholders for two columns of ToggleButton-->
<ColumnDefinition SharedSizeGroup="RefName"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition SharedSizeGroup="Name"/>
<RowDefinition SharedSizeGroup="Value"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding ChildrenValue}" Grid.Column="1" Margin="25, 0,0, 0" />
</Grid>
</DataTemplate>
</TreeView.Resources>
2) I want to improve the display by adding an another textbox (who is contained in the ParentViewModel) but this time at the end of the childrens
It Should be exactly like :
Parent : Name
Children1 Value
Children2 Value
Children3 Value
Children4 Value
Value
And this is the problem, how to improve the XAML to show the value?
I have tried to insert under
<TextBlock Grid.Column="0" Text="{Binding MyName}" Margin="10, 10, 10,10 "/>
this
<TextBlock Grid.Column="0" Grid.Row="1" Text="{Binding Value}" Margin="10, 10, 10,10 "/>
but it doesnt work. It is all a question about formatting but I'am not expert enough. Could you help me?
What you need to set is the ItemContainerStyle for the TreeView
A good starting point would be something like this
<Style x:Key="myTreeViewItemContainerStyle" TargetType="{x:Type TreeViewItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="14" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ToggleButton
x:Name="Expander"
Grid.Row="0"
Grid.Column="0"
ClickMode="Press"
IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
Style="{StaticResource myExpandCollapseToggleStyle}" />
<Border
x:Name="PART_Border"
Grid.Row="0"
Grid.Column="1"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter
x:Name="PART_Header"
Margin="0,2"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
ContentSource="Header" />
</Border>
<ItemsPresenter
x:Name="ItemsHost"
Grid.Row="1"
Grid.Column="1" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="Expander" Property="Visibility" Value="Hidden" />
</Trigger>
<!-- Use the same colors for a selected item, whether the TreeView is focussed or not -->
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="PART_Border" Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Which you can apply to the TreeView by setting its style
<Style TargetType="{x:Type TreeView}">
<Setter Property="ItemContainerStyle" Value="{StaticResource myTreeViewItemContainerStyle}" />
</Style>
For your requirement, you need to add another control after the ItemsPresenter, which you then bind to the property you want to display.

How do I set combobox background colour when it gets focus

I'm relatively new to WPF, so bear with me.
I'm trying to set the background colour of a combo box when it receives focus. I'm setting a trigger in the control template for it's togglebutton to change colour on mouse over, and when it receives focus. Mouse over works fine, but when I tab into the combobox nothing happens until I tab a second time(It changes colour then).
So what I want is for the background colour to change when the user first tabs in.
Any help would be greatly appreciated.
<SolidColorBrush x:Key="ComboBoxNormalBorderBrush" Color="Black" />
<SolidColorBrush x:Key="ComboBoxNormalBackgroundBrush" Color="#fff" />
<SolidColorBrush x:Key="ComboBoxDisabledForegroundBrush" Color="#888" />
<SolidColorBrush x:Key="ComboBoxDisabledBackgroundBrush" Color="#eee" />
<SolidColorBrush x:Key="ComboBoxDisabledBorderBrush" Color="#888" />
<ControlTemplate TargetType="ToggleButton" x:Key="ComboBoxToggleButtonTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Border
Grid.ColumnSpan="2"
Name="Border"
BorderBrush="{StaticResource ComboBoxNormalBorderBrush}"
CornerRadius="0" BorderThickness="0.6"
Background="{StaticResource YellowBrush}">
</Border>
<Border
Grid.Column="1"
Margin="1"
BorderBrush="#444"
Name="ButtonBorder"
CornerRadius="0, 0, 0, 0"
BorderThickness="2"
Background="Gray" />
<Path Name="Arrow" Grid.Column="1"
Data="M0,0 L0,2 L4,6 L8,2 L8,0 L4,4 z"
HorizontalAlignment="Center" Fill="White"
VerticalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource YellowBrush1}" />
</Trigger>
<Trigger Property="ToggleButton.IsFocused" Value="True">
<Setter TargetName="Border" Property="Background" Value="{StaticResource YellowBrush1}" />
</Trigger>
<Trigger Property="UIElement.IsMouseOver" Value="True">
<Setter Property="Panel.Background" TargetName="ButtonBorder" Value="DarkGray"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter Property="Panel.Background" TargetName="ButtonBorder" Value="LightGray"/>
<Setter Property="Shape.Fill" TargetName="Arrow" Value="Black"/>
</Trigger>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter Property="Panel.Background" TargetName="Border" Value="{StaticResource ComboBoxDisabledBackgroundBrush}"/>
<Setter Property="Panel.Background" TargetName="ButtonBorder" Value="{StaticResource ComboBoxDisabledBackgroundBrush}"/>
<Setter Property="Border.BorderBrush" TargetName="ButtonBorder" Value="{StaticResource ComboBoxDisabledBorderBrush}"/>
<Setter Property="TextElement.Foreground" Value="{StaticResource ComboBoxDisabledForegroundBrush}"/>
<Setter Property="Shape.Fill" TargetName="Arrow" Value="#999"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="UIElement.SnapsToDevicePixels" Value="True"/>
<Setter Property="FrameworkElement.OverridesDefaultStyle" Value="True"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="TextElement.Foreground" Value="Black"/>
<Setter Property="Height" Value="25"/>
<Setter Property="Margin" Value="0,0,0,4"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="IsEditable" Value="False"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="FrameworkElement.FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Background" Value="{StaticResource NouvemYellowBrush}"/>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid>
<ToggleButton Name="ToggleButton"
ClickMode="Press"
Focusable="True"
IsChecked="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
Template="{StaticResource ComboBoxToggleButtonTemplate}"/>
<ContentPresenter Name="ContentSite" Margin="5, 3, 23, 3" IsHitTestVisible="False"
HorizontalAlignment="Left" VerticalAlignment="Center"
Focusable="False"
Content="{TemplateBinding ComboBox.SelectionBoxItem}"
ContentTemplate="{TemplateBinding ComboBox.SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"/>
<TextBox Name="PART_EditableTextBox" Margin="3, 3, 23, 3"
IsReadOnly="{TemplateBinding IsReadOnly}"
Visibility="Hidden" Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Center"
Focusable="False">
<TextBox.Template>
<ControlTemplate TargetType="TextBox">
<Border Name="PART_ContentHost" Focusable="False"/>
</ControlTemplate>
</TextBox.Template>
</TextBox>
<!-- Popup showing items -->
<Popup Name="Popup"
Placement="Bottom"
Focusable="False"
AllowsTransparency="True"
IsOpen="{TemplateBinding ComboBox.IsDropDownOpen}"
PopupAnimation="Slide">
<Grid Name="DropDown" SnapsToDevicePixels="True"
MinWidth="{TemplateBinding FrameworkElement.ActualWidth}"
Focusable="False"
MaxHeight="{TemplateBinding ComboBox.MaxDropDownHeight}">
<Border Name="DropDownBorder"
Background="White"
Focusable="False"
Margin="0, 1, 0, 0"
CornerRadius="0"
BorderThickness="1"
BorderBrush="Black"/>
<ScrollViewer Margin="4" SnapsToDevicePixels="True" Focusable="False">
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained" Focusable="False"/>
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ItemsControl.HasItems" Value="False">
<Setter Property="FrameworkElement.MinHeight" TargetName="DropDownBorder" Value="95"/>
</Trigger>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" Value="{StaticResource ComboBoxDisabledForegroundBrush}"/>
</Trigger>
<Trigger Property="ItemsControl.IsGrouping" Value="True">
<Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
</Trigger>
<Trigger Property="ComboBox.IsEditable" Value="True">
<Setter Property="KeyboardNavigation.IsTabStop" Value="False"/>
<Setter Property="UIElement.Visibility" TargetName="PART_EditableTextBox" Value="Visible"/>
<Setter Property="UIElement.Visibility" TargetName="ContentSite" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Edit: showing the relevant view
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<command:EventToCommand Command="{Binding OnLoadingCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
<i:EventTrigger EventName="Unloaded">
<command:EventToCommand Command="{Binding OnClosingCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="11*"/>
<ColumnDefinition Width="14*"/>
<ColumnDefinition Width="14*"/>
<ColumnDefinition Width="14*"/>
<ColumnDefinition Width="14*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height=".2*"/>
<RowDefinition Height="3.5*"/>
<RowDefinition Height="8*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid x:Name="GridGlobalData" Grid.Row="1" Grid.ColumnSpan="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--left side-->
<Label Content="Code _________________________________________________________________________________________________________________"/>
<Label Content="Name _________________________________________________________________________________________________________________" Grid.Row="1"/>
<Label Content="Business Partner Type ________________________________________________________________________" Grid.Row="2"/>
<Label Content="Group _________________________________________________________________________________________________________________" Grid.Row="3"/>
<Label Content="Currency ___________________________________________________________________________________________________________" Grid.Row="4"/>
<TextBox x:Name="TextBoxCode" Text="{Binding PartnerCode, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1">
<TextBox.InputBindings>
<KeyBinding Command="{Binding ControlButtonCommand}" CommandParameter="Add" Key="A" Modifiers="Control" />
<KeyBinding Command="{Binding FindBusinessPartnerCommand}" CommandParameter="Code" Key="Enter"/>
</TextBox.InputBindings>
</TextBox>
<TextBox Text="{Binding PartnerName, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="1">
<TextBox.InputBindings>
<KeyBinding Command="{Binding FindBusinessPartnerCommand}" CommandParameter="Name" Key="Enter"/>
</TextBox.InputBindings>
</TextBox>
<ComboBox ItemsSource="{Binding BusinessPartnerTypes}" DisplayMemberPath="Type" SelectedItem="{Binding PartnerType}" SelectedIndex="0" Grid.Column="1" Grid.Row="2"/>
<ComboBox ItemsSource="{Binding BusinessPartnerGroups}" DisplayMemberPath="BPGroupName" SelectedItem="{Binding PartnerGroup}" SelectedIndex="0" Grid.Column="1" Grid.Row="3"/>
<ComboBox ItemsSource="{Binding BusinessPartnerCurrencies}" DisplayMemberPath="Name" SelectedItem="{Binding PartnerCurrency}" SelectedIndex="0" Grid.Column="1" Grid.Row="4"/>
<!--right side-->
<Label Content="Display Currency _________________________________________________________________________________________________________________" Grid.Column="3" />
<Label Content="Invoices _________________________________________________________________________________________________________________" Grid.Column="3" Grid.Row="1"/>
<Label Content="Deliveries _________________________________________________________________________________________________________________" Grid.Column="3" Grid.Row="2"/>
<Label Content="Orders _________________________________________________________________________________________________________________" Grid.Column="3" Grid.Row="3"/>
<ComboBox ItemsSource="{Binding BusinessPartnerCurrencies}" DisplayMemberPath="Name" SelectedItem="{Binding DisplayCurrency}" Style="{StaticResource StyleComboBoxReadonly}" SelectedIndex="0" Grid.Column="4"/>
<TextBox Style="{StaticResource StyleTextBoxNonEditable}" Grid.Column="4" Grid.Row="1"/>
<TextBox Style="{StaticResource StyleTextBoxNonEditable}" Grid.Column="4" Grid.Row="2"/>
<TextBox Style="{StaticResource StyleTextBoxNonEditable}" Grid.Column="4" Grid.Row="3"/>
</Grid>
<TabControl SelectedIndex="{Binding SelectedPartnerView}" Grid.Row="2" Grid.ColumnSpan="6" >
<TabItem Header="General">
<BusinessPartner:BPGeneralView />
</TabItem>
<TabItem Header="Contacts">
<BusinessPartner:BPContactView />
</TabItem>
<TabItem Header="Addresses">
<BusinessPartner:BPAddressesView />
</TabItem>
<TabItem Header="Payment Terms">
<BusinessPartner:BPPaymentTerms />
</TabItem>
<TabItem Header="Properties">
<BusinessPartner:BPPropertiesView />
</TabItem>
<TabItem Header="Remarks">
<BusinessPartner:BPRemarksView />
</TabItem>
<TabItem Header="Attachments">
<BusinessPartner:BPAttachmentsView />
</TabItem>
</TabControl>
<Grid x:Name="GridCrontrolButtons" Grid.Row="3" Grid.ColumnSpan="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="7*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<data:CrudView Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"/>
</Grid>
</Grid>
You should be able to achieve this by adding an additional IsKeyboardFocused trigger alongside your MouseOver and IsFocused triggers in the ToggleButton control template:
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter TargetName="Border" Property="Background" Value="{StaticResource YellowBrush1}" />
</Trigger>
MSDN: https://msdn.microsoft.com/en-us/library/bb613567%28v=vs.110%29.aspx (Scroll down to IsKeyboardFocused section)
UPDATE:
The problem in this case is to do with where you're setting your triggers. You're relying on the ToggleButton to have focus so that you can change it's background colour - but in actual fact you want to the content of the combobox to have focus.
The reason you have to TAB twice to apparently achieve focus is because for each ComboBox you're tabbing between the control's ToggleButton, and then the ComboBox selected item (through the ContentPresenter).
One possible fix: First you need to prevent your ToggleButton in your ComboBox template from getting focus:
<ToggleButton Name="ToggleButton"
ClickMode="Press"
Focusable="False"
IsTabStop="False" ... >
I've actually removed ALL of the Focusable="False" setters from your ToggleButton template as they're not needed.
Then make your ToggleButton template transparent (Border.Background), and remove the existing triggers that affect the Border.Background colour.
Now move to your ComboBox template and give the root <Grid> a name. I've called it templateRoot in my example.
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid Name="templateRoot">
<ToggleButton Name="ToggleButton" ... >
And now set the background colour for your combobox using that templateRoot. You can add the Triggers you removed from the ToggleButton template to the ComboBox template:
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource YellowBrush1}" />
</Trigger>
... and the other triggers.
With this approach, you're relying on the ComboBox control to trigger your changes when it has focus.
If this solution doesn't work for your needs, then I hope at least you can see where the problem you're having originates.
You shouldn't need to go to the level of editing the template for this, just the style:
<ComboBox>
<ComboBoxItem>Apple</ComboBoxItem>
<ComboBoxItem>Banana</ComboBoxItem>
<ComboBoxItem>Pear</ComboBoxItem>
<ComboBox.Style>
<Style TargetType="{x:Type ComboBox}">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Violet" />
</Trigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>

Styling WPF ScrollViewer To Appear Like VS2010 Tabs Scroller

I'm using AvalonDock to develop a tool for internal use by our developers and QA. I am working on a custom version of the VS2010 style that is provided in the Themes. The style just didn't function enough like VS2010 for me to be happy with it. I've made almost all the color and image changes and I just noticed that the tabs in the DocumentPane do not scroll like VS2010 when there are more tabs than can fit in the header area.
Since I have the complete style in my project I found the area where the styles are applied. I placed a ScrollViewer around the ad:DocumentTabPanel thinking I could somehow restyle the horizontal scrollbar so that there would be an arrow on the left and on the right of the tabs.
Is this possible?
Here is the style after my base modifications but without any modification to the scrollviewer:
<Style x:Key="{x:Type ad:DocumentPane}" TargetType="{x:Type ad:DocumentPane}">
<Setter Property="Background" Value="{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.DefaultBackgroundBrush}}}"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ad:DocumentPane}" >
<ControlTemplate.Resources>
<ContextMenu x:Key="DocumentsListMenu" StaysOpen="True" />
</ControlTemplate.Resources>
<Border
Background="{TemplateBinding Background}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border x:Name="PART_Header"
Grid.Row="0"
Focusable="False"
>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="18"/>
</Grid.ColumnDefinitions>
<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" CanContentScroll="True">
<ad:DocumentTabPanel
x:Name="paneTabsPanel"
Panel.ZIndex ="1"
IsItemsHost="True"
TabItemStyle="{StaticResource CustomDocumentTabItemStyle}"/>
</ScrollViewer>
<Button x:Name="PART_ShowContextMenuButton"
Grid.Column="2"
Width="15" Height="15"
Style="{StaticResource PaneHeaderCommandStyle}">
<Image x:Name="ShowContextMenuIcon" Source="pack://application:,,,/Images/Dev2010/PinMenu.png" Width="13" Height="13" Stretch="None"/>
</Button>
</Grid>
</Border>
<Grid Grid.Row="1">
<Border
x:Name="topBorder"
Height="4"
Background="{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.DocumentHeaderBorder}}}"
CornerRadius="2,2,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Stretch"
>
</Border>
<Border
x:Name="bottomBorder"
Height="4"
Background="{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.DocumentHeaderBorder}}}"
CornerRadius="0,0,2,2"
VerticalAlignment="Bottom"
HorizontalAlignment="Stretch"
>
</Border>
<ContentPresenter
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedItem.Content}"
Margin="0,4,0,4"
KeyboardNavigation.TabNavigation="Local"
KeyboardNavigation.DirectionalNavigation="Contained"
KeyboardNavigation.TabIndex="1"
/>
</Grid>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="False">
<Setter Property="Visibility" Value="Hidden"/>
</Trigger>
<Trigger Property="ShowHeader" Value="False">
<Setter Property="Visibility" Value="Collapsed" TargetName="PART_Header" />
</Trigger>
<!--<DataTrigger Binding="{Binding Path=IsMainDocumentPane, RelativeSource={RelativeSource Self}}" Value="True">
<Setter Property="Source" Value="pack://application:,,,/Images/Dev2010/PinDockMenu.png" TargetName="ShowContextMenuIcon"/>
</DataTrigger>-->
<Trigger Property="ContainsActiveDocument" Value="True">
<Setter Property="Background"
Value="{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.DocumentHeaderBorderSelected}}}"
TargetName="topBorder"/>
<Setter Property="Background"
Value="{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.DocumentHeaderBorderSelected}}}"
TargetName="bottomBorder"/>
</Trigger>
<Trigger Property="ContainsActiveContent" Value="True">
<Setter Property="Background"
Value="{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.DocumentHeaderBorderSelectedActivated}}}"
TargetName="topBorder"/>
<Setter Property="Background"
Value="{DynamicResource {ComponentResourceKey {x:Type ad:DockingManager}, {x:Static ad:AvalonDockBrushes.DocumentHeaderBorderSelectedActivated}}}"
TargetName="bottomBorder"/>
</Trigger>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
From="0" To="1" Duration="0:0:0.200" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I did something like this in the past, and found it easiest to hide the ScrollViewer's ScrollBar, and manually scroll the content when two RepeatButtons are pressed.
The code I originally started with can be found here, but the basic idea is to overwrite the ScrollViewer's template to look something like this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<RepeatButton Grid.Column="0" Command="ScrollBar.PageLeftCommand" Content="<" />
<RepeatButton Grid.Column="2" Command="ScrollBar.PageRightCommand" Content=">" />
<ScrollContentPresenter Grid.Column="1" Content="{TemplateBinding ScrollViewer.Content}"/>
</Grid>

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