Unable to apply CellStyle from style defined in ResourceDictionary - wpf

I have defined some styles for a datagrid, but the styles for CellStyle, ColumnHeaderStyle and RowStyle is not applied. Others styles like the background color and rowheight are working fine.
The default style are based on FirstFloor.ModernUI's datagrid styling
If I put the styles directly on the data-grid then everything works fine. also at design-time
<DataGrid
Style="{StaticResource BilagDatagridStyle}"
ColumnHeaderStyle="{StaticResource BilagsColumnHeaderStyle}"
CellStyle="{StaticResource DataGridCellNoInteractionStyle}"
RowStyle="{StaticResource DataGridRowNoInteractionStyle}"
Without it's not working
<DataGrid
Style="{StaticResource BilagDatagridStyle}"
This is the styles that I am using:
<Style x:Key="BilagsColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="FontSize" Value="12"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="4,3"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="DefaultReadOnlyGridStyle" TargetType="{x:Type DataGrid}" BasedOn="{StaticResource {x:Type DataGrid}}">
<Setter Property="CanUserAddRows" Value="False"/>
<Setter Property="CanUserDeleteRows" Value="False"/>
<Setter Property="CanUserSortColumns" Value="False"/>
<Setter Property="AutoGenerateColumns" Value="False"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="IsReadOnly" Value="True"/>
<Setter Property="SelectionMode" Value="Single"/>
<Setter Property="HeadersVisibility" Value="Column"/>
<Setter Property="Width" Value="Auto"/>
<Setter Property="RowHeight" Value="30"/>
<Style x:Key="BilagDatagridStyle" TargetType="{x:Type DataGrid}" BasedOn="{StaticResource DefaultReadOnlyGridStyle}">
<Setter Property="CellStyle" Value="{StaticResource DataGridCellNoInteractionStyle}"/>
<Setter Property="RowStyle" Value="{StaticResource DataGridRowNoInteractionStyle}"/>
<Setter Property="ColumnHeaderStyle" Value="{StaticResource BilagsColumnHeaderStyle}"/>
It's the Template part in the BilagsColumnHeaderStyle that's overwritten. I have been trying to write a separate Template but I cant get the syntax right. Maybe if I split the styling and the template part it will work?
Any suggestions are much appreciated

Related

WPF: disable ListViewItem base on model view property

So I have this ModelView property that changed when my application do my stuff:
private bool isPlay;
public bool IsPlay
{
get { return isPlay; }
set
{
isPlay = value;
NotifyPropertyChanged("IsPlay");
}
}
And when this IsPlay is True I want my ListViewItem IsEnabled = False so this is my Style my ListView using:
<Style TargetType="{x:Type ListView}">
<Setter Property="TextBlock.TextAlignment" Value="Center"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="SelectionMode" Value="Single"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="AlternationCount" Value="2"/>
<!-- ListViewItem -->
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Height" Value="32"/>
<Setter Property="BorderBrush" Value="transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<!--<Setter Property="IsSelected" Value="{Binding IsSelected}" />-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<GridViewRowPresenter Content="{TemplateBinding Content}"
Columns="{TemplateBinding GridView.ColumnCollection}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=IsPlay}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="Gray" Opacity="0.1"/>
</Setter.Value>
</Setter>
<Setter Property="IsEnabled" Value="False"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Setter.Value>
</Setter>
</Style>
The problem is that the ListViewItem IsEnabled not changed so I bind this IsPlay property into some TextBlock to see is its change its state properly (True to False or vice versa) and this working fine but my ListView Style not.
Update
Here the declaration of my View Model (only one instance):
<Window.DataContext>
<viewmodel:ViewModelBase/>
</Window.DataContext>
The ListViewItem.DataContext is bound to the data items of your list, so you can't directly access properties that exist at the level of the ListView.
You can use a relative binding in this case:
<Condition Binding="{Binding DataContext.IsPlay,RelativeSource={RelativeSource AncestorType=ListView,Mode=FindAncestor}}" Value="True"/>

WPF ComboBox, setting the background color of current item

In my WPF application I need to set the background color of my combobox.
Example
As you can see in the file attached, I set thw background color to blue as (in code behind):
_combobox.Background = Brushes.DodgerBlue;
I have also set the triggers in order to handle the event while selecting the items (set style for both ComboBox and ComboBoxItem:
<Style x:Key="CmbStyleItem" TargetType="{x:Type ComboBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border x:Name="gd" Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}, Path=Background}" Padding="4,6,2,2">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ComboBoxItem.IsMouseOver" Value="True">
<Setter TargetName="gd" Property="Background" Value="#E7E2E2" />
<Setter TargetName="gd" Property="TextElement.Foreground" Value="#000000"/>
</Trigger>
<Trigger Property="ComboBoxItem.IsSelected" Value="True">
<Setter TargetName="gd" Property="Background" Value="#D6D6D6" />
<Setter TargetName="gd" Property="TextElement.Foreground" Value="#000000" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Width" Value="Auto" />
<Setter Property="Height" Value="27" />
<Setter Property="Padding" Value="4,6,2,2" />
<Setter Property="FontFamily" Value="{StaticResource fntConsole}" />
<Setter Property="Typography.Capitals" Value="AllSmallCaps"/>
<Setter Property="FontSize" Value="13.55" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="ItemContainerStyle" Value="{DynamicResource CmbStyleItem}"/>
</Style>
Basically I'm not able to set the background color of selected item, for example in the attachment, the item "Tav1800x650x18". Any hints?
if i understant your problem, you want to modify the background color of combobox when no selecteditem :
so you have this line <Setter Property="Background" Value="Transparent" />
which gives the default background color
you have to set Value with the color you want.
Or i missunderstand you.....
Replace:
Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}, Path=Background}"
To: Background="{TemplateBinding Background}"

TextBox ControlTemplate inside of a Style with InputBindings

I've created a WPF Style for a TextBox with an InputBindings (KeyBinding for Enter) inside the ControlTemplate.
Style and InputBindings is working fine for my TextBoxes, but if I use this Style for my TextBoxes the TabOrder/TabStop is not working any more.
This is the style:
<Style x:Key="TextBoxTemplate" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="FontSize" Value="16"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="5,0,5,5"/>
<Setter Property="Width" Value="150"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<TextBox Text="{TemplateBinding Text}">
<TextBox.InputBindings>
<KeyBinding Command="{Binding EnterKeyCommand}" Key="Enter"/>
</TextBox.InputBindings>
</TextBox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How I add it to my TextBoxes:
<TextBox Text={Binding FirstName} Style="{StaticResource TextBoxTemplate}">
<TextBox Text={Binding LastName} Style="{StaticResource TextBoxTemplate}">
I think the problem is that I use a TextBox inside of the ControlTemplate.
But I don't know how to get running the InputBindings without the TextBox inside of the Template
Do you have any idea?
Thanks Phil
Modify your template to look like the original one plus your KeyBinding:
<Style x:Key="TextBoxTemplate" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="FontSize" Value="16"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Margin" Value="5,0,5,5"/>
<Setter Property="Width" Value="150"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"
SnapsToDevicePixels="True">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
<ScrollViewer.InputBindings>
<KeyBinding Command="{Binding EnterKeyCommand}" Key="Enter"/>
</ScrollViewer.InputBindings>
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="#FF7EB4EA"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="#FF569DE5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

How to make the WPF Label Selectable?

I just want to copy the label content from the UI Window. Anybody can help how to make it?
I had the same problem as you.
I wanted my labels to be selectable.
I did not find a proper way to do that, instead I use a TextBox with a custom style.
<Style x:Key="TextBoxAsLabel" TargetType="{x:Type TextBox}">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="False"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="FontSize" Value="11"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<themes:ClassicBorderDecorator x:Name="Bd" BorderThickness="0" BorderStyle="Sunken" Background="{TemplateBinding Background}">
<ScrollViewer x:Name="PART_ContentHost" BorderBrush="Transparent" BorderThickness="0"/>
</themes:ClassicBorderDecorator>
<ControlTemplate.Triggers>
<Trigger Property="IsReadOnly" Value="true">
<Setter Property="Background" TargetName="Bd" Value="Transparent"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderThickness" Value="0,0,0,0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
you also need to add this to your namespaces:
xmlns:themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Classic"
Usage is : <TextBox Text="{Binding ValueToBind}" IsReadOnly="True" Style="{DynamicResource TextBoxAsLabel}" />
Note: Change your style binding type as needed.
Hope this will help you :)
You shouldn't have to override the entire template. Try this:
<TextBox Text="Copy this...">
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</TextBox.Style>
</TextBox>
The above style should give you a selectable TextBox that looks like a TextBlock or a Label.

Set button hover or onmouseover background color

I am struggling to find a solution to this. Every other one i;ve tried is not working. Maybe I am missing something.
I want to change the background color of a Button when I hover over it with the mouse.
This is my XAML:
<Window x:Class="Recruitment_Manager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="374" Width="940">
<Window.Resources>
<Style TargetType="Button" x:Key="NavigationButtonStyle">
<Setter Property="Height" Value="35"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="StackPanel" x:Key="NavigationButtonContentStyle">
<Setter Property="Orientation" Value="Horizontal"/>
</Style>
<Style TargetType="Image" x:Key="NavigationButtonImageStyle">
<Setter Property="Width" Value="35"/>
</Style>
<Style TargetType="Label" x:Key="NavigationButtonLabelStyle">
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="15"/>
</Style>
</Window.Resources>
<Grid>
<StackPanel HorizontalAlignment="Left" Width="200">
<StackPanel.Background>
<SolidColorBrush Color="#404040"/>
</StackPanel.Background>
<Button Style="{StaticResource ResourceKey=NavigationButtonStyle}">
<StackPanel Style="{StaticResource ResourceKey=NavigationButtonContentStyle}">
<Image Style="{StaticResource ResourceKey=NavigationButtonImageStyle}">
</Image>
<Label Style="{StaticResource ResourceKey=NavigationButtonLabelStyle}">
Settings
</Label>
</StackPanel>
</Button>
</StackPanel>
</Grid>
But it looks like the trigger never executes?
What am I missing or how can I get what I want?
Thank you in advance.
To remove the default MouseOver behaviour on the Button you will need to modify the ControlTemplate. Changing your Style definition to the following should do the trick:
<Style TargetType="{x:Type Button}" x:Key="NavigationButtonStyle">
<Setter Property="Height" Value="35"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
Try following code
<Style TargetType="Button" x:Key="NavigationButtonStyle">
...
<Trigger Property="Control.IsMouseOver" Value="True">
<Setter Property="Background" Value="Green"/>
</Trigger>
</Style>

Resources