WPF ComboBox remove highlight effect without overriding entire style - wpf

I'm new to WPF and have run into a bit of a problem. I am trying to remove the blue gradient effect on a combobox (e.g. when the user mouses over it) in order to create a more flat UI aesthetic, but I haven't been able to figure out how. Most of the solutions I've seen while googling involve doing somthing like:
<Style x:Key="myComboBox" TargetType="{x:Type ComboBox}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<!-- and then the rest of the style re-implements the combobox from scratch... -->
That seems a bit much just to remove one minor effect. I've also tried doing things like:
<Style x:Key="myComboBox" TargetType="{x:Type ComboBox}">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="LightGray"/>
<Setter Property="BorderBrush" Value="DarkGray"/>
<Setter Property="Focusable" Value="False" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightGray"/>
</Trigger>
</Style.Triggers>
But that doesn't seem to have any effect either. Does anyone know what setting I might change to remove the hover effect?

Related

Removing box / border around selected cell contents in WPF DataGrid

Trying to restyle a WPF datagrid. Almost where I need to be, except for one peculiarity: when selecting a row, the contents of all the cells are surrounded by a white border.
I'm at a loss as to how to get rid of this. At the moment, my styling looks like this:
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#3CACDC" />
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#90C8E0" />
</Trigger>
</Style.Triggers>
</Style>
Plus DataGridCell has an almost identical style set.
It's not clear whether the question How to suppress DataGrid cell selection border? is asking the same question, but the accepted solution of setting FocusVisualStyle to Null doesn't remove the border. It does, however, change the style:
How can I get ride of that border?
I think you can try styling DataGridCell style
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
</Style>
</DataGrid.CellStyle>

Background color of selected DataGridRow not working / how to combine with AlternationIndex?

I'm trying to style a DataGrid, this includes styling DataGridRow as well. What I want is having an alternating background behavior on my rows (say, White/Grey); when a row is selected, the background should be YellowGreen. Somehow the following code is not working, but I'm sure using DataGridCell for the selection part would work; I'd just like to know why this isn't doing it:
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="DataGridRow.AlternationIndex" Value="0">
<Setter Property="Background" Value="{StaticResource EnBWLichtgrau}"/>
</Trigger>
<Trigger Property="DataGridRow.AlternationIndex" Value="1">
<Setter Property="Background" Value="White"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="DataGridRow.AlternationIndex" Value="0"/>
<Condition Property="DataGridRow.IsSelected" Value="True"/>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Background" Value="Pink"/>
</MultiTrigger.Setters>
</MultiTrigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type DataGrid}">
<Setter Property="AlternationCount" Value="2"/>
<Setter Property="BorderBrush" Value="{StaticResource EnBWAnthrazitgrau}"/>
<Setter Property="HeadersVisibility" Value="Column"/>
</Style>
Maybe some setters override the MultiTrigger setters, maybe something else, I don't know. The MultiTrigger isn't really necessary right now, but even a simple Trigger on IsSelected doesn't work this way.
As I said, I could probably go over to styling DataGridCell, but the "why" is what I'm interested in :-) Thanks!
EDIT: I tried using DataGridCell instead for the IsSelected part and it works as expected. But what if I wanted the selected row background color to be different depending on the AlternationIndex of the DataGridRow the cell is in? Is there some way to get the value of this index inside the DataGridCell style definition e.g.?

VisulStudio 2012 designer doesn't recognize properties of DataGrid correctly

In a WPF user control declaration I have the following style define:
<UserControl.Resources>
<Style x:Key="Datagrid" TargetType="{x:Type DataGrid}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="HeadersVisibility " Value="Column"/>
<Setter Property="VerticalGridLinesBrush " Value="{StaticResource DatagridVerticalLinesBrush}"/>
<Setter Property="HorizontalGridLinesBrush " Value="Transparent"/>
<Setter Property="RowHeaderWidth " Value="0"/>
<Setter Property="CanUserAddRows " Value="False"/>
<Setter Property="CanUserDeleteRows " Value="False"/>
</Style>
</UserControl.Resources>
The problem is that the Visual Studio 2012 designer thinks the properties don't exist on the type DataGrid. It says that: the member "XXXXXXXXXXXX" is not recognized or is not accessible.
Despite the errors, the style is applied correctly at run time and the properties exist on the DataGrid (they are DependencyProperies) and are public.
Any idea what could be causing it to think they don't exist or why are they inaccessible to the designer?
By the way, the Background property is ok. It's only the other 7 that have errors.
I have loaded this up in VS2012, created a UserControl, added the above style. I observed that the Background and BorderBrush properties are seen as valid, but the others are not.
Then...I noticed the spaces in the quoted names. Once removed all is well...
<UserControl.Resources>
<Style x:Key="Datagrid" TargetType="{x:Type DataGrid}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HeadersVisibility" Value="Column"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="VerticalGridLinesBrush" Value="{StaticResource DatagridVerticalLinesBrush}"/>
<Setter Property="HorizontalGridLinesBrush" Value="Transparent"/>
<Setter Property="RowHeaderWidth" Value="0"/>
<Setter Property="CanUserAddRows" Value="False"/>
<Setter Property="CanUserDeleteRows" Value="False"/>
</Style>
</UserControl.Resources>
It may be a cut/paste error but you have an extra space before the closing double-quotes on all the property names except for Background and BorderBrush. The parser probably trims the property name before reflection so it's able to find it at runtime.

WPF Trigger Properties

I am fairly new to WPF and I am currently working with triggers. I have a question regarding a simple trigger. By simple trigger, I mean one that watches for a change in a dependency property and uses a setter to change the style.
Example:
<Style.Triggers>
<Trigger Property="Control.IsFocused" Value ="True">
<Setter Property=" Control.Foreground" Value =" DarkRed" />
</Trigger>
</Style.Triggers>
All examples I have seen have used the following trigger properties:
<Trigger Property="Control.IsFocused" Value ="True">
<Trigger Property="Control.IsMouseOver" Value ="True">
<Trigger Property="Button.IsPressed" Value ="True">
Question:
Are these the only trigger properties available? If not, what others exist?
I have searched online but to no avail. Maybe someone could shed some light on this.
These are not the only properties that you can use in your Triggers, however, they are common examples because they are easily understandable and easy to demonstrate.
In truth, you can have your Trigger watch any DependencyProperty, but because it is "triggered" when the value changes (and matches the Value you tell it to watch for), it only makes sense to use properties that will change at runtime, often from user action (such as focus, mouse over, pressed, etc). Only certain DependencyProperties actual change value under these circumstances, so not all of them make sense to use in Triggers.
Microsoft has added several DependencyProperties to the standard controls so that you can easily create triggers based on changes. However you can also create your own controls with your own DependencyProperties and have triggers that respond when your custom DependencyProperties change.
Keep in mind, PropertyTriggers are only one flavor of Trigger in WPF. There are also EventTriggers and DataTriggers and MultiTriggers. These other triggers fire based on events or changes in data, or in the case of MultiTriggers multiple property (or data) values.
Is there something specific you're trying to do with Triggers? This other answer provides a good explanation of what each type of trigger does.
There are multiple types of triggers in WPF, but the two most commonly used are regular Triggers and DataTriggers
Both types of triggers will watch a value, and when it changes to match the specified Value then they apply your Style Setters.
Regular triggers can be used for any Dependency Property of the object. This includes properties like Text, Visibility, Background, etc in addition to the more commonly triggered properties that you specified: IsFocused, IsMouseOver, and IsPressed.
Note that per the MSDN page about Trigger.Property, you don't need to specify the class name prefix if the Style or Template containing the trigger has it's TargetType property set
An easy way to remember it is if you can bind the property, you can set a Trigger on it.
DataTriggers are triggers that watch a bound value instead of a Dependency Property. They allow you to watch a bound expression, and will react when that binding evaluates equal to your Value.
For example, you could set a DataTrigger on "{Binding Value}" or "{Binding ElementName=MyTextBox, Path=IsChecked}". You can even use Converters with DataTriggers, such as
<DataTrigger
Binding="{Binding SomeInt, Converter={StaticResource IsGreaterThanZero}}"
Value="True">
Use this code for better experience with trigger in wpf.
<Window x:Class="DataBinding.Trigger2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Trigger2" Height="500" Width="500">
<Window.Resources>
<Style TargetType="Button">
<Style.Setters>
<Setter Property="FontFamily" Value="Tahoma"></Setter>
<Setter Property="FontSize" Value="15"></Setter>
<Setter Property="FontWeight" Value="Bold"></Setter>
<Setter Property="Height" Value="25"></Setter>
<Setter Property="Width" Value="100"></Setter>
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Purple"></Setter>
<Setter Property="Foreground" Value="DarkCyan"></Setter>
<Setter Property="FontFamily" Value="Franklin Gothic"></Setter>
<Setter Property="FontSize" Value="10"></Setter>
<Setter Property="FontWeight" Value="Normal"></Setter>
<Setter Property="Height" Value="50"></Setter>
<Setter Property="Width" Value="200"></Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="FontFamily" Value="Calibri"></Setter>
<Setter Property="FontSize" Value="25"></Setter>
<Setter Property="FontWeight" Value="Heavy"></Setter>
<Setter Property="Height" Value="100"></Setter>
<Setter Property="Width" Value="400"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="Green"></Setter>
<Setter Property="Foreground" Value="Violet"></Setter>
<Setter Property="FontFamily" Value="Times New Roman"></Setter>
<Setter Property="FontSize" Value="20"></Setter>
<Setter Property="FontWeight" Value="Thin"></Setter>
<Setter Property="Height" Value="250"></Setter>
<Setter Property="Width" Value="250"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Button>It's a Magic.</Button>

wpf DataGrid Loses its Row Selection when the focus is lost

I have come accross a very strange behavior with the DataGrid. I have following Trigger on the DataGridRow
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource SelectionBackgroundBrush}"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
Initially when the row is selected, I get the behavior from the above trigger. However, after selection, if the DataGrid loses focus (say for example I click some other button on window) the Foreground property loses its value, but the background remains as specified in the trigger. Has anyone ever come accross this behavior, or there is some problem with my code above (or elsewhere in my applicaion for that matter). Any workarounds for the above issue ?
I've used DataGridCell instead of DataGridRow and it works for me
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="BorderBrush" Value="#CCDAFF" />
<Setter Property="Background" Value="#3399ff"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
Hope it helps someone!

Resources