When developing a custom control in WPF I noticed a strange clipping behavior. When I resize the control under a certain minimum boundaries/tress-hold it decides to clip the top 24 pixels of the control for reasons I don't understand.
It would be much appreciated if somebody could explain how i can achieve the desired graphical effect without clipping behavior as illustrated.
The behavior occurs with the following XAML. Note that the XAML is a stripped down to make the it compliant with standard .net 4.0 controls.
<Style x:Key="{ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Rectangle x:Name="Border" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" SnapsToDevicePixels="True"/>
<Polygon x:Name="Arrow" Fill="Black" HorizontalAlignment="Right" Margin="8,8,3,3" Opacity="0.15" Points="0,10 10,10 10,0" Stretch="Uniform" VerticalAlignment="Bottom"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Stroke" TargetName="Border" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Fill" TargetName="Border" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Visibility" TargetName="Arrow" Value="Collapsed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DataGridStyle1" 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="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<Border Background="Transparent" Margin="0,24,0,0" >
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="True">
<ScrollViewer x:Name="DG_ScrollViewer" Focusable="false">
<ScrollViewer.Template>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Command="{x:Static DataGrid.SelectAllCommand}" Focusable="false" Style="{DynamicResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}}" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.All}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Width="{Binding CellsPanelHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
<DataGridColumnHeadersPresenter Grid.Row="0" x:Name="PART_ColumnHeadersPresenter" Grid.Column="1" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
<Grid VerticalAlignment="Top" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="1" ClipToBounds="False">
<Grid.RenderTransform>
<TranslateTransform Y="-24" />
</Grid.RenderTransform>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Fill="Yellow" Grid.Row="1" Grid.ColumnSpan="3" Grid.Column="1" Height="48" />
</Grid>
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
</Style.Triggers>
</Style>
<DataGrid AutoGenerateColumns="False" HorizontalAlignment="Left" Margin="12,12,0,12" Name="dataGrid1" Width="868" FrozenColumnCount="2"
ScrollViewer.HorizontalScrollBarVisibility="Visible" CanUserSortColumns="False" CanUserReorderColumns="False"
AreRowDetailsFrozen="True" CanUserAddRows="False" Style="{StaticResource DataGridStyle1}"
ScrollViewer.VerticalScrollBarVisibility="Visible">
<DataGrid.Columns>
<DataGridTextColumn Header="Layer Name" Width="250" IsReadOnly="True" />
<DataGridHyperlinkColumn Header="" Width="150" IsReadOnly="True" />
<DataGridTemplateColumn Width="*" HeaderStyle="{StaticResource DataGridColumnHeaderStyle}" IsReadOnly="True">
<DataGridTemplateColumn.Header>
<Grid Height="18">
<TextBlock Text="100.0f" Margin="0,-10" />
</Grid>
</DataGridTemplateColumn.Header>
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<StackPanel>
<TextBlock Text="test" />
<ItemsPresenter />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
So after a few days of fiddling I found the culprit to be GetLayoutClip method. This method returns clipping geometry only if the bounds of the control is smaller than the minimum bounds.
Easiest solution to override this behavior was to make a custom control inherit from the said base control. And to construct new clipping geometry with the extra margin taken into account.
Related
I have an DataGrid on which I used a style which looks like that:
<Style x:Key="DataGridStyle" TargetType="{x:Type DataGrid}">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderBrush" Value="#FF688CAF"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<Border Background="{TemplateBinding Background}" CornerRadius="20" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="DG_ScrollViewer" Focusable="false">
<ScrollViewer.Template>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button Command="{x:Static DataGrid.SelectAllCommand}" Focusable="false" Style="{DynamicResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}}" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.All}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Width="{Binding CellsPanelHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
<DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" Grid.Column="1" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" Grid.ColumnSpan="2" Grid.Row="1"/>
<ScrollBar x:Name="PART_VerticalScrollBar" Grid.Column="2" Maximum="{TemplateBinding ScrollableHeight}" Orientation="Vertical" Grid.Row="1" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>
<Grid Grid.Column="1" Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollBar x:Name="PART_HorizontalScrollBar" Grid.Column="1" Maximum="{TemplateBinding ScrollableWidth}" Orientation="Horizontal" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
</Grid>
</Grid>
</ControlTemplate>
</ScrollViewer.Template>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
</Style.Triggers>
</Style>
and the other DataGrid Code:
<DataGrid Style="{StaticResource DataGridStyle}" Margin="10" SelectionUnit="CellOrRowHeader" AutoGenerateColumns="False"
SelectionMode="Single"
ItemsSource="{Binding Path=collRMA, ElementName=vmRMA,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
x:Name="datagrid" CanUserAddRows="False" CanUserDeleteRows="False"
CanUserResizeRows="True"
GridLinesVisibility="None" ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto" MaxHeight="380"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding artNumber}" Header="artNumber" Visibility="Hidden" Width="*"/>
<DataGridTextColumn Binding="{Binding position}" Header="Pos" Width="0.5*"/>
<DataGridTextColumn Binding="{Binding description}" Header="description" Width="*"/>
</DataGrid.Columns>
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Command="Copy"/>
</ContextMenu>
</DataGrid.ContextMenu>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}" x:Name="test" >
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Height" Value="30"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="Green"/>
<Setter Property="Padding" Value="10 0 0 0"/>
<EventSetter Event="PreviewMouseDoubleClick" Handler="DataGridColumnHeader_PreviewMouseDoubleClick"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid x:Name="insideHeader" Background="Transparent">
<Border x:Name="borderHeader" BorderThickness="0"
CornerRadius="10"
Background="White"
Padding="10,0,0,0"
>
<ContentPresenter />
</Border>
<!--<Thumb HorizontalAlignment="Right"
Grid.Column="1"
Name="PART_HeaderGripper"
Margin="0,4,0,4"
Width="2"/>-->
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{DynamicResource PrimaryBlueColor}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="borderHeader" Property="Background" Value="{DynamicResource SecundaryGrayColor}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type DataGridRowHeader}">
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontFamily" Value="sans-serif"/>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="#333333"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border x:Name="insideBorder" Background="Transparent" BorderThickness="0 2 0 1" BorderBrush="#dddddd">
<Border x:Name="BorderCell" BorderThickness="0"
CornerRadius="6"
Background="White"
Padding="8,5,0,5"
Margin="2">
<ContentPresenter/>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{DynamicResource PrimaryBlueColor}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.Resources>
</DataGrid>
The Problem which I got now, is that when I double Click the Column Header, the Content of the Cell not widht the Content. So the widht doesnt Fit the Content of the Cell if the Cells Content longer then the actual Cell widht. Anyone an Idea why the Cell Content dont update the Widht when I double click the Column Header?
Is there a way on how to open the Calendar Window when clicking DatePickerTextBox ?
Currently, It will open when clicking the "PART_Button" button.
So I want to also open at DatePickerTextBox "PART_TextBox"
Below is my code.
<Style TargetType="{x:Type DatePicker}">
<Setter Property="CalendarStyle" Value="{StaticResource Calendar_Style}" />
<Setter Property="FontFamily" Value="/Fonts/#Poppins"/>
<Setter Property="FontSize" Value="15" />
<Setter Property="FontWeight" Value="Regular"/>
<Setter Property="BorderThickness" Value="1" />
<Setter Property="SelectedDateFormat" Value="Short"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="Focusable" Value="True" />
<Setter Property="IsHitTestVisible" Value="True" />
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Background" Value="{DynamicResource Background}"/>
<Setter Property="BorderBrush" Value="White"/>
<Setter Property="Foreground" Value="{DynamicResource Text}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePicker}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" CornerRadius="4">
<Grid x:Name="PART_Root" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<DatePickerTextBox x:Name="PART_TextBox" Grid.Column="0" Grid.Row="0" Focusable="True" HorizontalAlignment="Left" Padding="5,0,0,0" VerticalAlignment="Center" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
IsReadOnly="True" Background="{DynamicResource Background}" Foreground="White"
Style="{StaticResource DatePickerTextBoxStyle}" Grid.ColumnSpan="2" />
<Button x:Name="PART_Button" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Right" VerticalAlignment="Center" Width="40" Height="40" BorderBrush="{x:Null}">
<iconPacks:Octicons Kind="Calendar"/>
</Button>
<Grid x:Name="PART_DisabledVisual" Grid.ColumnSpan="2" Grid.Column="0" IsHitTestVisible="False" Opacity="0" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="1" Fill="Black" RadiusY="1" Grid.Row="0" RadiusX="1"/>
<Rectangle Grid.Column="0" Fill="Black" Height="18" Margin="3,0,3,0" RadiusY="1" Grid.Row="0" RadiusX="1" Width="19"/>
<Popup x:Name="PART_Popup" AllowsTransparency="True" Placement="Bottom" PlacementTarget="{Binding ElementName=PART_TextBox}" StaysOpen="False"/>
</Grid>
</Grid>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Source={x:Static SystemParameters.HighContrast}}" Value="false">
<Setter Property="Foreground" TargetName="PART_TextBox" Value="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="{DynamicResource MainBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
Thank you very much.
You should be able to add a mouse event where you're using the DatePicker to open the dropdown for the calendar using:
private void OnClick(object sender, RoutedEventArgs e)
{
datePicker.IsDropDownOpen = true;
}
Alternatively, you could implement a custom control over the top of the DatePicker to handle this from the control itself.
I have a 'plus' button (see image) inside big button. How execute command of 'plus' button.
'plus' button in my example is CreateNewFolderButton(first style) and locate in Grid.Column=2 of MakeNewFolderButton(second style).
Tinkering with WindowChrome.IsHitTestVisibleInChrome and IsHitTestVisible doesn't help.
How to get access to the 'plus' button and execute its command with MVVM?
<Style x:Key="CreateNewFolderButton" TargetType="{x:Type Button}" BasedOn="{StaticResource HoverLess}">
<Setter Property="ToolTip" Value="Create Folder"/>
<Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True"/>
<Setter Property="IsHitTestVisible" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Grid >
<Ellipse Width="{StaticResource WidthNavigationAndCreation}" Height="{StaticResource HeightNavigationAndCreation}" />
<Ellipse Width="{StaticResource WidthNavigationAndCreation}" Height="{StaticResource HeightNavigationAndCreation}" x:Name="image" >
<Ellipse.Fill>
<ImageBrush ImageSource="{DynamicResource AddFolder}" />
</Ellipse.Fill>
</Ellipse>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" TargetName="image" Value="{DynamicResource IBAddFolderMouseOver}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="MakeNewFolderButton" TargetType="{x:Type Button}" BasedOn="{StaticResource FolderFileButtons}">
<Setter Property="IsHitTestVisible" Value="False"/>
<Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="0 0 0 0.5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image Width="{StaticResource WidthFolderAndFilesIcon}"
Height="{StaticResource HeightFolderAndFilesIcon}" Source="/Images/FolderAndFiles/BlackEmptyFolder48x48.png"/>
<TextBox Grid.Column="1" Style="{StaticResource TextBoxEnterFileCreation}"
Tag="New Folder Name"
Text="{Binding RelativeSource={RelativeSource AncestorType=Window},
Path=DataContext.NewFolderName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button Grid.Column="2" Style="{StaticResource CreateNewFolderButton}"
Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.MakeFolder}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="border" Value="{StaticResource ButtonBackgroundMouseOver}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
'Plus' button inside big button
As I wrote in comment this code works:
<Button Content="Outer button" Command="{Binding TestCmd}">
<Button.Template>
<ControlTemplate TargetType="ButtonBase">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="AUTO" />
<ColumnDefinition Width="AUTO" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="LABEL CONTENT" Foreground="BlueViolet"/>
<Button Grid.Column="1" Content="INNER BUTTON" Command="{Binding TestCmd2}"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
So if you press "INNER BUTTON" the TestCmd2 being executed and if you click a "LABEL CONTENT" the TestCmd being executed.
Related to this question: How to style the top-left corner of a DataGrid in XAML?
How to customize style for top-left corner of WPF-Toolkit's DataGrid
XAML:
<Window x:Class="Matrix_WPFToolkit_Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
Title="MainWindow" Height="350" Width="525">
<Grid>
<toolkit:DataGrid x:Name="dataGrid" IsReadOnly="True" HeadersVisibility="All" GridLinesVisibility="All" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserResizeRows="False" CanUserSortColumns="False" SelectionMode="Single" SelectionUnit="Cell" RowDetailsVisibilityMode="Visible" SelectionChanged="dataGrid_SelectionChanged" Margin="-1,0,1.4,0.4" SelectedCellsChanged="dataGrid_SelectedCellsChanged">
<toolkit:DataGrid.RowHeaderTemplate>
<DataTemplate>
<TextBlock Text="1"/>
</DataTemplate>
</toolkit:DataGrid.RowHeaderTemplate>
<toolkit:DataGrid.ColumnHeaderStyle>
<Style TargetType="toolkit:DataGridColumnHeader">
<Setter Property="Background" Value="Gray"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="Black"/>
</Style>
</toolkit:DataGrid.ColumnHeaderStyle>
<toolkit:DataGrid.RowHeaderStyle>
<Style TargetType="toolkit:DataGridRowHeader">
<Setter Property="Background" Value="Gray"/>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
</toolkit:DataGrid.RowHeaderStyle>
<toolkit:DataGrid.CellStyle>
<Style TargetType="toolkit:DataGridCell">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Background" Value="LightGray" />
<Setter Property="Foreground" Value="Black" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</toolkit:DataGrid.CellStyle>
<toolkit:DataGrid.RowStyle>
<Style TargetType="toolkit:DataGridRow">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="BorderThickness" Value="0" />
</Trigger>
</Style.Triggers>
</Style>
</toolkit:DataGrid.RowStyle>
</toolkit:DataGrid>
</Grid>
Here I have customized the row header template, column heade style, cell selection style. How to style top-left corner cell in the data-grid (WPF Toolkit's)
Try this, changing Fill color on IsMouseOver:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication2"
xmlns:Custom="http://schemas.microsoft.com/wpf/2008/toolkit"
x:Class="WpfApplication2.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="300">
<Window.Resources>
<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}}" />
<Setter TargetName="Border" Property="Fill" Value="Red" />
</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 x:Key="DataGridStyle1" TargetType="{x:Type Custom: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" />
<!-- This is needed to force DG to have a non-default value. Otherwise the DGR.DetailsVisibility cannot have a value of VisibleWhenSelected by default. -->
<Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected" />
<Setter Property="ScrollViewer.CanContentScroll"
Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Custom: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 Custom:DataGrid.SelectAllCommand}"
Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGrid}}, Path=CellsPanelHorizontalOffset}"
Template="{StaticResource SelectAllButtonTemplate}"
Focusable="false"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGrid}}, Path=HeadersVisibility, Converter={x:Static Custom:DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static Custom:DataGridHeadersVisibility.All}}" />
<!--Column Headers-->
<Custom:DataGridColumnHeadersPresenter Grid.Column="1"
Name="PART_ColumnHeadersPresenter"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGrid}}, Path=HeadersVisibility, Converter={x:Static Custom:DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static Custom:DataGridHeadersVisibility.Column}}"/>
<!--DataGrid content-->
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" Grid.Row="1" Grid.ColumnSpan="2" CanContentScroll="{TemplateBinding CanContentScroll}" />
<ScrollBar Grid.Row="1" 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 Custom: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>
</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>
</Window.Resources>
<Window.DataContext>
<local:MyViewModel/>
</Window.DataContext>
<Grid>
<Custom:DataGrid x:Name="dataGrid1" Margin="0" ItemsSource="{Binding Data}" Style="{StaticResource DataGridStyle1}"/>
</Grid>
Is it possible to create some sort of base expander style and override the background color of the header in a derived style?
In my application I'm using expanders a lot and I would like to change the background color of the header. I know I could just copy&paste my style and edit the color, but it would be nicer to just create a new style based on the "base style" and setting the header's background color.
But I do not know how to access this color.
It's the color of this line: below I'd like to change (the border in the header): Border Name="border"... I cannot access "border" in the setter of the derived style...
This is my (base) style:
<Style TargetType="Expander" x:Key="ExpanderStyle">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextColor}}"/>
<Setter Property="Template">
<Setter.Value>
<!-- Control template for expander -->
<ControlTemplate TargetType="Expander" x:Name="exp">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Name="ContentRow" Height="0"/>
</Grid.RowDefinitions>
<Border Name="border" Grid.Row="0" Background="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" BorderThickness="1" CornerRadius="4,4,0,0" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<ToggleButton x:Name="tb" FontFamily="Marlett" FontSize="9.75" Background="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" Foreground="Black" Grid.Column="1" Content="u" IsChecked="{Binding Path=IsExpanded,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" />
<ContentPresenter x:Name="HeaderContent" Grid.Column="0" Margin="4" ContentSource="Header" RecognizesAccessKey="True" />
</Grid>
</Border>
<Border x:Name="Content" Grid.Row="1" BorderThickness="1,0,1,1" CornerRadius="0,0,4,4" >
<ContentPresenter Margin="4" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="ContentRow" Property="Height" Value="{Binding ElementName=Content,Path=Height}" />
<Setter Property="Content" TargetName="tb" Value="t"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I would like to do something like this:
<Style x:Key="ExpanderStyleRed" BasedOn="{StaticResource ExpanderStyle}" TargetType="Expander">
<Setter Property="???" Value="Red"/>
<Style>
Use TemplateBinding:
<Style TargetType="Expander" x:Key="ExpanderStyle">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextColor}}"/>
<Setter Property="Template">
<Setter.Value>
<!-- Control template for expander -->
<ControlTemplate TargetType="Expander" x:Name="exp">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Name="ContentRow" Height="0"/>
</Grid.RowDefinitions>
<Border Name="border" Grid.Row="0" Background="{TemplateBinding Background}" BorderThickness="1" CornerRadius="4,4,0,0" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<ToggleButton x:Name="tb" FontFamily="Marlett" FontSize="9.75" Background="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" Foreground="Black" Grid.Column="1" Content="u" IsChecked="{Binding Path=IsExpanded,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}" />
<ContentPresenter x:Name="HeaderContent" Grid.Column="0" Margin="4" ContentSource="Header" RecognizesAccessKey="True" />
</Grid>
</Border>
<Border x:Name="Content" Grid.Row="1" BorderThickness="1,0,1,1" CornerRadius="0,0,4,4" >
<ContentPresenter Margin="4" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter TargetName="ContentRow" Property="Height" Value="{Binding ElementName=Content,Path=Height}" />
<Setter Property="Content" TargetName="tb" Value="t"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderStyleRed" BasedOn="{StaticResource ExpanderStyle}" TargetType="Expander">
<Setter Property="Background" Value="#2fff0000"/>
</Style>
And then:
<Grid>
<Expander x:Name="expander1" Style="{DynamicResource ExpanderStyle}" Header="Expander" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="7,10,0,0" Height="108">
<TextBlock Width="250" Height="150" TextWrapping="Wrap">
asklsaklsa saaskklsaklas alsaklalkjd
asklsaklsaklsa saklsaklsakl jsajkjska
saklsaklsakl sasa
</TextBlock>
</Expander>
<Expander x:Name="expander2" Style="{DynamicResource ExpanderStyleRed}" Header="Expander" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="12,126,0,0" Height="133">
<TextBlock Width="250" Height="150" TextWrapping="Wrap">
asklsaklsa saaskklsaklas alsaklalkjd
asklsaklsaklsa saklsaklsakl jsajkjska
saklsaklsakl sasa
</TextBlock>
</Expander>
</Grid>