Change style of a child control on MouseOver in WPF - wpf

I have a custom control that holds two Rectangles and several TextBoxes. I wish to change the background color of the Rectangle on MouseOver.
I add trigger as following:
<Rectangle
Grid.Column="1"
Fill="#FF383838"
Grid.ColumnSpan="3"
Margin="0,4,4,4">
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Fill" Value="#FF383838" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" Value="#FF575757" />
</Trigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
But since rectangle is part of my control, I assume the event is not firing.

Setting a property via XAML will be applied over the style properties that you try to set. To fix this, remove Fill=#FF383838 so you should have:
<Rectangle Grid.Column="1"
Grid.ColumnSpan="3"
Margin="0,4,4,4">
//... rest of code here

Try this code:
<Window.Resources>
<Style TargetType="Rectangle" x:Key="test">
<Setter Property="Fill" Value="#FF383838" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" Value="#FF575757" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Rectangle Style="{StaticResource test}" />

Related

How to Remove default button background MouseOver in wpf?

I have three buttons on my Xaml
<Page.Resources>
<Style x:Key="GroupToggleStyle" TargetType="RadioButton" BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="Background" Value="BlueViolet"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource Self}}"
Value="True">
<DataTrigger.Setters>
<Setter Property="Background" Value="Red"/>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</Page.Resources>
<Grid>
<RadioButton GroupName="LanguageGroup" Command="{Binding LanguageChangeCommand}" IsChecked="{Binding Button0}"
CommandParameter="English" Content="English" Foreground="White" Width="80"
Style="{StaticResource GroupToggleStyle}" FontSize="15" Grid.Row="3" Grid.Column="2" BorderBrush="#0000ffff" Height="30" Margin="8,5,162,21" Grid.ColumnSpan="2" Background="BlueViolet">
<RadioButton.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="Red"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</RadioButton.Resources>
</RadioButton>
<Grid/>
But when I put mouse over my button, button's background changes to default windows gray background.
What's The Problem?
Here is a photo of my buttons
The ToggleButton defines animations inside its ControlTemplate to control the e.g., checked and hover behavior/states. You will have to override the default ControlTemplate in order to implement your custom animations and triggers.
Additionally, you must also move the mouse over trigger to the RadioButton template too.
You can find examples of the default styles and templates at Control Styles and Templates or use the XAML designer (or Blend) to edit a copy of the elements template.
<Style x:Key="GroupToggleStyle"
TargetType="RadioButton"
BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="Background"
Value="BlueViolet" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Border x:Name="Border"
CornerRadius="5"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled"
Value="False">
<Setter Property="Background"
Value="Gray" />
</Trigger>
<Trigger Property="IsChecked"
Value="True">
<Setter TargetName="Border"
Property="Background"
Value="Red" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<!-- Target the border to allow local Background values on the templated control -->
<Setter TargetName="Border"
Property="Background"
Value="Green" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
In case you want to change individual buttons only, simply base the individual Style on the common base Style (but note that you have to remove the local Style assignment as the local value has a higher precedence than the implicit Style).

How to change the orientation property of WrapPanel by trigger?

I want to know how to change the WrapPanel orientation property by triggers.
I use trigger to change the wrap panel orientation property, but it doesn't work.
<WrapPanel Orientation="Horizontal">
<WrapPanel.Style>
<Style TargetType="WrapPanel">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="Red"/>
<Setter Property="Orientation" Value="Vertical"/>
</Trigger>
</Style.Triggers>
</Style>
</WrapPanel.Style>
<Button Content="button1" Margin="10"/>
<Button Content="button2" Margin="10"/>
</WrapPanel>
I expect the button to be Vertical and the background to be Red, but the result is Horizontal button and Red background. Background is changed right, but orientation is not changed.
set default Orientation value via Style Setter. Orientation="Horizontal" is a local value, which cannot be reset by Style Trigger
<WrapPanel>
<WrapPanel.Style>
<Style TargetType="WrapPanel">
<Setter Property="Orientation" Value="Horizontal"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="Red"/>
<Setter Property="Orientation" Value="Vertical"/>
</Trigger>
</Style.Triggers>
</Style>
</WrapPanel.Style>
<Button Content="button1" Margin="10"/>
<Button Content="button2" Margin="10"/>
</WrapPanel>

Is there a MouseDown setter property for a rectangle that acts as a button control template?

As the title suggests, I'm looking for a trigger property that triggers when the left mouse button is clicked over the button. Problem being my button has a rectangle as it's control template and I'd like to change the fill/stroke when the button/rectangle is clicked.
The only trigger property I can find that works is "IsMouseOver"
Anything like MouseDown or IsPressed doesn't work.
My xaml right now:
<Button x:Name="my_Button" Click="my_Button_Click" Margin="268,91,-266,-94">
<Button.Template>
<ControlTemplate>
<Rectangle HorizontalAlignment="Left" Height="20" Stroke="Black" VerticalAlignment="Top" Width="141" Margin="105,10,0,0" StrokeThickness="2">
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Fill" Value="Blue" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" Value="Red"/>
<Setter Property="Stroke" Value="Black"/>
</Trigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</ControlTemplate>
</Button.Template>
</Button>
Where the Trigger Property "IsMouseOver" is I would like the property to be MouseDown, and then proceeding to set the fill and stroke of the rectangle to different colors.
xaml I've tried that hasn't worked:
<Trigger Property="MouseDown" Value="True">
<Setter Property="Fill" Value="Red"/>
<Setter Property="Stroke" Value="Black"/>
</Trigger>
Edit: I would like to clarify that IsMouseOver works perfectly with the trigger property, but I need it to be when the mouse is clicked on the button rather than hovered over.
See the DataTrigger below :
<Button x:Name="my_Button" Click="my_Button_Click" Margin="268,91,-266,-94">
<Button.Template>
<ControlTemplate>
<Rectangle HorizontalAlignment="Left" Height="20" Stroke="Black" VerticalAlignment="Top" Width="141" Margin="105,10,0,0" StrokeThickness="2">
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Fill" Value="Blue" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsPressed, RelativeSource={RelativeSource Mode=TemplatedParent}}" Value="True">
<Setter Property="Fill" Value="Red"/>
<Setter Property="Stroke" Value="Black"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</ControlTemplate>
</Button.Template>
</Button>

How do I set TabControls TabItem header FontSize

I have a TabControl with a style that changes the FontSize of the Header of the TabItem. When I data bind the ItemsSource only the headers are affected by the FontSize. But when I use the same style on another TabControl and add the TabItems in XAML the FontSize is changed on all content in the TabItem. I want the style to work with both databound and non-databound TabItems.
<TabControl Style="{StaticResource VariablesTabControl}" ItemsSource="{Binding TabItems}">
...
</TabControl>
MainSkin.xaml:
<Style TargetType="TabControl" x:Key="VariablesTabControl">
<Setter Property="ItemContainerStyle" Value="{StaticResource VariableTabItem}" />
...
</Style>
<Style TargetType="TabItem" x:Key="VariableTabItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Grid Name="Panel" MinHeight="30" MinWidth="120">
<ContentPresenter x:Name="ContentSite" VerticalAlignment="Center" HorizontalAlignment="Left" ContentSource="Header" Margin="10,2" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Panel" Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="{StaticResource ForegroundBrush}" />
<Setter Property="FontSize" Value="12" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Panel" Property="Background" Value="{StaticResource BackgroundMouseOver}" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Panel" Property="Background" Value="{StaticResource SelectedBrush}" />
<Setter Property="Foreground" Value="{StaticResource ForegroundBrush}" />
<Setter Property="FontSize" Value="12" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Your problem is a result of Property Value Inheritance.
When you define the TabItems in xaml something like this:
<TabItem>
<TabItem.Header>
<TextBlock Text="TEST_HEADER1" />
</TabItem.Header>
<TextBlock Text="TEST_CONTENT1" />
</TabItem>
Both TextBoxes, the header, and the content are in the logical tree of the TabItem that means that any Inheritable property set on TabItem will be propagated down the tree to these TextBoxes.
The Foreground and FontSize are Inheritable.
If you have something like:
<TabItem Header="TEST_HEADER2">TEST_CONTENT2</TabItem>
you don't have any Elements in TabItem's logical tree, the elements for the Header and the content will be auto generated, and the properties will not be inherited.
But this type of declaring TabItem's is not very useful, you usually need some advanced XAML as the items content so I think the best way to solve this is by changing all those text properties in TabItem's HeaderTemplate, you can bind to TabItem's properties using the RelativeSource.

WPF: Can I Set IsMouseOver Property of a ChildElement When The Parent Is Moused Over?

Suppose I have a button nested in the Template of a ListBoxItem, can I set the IsMouseOver property of the button to true, so that it looks like its moused over?
Just for illustration, the notifications on the top of the window are what I am referring to. Its basically ListBoxItem's with a TextBlock and Button
Unfortunately, no. "IsMouseOver" is readonly.
I'm assuming, though, that you have a custom control template for the Button, right? If that's the case, one workaround is to mess with the Tag property of the button. Add a trigger to the ControlTemplate that gets fired when a specific Tag value is set. Then, in the DataTemplate for your ListBoxItems, just set the button's Tag to that specific value when IsMouseOver on the item is true. Below is an example:
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel x:Name="dp" Background="Transparent">
<Button x:Name="btn" DockPanel.Dock="Right" Content="x" Background="Gainsboro">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border x:Name="bd" Padding="2" BorderBrush="Black" BorderThickness="1"
Background="WhiteSmoke">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="LightBlue"/>
</Trigger>
<Trigger Property="Tag" Value="SimulatedMouseOver">
<Setter TargetName="bd" Property="Background" Value="LightBlue"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="bd" Property="Background" Value="Gray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
<TextBlock Text="{Binding}"/>
</DockPanel>
<DataTemplate.Triggers>
<Trigger SourceName="dp" Property="IsMouseOver" Value="True">
<Setter TargetName="btn" Property="Tag" Value="SimulatedMouseOver"/>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
<s:String>Item1</s:String>
<s:String>Item2</s:String>
<s:String>Item3</s:String>
</ListBox>

Resources