I have just started learning WPF and trying to hide a StackPanel during MouseOver. Below is the code that I use. I can only see the Panel flickering when mouse is placed on it but, it doesn't hide completely. Am I missing something here? Thanks in advance.
<Style x:Key="myStyle" TargetType="{x:Type StackPanel}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Visibility" Value="Hidden" />
</Trigger>
<Trigger Property="IsMouseOver" Value="false">
<Setter Property="Visibility" Value="Visible" />
</Trigger>
</Style.Triggers>
</Style>
Stackpanel:
<StackPanel Style="{StaticResource myStyle}">
// Child controls
</StackPanel>
When the StackPanel is hidden, the IsMouseOver property toggles to false, which makes the StackPanel visible again.
You might set the Opacity property instead of Visibility:
<Style x:Key="myStyle" TargetType="{x:Type StackPanel}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0" />
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Opacity" Value="1" />
</Trigger>
</Style.Triggers>
</Style>
Or, as pointed out in the other answer, declare just one Trigger for IsMouseOver == true:
<Style x:Key="myStyle" TargetType="{x:Type StackPanel}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0" />
</Trigger>
</Style.Triggers>
</Style>
Clemens has already answered your question, but just FYI when you are triggering on a Boolean value, you don't need a trigger for both states. Just set a single trigger for the true or false state, then when the state no longer applies the properties that were changed by the setters in the trigger will revert back to their previous values. This will cut down on the amount of XAML you need to write.
Related
Here is a simple XAML with trigger that should change ToggleButton content when it is checked. But for some reason it doesn't work. I have a silly feeling that I missed something extra small. Appreciate your help
<ToggleButton Content="<">
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content" Value=">" />
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
You must move Content="<" from ToggleButton to setter of Style.
Example:
<ToggleButton>
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="Content" Value="<" />
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content" Value=">" />
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
Because local value has higher precedence order over Style setters and triggers:
Property system coercion.
Active animations, or animations with a Hold behavior.
3. Local value.
TemplatedParent template properties.
Implicit style.
6. Style triggers.
Template triggers.
8. Style setters.
...
For more information, please see:
MSDN: Dependency Property Value Precedence
You are overriding the Content set by the Trigger by setting the Content attribute at the control level. You want to set it using a Setter within the Style instead:
<ToggleButton>
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="Content" Value="<" />
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content" Value=">" />
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
i have a Ribbonbutton wich i want to change the Icon on MouseOver but it does not seem to work.
Here is my Code:
<RibbonButton Label="Verbindung testen" LargeImageSource="../Resources/Buttons/disconnect.png" Command="{Binding SettingsVM.TestConnectionCommand}">
<RibbonButton.Style>
<Style TargetType="{x:Type RibbonButton}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="LargeImageSource" Value="../Resources/Buttons/connect.png"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="LargeImageSource" Value="../Resources/Buttons/disconnect.png"/>
</Trigger>
</Style.Triggers>
</Style>
</RibbonButton.Style>
</RibbonButton>
It just shows the first Icon "disconnect.png" and on mouse over it gets highlighted like all the other buttons, but no image change.
I also tried it this way, with ControlTemplate:
<RibbonButton Label="Verbindung testen" LargeImageSource="../Resources/Buttons/disconnect.png" Command="{Binding SettingsVM.TestConnectionCommand}">
<RibbonButton.Template>
<ControlTemplate TargetType="{x:Type RibbonButton}">
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="LargeImageSource" Value="../Resources/Buttons/connect.png"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="LargeImageSource" Value="../Resources/Buttons/disconnect.png"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</RibbonButton.Template>
Here it doesnt show an icon at all.
Found the Answer!
WPF RibbonButton: LargeImageSource and Label not updated via DataTriggers
The problem is your setting properties for LargeImageSource and Label in the button itself. When you do this it takes precidence over your style triggers. I suggest using setters in the style to set your defaults, and remove the property settings it the button.
So it has to be:
<RibbonButton Label="Verbindung testen" Command="{Binding SettingsVM.TestConnectionCommand}">
<RibbonButton.Style>
<Style TargetType="{x:Type RibbonButton}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="LargeImageSource" Value="../Resources/Buttons/connect.png"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="LargeImageSource" Value="../Resources/Buttons/disconnect.png"/>
</Trigger>
</Style.Triggers>
</Style>
</RibbonButton.Style>
Removing the "LargeImageSource" from the Button itself.
I've implemented code to get around the double click issue when selecting a row in a WPF DataGrid. I'm using the following code from here: https://stackoverflow.com/a/5857908/40106.
<Style TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsEditing" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
Rows have alternating colors. The problem is when I mouse over a row, in one column, the light blue color is replaced by white.
The above code works great except for this one issue. How do I stop the color from changing when mousing over a row?
I have tried the following but it doesn't have any effect:
<Style TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsEditing" Value="True" />
<Setter Property="Background" Value"AliceBlue" />
</Trigger>
</Style.Triggers>
</Style>
The problem is, that the cell will display it's edit style when you hover the mouse above the cell.
For a DataGridTextColumn this means, that a TextBox with a white background is displayed.
You can set a Style to <DataGridTextColumn.EditingElementStyle> and set the Background to transparent.
<DataGridTextColumn Header="Name" Binding="{Binding Name}" >
<DataGridTextColumn.EditingElementStyle>
<Style TargetType="TextBox">
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="BorderThickness" Value="0"></Setter>
</Style>
</DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>
To get the white Background, when actually editing the cell you could add another trigger to the IsSelected event:
<Style TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsEditing" Value="True" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
Another option would be to apply the DataGridCell Style to CheckBoxColumns only. For other Column types it wouldn't make a difference anyway.
I want that the Background changes to Gray if the Window is not the current active Window. I tried this:
<mm:MetroWindow.Style>
<Style TargetType="{x:Type mm:MetroWindow}">
<Style.Triggers>
<Trigger Property="IsFocused" Value="False">
<Setter Property="Background" Value="Gray" />
</Trigger>
</Style.Triggers>
</Style>
</mm:MetroWindow.Style>
But it does not work, the Background is always Gray, even if the Window is in focus. Did I use the wrong Property or what am I doing wrong?
Use IsActive property:
XAML:
<Style x:Key="MetroWindowStyle2" TargetType="{x:Type Controls:MetroWindow}">
<Style.Triggers>
<Trigger Property="IsActive" Value="False">
<Setter Property="Background" Value="Gray" />
</Trigger>
</Style.Triggers>
</Style>
You need to add:
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
(or whatever colour you want the background to be).
You might also have to add:
<Setter Property="Focusable" Value="true"/>
to your style.
Source
You need to set the active background in the Style as well. There are several ways a background can by set, and the Style does not come high in the heirarchy. See https://msdn.microsoft.com/en-us/library/ms743230%28v=vs.100%29.aspx
<mm:MetroWindow.Style>
<Style TargetType="{x:Type mm:MetroWindow}">
<Setter Property="Background" Value="someColour" />
<Style.Triggers>
<Trigger Property="IsFocused" Value="False">
<Setter Property="Background" Value="Gray" />
</Trigger>
</Style.Triggers>
</Style>
</mm:MetroWindow.Style>
Actually, I can see that you are using the theme MahApps.Metro. For that theme, you can just set the property 'NonActiveWindowTitleBrush' as below to control the color of inactive window title. In my below example, I set the inactive window title as white.
<Controls:MetroWindow x:Class="CefSharp.MinimalExample.Wpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
xmlns:cef="clr-namespace:CefSharp;assembly=CefSharp.Core"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
NonActiveWindowTitleBrush="White"
>
I have a Button and its Style:
<Button Name="MyBtn" Style="{StaticResource ButtonEnabledStyle}"
IsEnabled="False" Opacity="1" />
<Style x:Key="ButtonEnabledStyle" TargetType="Button">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True" >
<Setter Property="Opacity" Value="0.1" />
</Trigger>
</Style.Triggers>
</Style>
But when I enable the Button (MyBtn.IsEnabled = true) it does not change its Opacity. Why? How can I solve this problem? Thanks.
A local value set on the element (Opacity="1" in your code) will always take precedence over a style or style trigger value. Please have a look at Dependency Property Setting Precedence List.
An easy fix is to set the default value on the style instead:
<Style x:Key="ButtonEnabledStyle" TargetType="Button">
<Setter Property="Opacity" Value="1.0" />
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True" >
<Setter Property="Opacity" Value="0.1" />
</Trigger>
</Style.Triggers>
</Style>