IsMouseOver Not Triggering for Button - c#

The problem is IsMouseOver is not working when I hover the button, though I have customized the button and it is not working.
Can you say where is the error?
<cc:CustomFlatButton Grid.Column="1"
Margin="1,0,5,4"
Command="{Binding ElementName=me, Path=Command疑い}"
CommandParameter="{Binding}"
IsEnabled="{Binding Path=疑いIsEnableFlag}">
<Run FontWeight="Bold">
疑い病名
</Run>
<Button.Style>
<Style TargetType="cc:CustomFlatButton">
<Setter Property="MinWidth" Value="80" />
<Setter Property="FontFamily" Value="メイリオ" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type cc:CustomFlatButton}">
<Border Height="22"
Margin="1"
VerticalAlignment="Center"
Background="White"
BorderBrush="#FFFF5656"
BorderThickness="2"
CornerRadius="6"
RenderOptions.BitmapScalingMode="NearestNeighbor"
TextOptions.TextFormattingMode="Display"
UseLayoutRounding="True">
<Label Padding="0,1,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}"
Foreground="Black" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="cc:CustomFlatButton.IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkGoldenrod"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</cc:CustomFlatButton>
I have also checked if I use trigger Property="IsMouseOver". It is also not working. Where is the problem?

You have changed the Button Template and in this Template no property is bound to the Backgroud of the button.
In the trigger, you change the value of this property, but since no one uses this property, nothing changes in the display.
There are two main options to solve.
Set the Border's background binding to the Backgroud property of the button:
<cc:CustomFlatButton Grid.Column="1"
Margin="1,0,5,4"
Command="{Binding ElementName=me, Path=Command疑い}"
CommandParameter="{Binding}"
IsEnabled="{Binding Path=疑いIsEnableFlag}">
<Run FontWeight="Bold">
疑い病名
</Run>
<Button.Style>
<Style TargetType="cc:CustomFlatButton">
<Setter Property="MinWidth" Value="80" />
<Setter Property="FontFamily" Value="メイリオ" />
<Setter Property="Background" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type cc:CustomFlatButton}">
<Border Height="22"
Margin="1"
VerticalAlignment="Center"
Background="{TemplateBinding Background}"
BorderBrush="#FFFF5656"
BorderThickness="2"
CornerRadius="6"
RenderOptions.BitmapScalingMode="NearestNeighbor"
TextOptions.TextFormattingMode="Display"
UseLayoutRounding="True">
<Label Padding="0,1,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}"
Foreground="Black" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="cc:CustomFlatButton.IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkGoldenrod"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</cc:CustomFlatButton>
Or change the Border background with ControlTemplate triggers.
But this is applicable if CustomFlatButton is a Custom Control and not a UserControl.
That is, the CustomFlatButton should not have any predefined XAML.
<cc:CustomFlatButton Grid.Column="1"
Margin="1,0,5,4"
Command="{Binding ElementName=me, Path=Command疑い}"
CommandParameter="{Binding}"
IsEnabled="{Binding Path=疑いIsEnableFlag}">
<Run FontWeight="Bold">
疑い病名
</Run>
<Button.Style>
<Style TargetType="cc:CustomFlatButton">
<Setter Property="MinWidth" Value="80" />
<Setter Property="FontFamily" Value="メイリオ" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type cc:CustomFlatButton}">
<Border x:Name="PART_Border"
Height="22"
Margin="1"
VerticalAlignment="Center"
Background="White"
BorderBrush="#FFFF5656"
BorderThickness="2"
CornerRadius="6"
RenderOptions.BitmapScalingMode="NearestNeighbor"
TextOptions.TextFormattingMode="Display"
UseLayoutRounding="True">
<Label Padding="0,1,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}"
Foreground="Black" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="cc:CustomFlatButton.IsMouseOver" Value="True">
<Setter Property="Background" Value="DarkGoldenrod" TargetName="PART_Border"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</cc:CustomFlatButton>

Related

WPF Override control background property

I'm kind of new to WPF and I'm not really sure how the whole thing works. I have three buttons below, which I would like to be individually coloured. I also want them to be transparent and have grey text when they are disabled.
I want them to retain the Background colour property assigned in MainWindow.xaml when they are enabled and be transparent when disabled.
I'm not sure how I would go about this. Does it involve templates, styles, binding converters? Any help would be greatly appreciated.
MainWindow.xaml
<Button Grid.Column="0" Content="Suspend" Style="{StaticResource BubbleButton}" IsEnabled="True" Background="Blue"/>
<Button Grid.Column="1" Content="Training Mode" Style="{StaticResource BubbleButton}" IsEnabled="True" Background="Orange"/>
<Button Grid.Column="2" Content="Exit Program" Style="{StaticResource BubbleButton}" Background="Red"/>
App.xaml
<Style x:Key="BubbleButton" TargetType="{x:Type Button}">
<!-- Triggers -->
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Trigger.Setters>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="Gray"/>
</Trigger.Setters>
</Trigger>
</Style.Triggers>
<!-- Style -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="10" Background="{TemplateBinding Background}" Name="Button" Margin="10,5,10,5">
<Grid>
<Border BorderThickness="1,0,1,1" BorderBrush="Black" CornerRadius="{Binding ElementName=Button, Path=CornerRadius}">
<Border.Effect>
<BlurEffect Radius="2" KernelType="Gaussian"/>
</Border.Effect>
</Border>
<Border BorderThickness="0,1,0,0" BorderBrush="White" Margin="2" Opacity="0.7" CornerRadius="{Binding ElementName=Button, Path=CornerRadius}">
<Border.Effect>
<BlurEffect Radius="2" KernelType="Gaussian"/>
</Border.Effect>
</Border>
<TextBlock TextWrapping="WrapWithOverflow" Text="{TemplateBinding Content}" FontWeight="Medium" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="Gray" />
<Setter Property="FontSize" Value="20" />
</Style>
Enabled:
Disabled:
using ControlTemplate.Triggers and adding TargetName should make it work. do the same for TextBlock and Foreground (from what I see, the Setter in Style, not in Trigger should be White).
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Button" Property="Background" Value="Transparent"/>
</Trigger>
</ControlTemplate.Triggers>

how to find ErrorContent in Validation.ErrorTemplate

I have a global style for all comboboxes in application. For error validation I am using IDataErrorInfo. So when there will be error I want all textboxes to have such custom view:
with different ErrorContent (mouse should be over circle to show toolTip with error info). My combobox style is:
<Style x:Key="AlStyleTextBoxArial12" TargetType="{x:Type TextBox}">
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontSize" Value="12pt"/>
<Setter Property="Margin" Value="3,3,3,3"/>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<Grid DockPanel.Dock="Right" Margin="-23,0,0,0" Width="15" Height="15">
<Grid.ToolTip>
<ToolTip Content="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Grid.ToolTip>
<Ellipse Fill="Red" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
<TextBlock Text="!" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" FontSize="11pt" FontWeight="Bold" Margin="0,0,0,1"/>
</Grid>
<Border BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder/>
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
And my TextBox is implemented this way:
<TextBox Text="{Binding Snr, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
Grid.Row="3" Grid.Column="2"/>
View of the TextBox, when I have error, is ok, but I cannot set toolTip. It is always empty. Any ideas why I cann't get ErrorContent?
I've changed my style to this :
<Style x:Key="AlStyleTextBoxArial12" TargetType="{x:Type TextBox}">
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontSize" Value="12pt"/>
<Setter Property="Margin" Value="3,3,3,3"/>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<Grid DockPanel.Dock="Right" Margin="-23,0,0,0" Width="15" Height="15">
<Grid.ToolTip>
<ToolTip Content="{Binding [0].ErrorContent}"/>
</Grid.ToolTip>
<Ellipse Fill="Red" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
<TextBlock Text="!" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" FontSize="11pt" FontWeight="Bold" Margin="0,0,0,1"/>
</Grid>
<Border BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder x:Name="customAdorner" ToolTip="{Binding [0].ErrorContent}"/>
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
and it is working now.

Bind ControlTemplateTrigger to TextBlock property

I am trying to change the TextBlock text colour whenever the Button is highlighted.
However, I don't know how to bind the ControlTemplate.Trigger to the TextBlock Foreground. I tried giving the TextBlock a Name and then using TargetName in Setter but it said that the name wasn't recognised.
<Button Name="Home" HorizontalAlignment="Left" Width="75" Click="Button_Click_Home" Background="#FF252525" BorderThickness="5">
<Button.Content>
<Grid HorizontalAlignment="Center" VerticalAlignment="Bottom">
<TextBlock FontFamily="/VideoManager;component/#Myriad Pro" FontSize="13.333" Foreground="White" Text="Home"></TextBlock>
</Grid>
</Button.Content>
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<ContentPresenter />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="#FF360A0A" /> // What to put here..
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
this is going to help you, but it has a lot of loss, so i suggest to you to read more about Styles And Templates
<Button Name="Home" HorizontalAlignment="Left" Width="75" Background="#FF252525" BorderThickness="5">
<Button.Content>
<Grid HorizontalAlignment="Center" VerticalAlignment="Bottom">
<TextBlock FontFamily="/VideoManager;component/#Myriad Pro" FontSize="13.333" Text="Home"></TextBlock>
</Grid>
</Button.Content>
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Yellow" />
<Setter Property="Background" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>

Removing outer border of toggle button wpf

So I have looked through numerous questions where people want to mess with borders of their buttons. I am using a toggle button (WPF) and it seems like there is an 'inner' border and an 'outer' border. I can manage to change the inner boarder to red, but I have no clue how to change the color of the outer border, or even get rid of it. I have gotten rid of the chrome button or whatever that comes with the aero theme, but I still cannot change this border. This is the picture of what I am getting for toggle buttons:
As you can see there is white in the borders. Here is my code for that style:
<Style x:Key="Style1" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="Black"/>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Button BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true" Foreground="White">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Button>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
</Trigger>
<Trigger Property="IsChecked" Value="true">
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I am using it like this:
<ListBox SelectionMode="Single" Name="touchPanel" Grid.Row="2" Grid.Column="3" Width="Auto" Height="Auto" VerticalAlignment="Top" Background="Black" BorderThickness="0">
<RadioButton Width="60" Height="60" Name="mouseTouchSelection" IsChecked="True" Content="Mouse" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="panTouchSelection" BorderThickness="0" Content="Pan" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="rotateTouchSelection" Content="Rotate" Style="{DynamicResource RadioButtonStyle1}"/>
<RadioButton Width="60" Height="60" Name="zoomBoxTouchSelection" Content="Box Zoom" Style="{DynamicResource RadioButtonStyle1}" />
</ListBox>
But what I would like the buttons to look like is:
I achieved the above buttons by just overriding the default button style, but I can't seem to do it with the Toggle Button. I tried overriding Radio Button also, and I had the same problem. What am I missing? Can I somehow use the Button style instead of the toggle button style? I am just starting to learn Styles, so don't be to harsh! Appreciate all input though!
The Button in your controltemplate is creating the extra borders. If you replace Button with a Border you can style the togglebutton borders. Is there a reason you're using a Button? You can use triggers to provide the button behavior if needed. See below:
<Style x:Key="Style1" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="Black"/>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Name="Border" BorderThickness="1" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true" >
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource DarkBrush}" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource PressedBrush}"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="Border" Property="Background" Value="{StaticResource CheckedBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have only tested it with Buttons, RadioButtons, and ToggleButtons, but the problem arises when trying to nest buttons withing a listbox. So I switched the code from:
<ListBox SelectionMode="Single" Name="touchPanel" Grid.Row="2" Grid.Column="3" Width="Auto" Height="Auto" VerticalAlignment="Top" Background="Black" BorderThickness="0">
<RadioButton Width="60" Height="60" Name="mouseTouchSelection" IsChecked="True" Content="Mouse" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="panTouchSelection" BorderThickness="0" Content="Pan" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="rotateTouchSelection" Content="Rotate" Style="{DynamicResource RadioButtonStyle1}"/>
<RadioButton Width="60" Height="60" Name="zoomBoxTouchSelection" Content="Box Zoom" Style="{DynamicResource RadioButtonStyle1}" />
</ListBox>
to:
<StackPanel Grid.Column="3" Grid.Row="2">
<RadioButton Width="60" Height="60" Name="mouseTouchSelection" IsChecked="True" Content="Mouse" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="panTouchSelection" BorderThickness="0" Content="Pan" Style="{DynamicResource RadioButtonStyle1}" />
<RadioButton Width="60" Height="60" Name="rotateTouchSelection" Content="Rotate" Style="{DynamicResource RadioButtonStyle1}"/>
<RadioButton Width="60" Height="60" Name="zoomBoxTouchSelection" Content="Box Zoom" Style="{DynamicResource RadioButtonStyle1}" />
</StackPanel>
and I got the visual results I wanted (we will see if they work properly).

Changed button control template and now mouseover wont work

My button looks like this:
<Button ToolTip="Pending" Height="33" HorizontalAlignment="Right" Margin="0,5,379,0" Name="radButton2" VerticalAlignment="Top" Width="64" Background="#FF515151" BorderBrush="#FF515151" FontSize="14" Foreground="#FF5F5C5C" FontFamily="Mangal" Command="{Binding SetToPendingCommand}" IsEnabled="{Binding IsSetToPendingButtonEnabled}" Grid.Column="1" Grid.ColumnSpan="2">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="White" BorderThickness="1.5" CornerRadius="0">
<TextBlock Text="Pending" Foreground="White" TextAlignment="Center" FontSize="13" Margin="0,4, 0, 0" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
How do I get the mouseover to work correctly. I have tried not using a style and setting the template directly but that didnt't work either.
One way to do it is to move Triggers into ControlTemplate, give Border some name, for example x:Name="PART_Border", and then in the Setter you can specify TargetName="PART_Border":
<Button ...>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="White" BorderThickness="1.5" CornerRadius="0" x:Name="PART_Border">
<TextBlock Text="Pending" Foreground="White" TextAlignment="Center" FontSize="13" Margin="0,4, 0, 0" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red" TargetName="PART_Border"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
Move the trigger to ControlTemplate instead:
<ControlTemplate>
<Border BorderThickness="1.5" CornerRadius="0">
<TextBlock x:Name="txtBlock" Text="Pending" Foreground="White"
TextAlignment="Center" FontSize="13" Margin="0,4,0,0" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="txtBlock" Property="Background" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
All you need to do is add a template binding to the background property of the Border:
<Border Background="{TemplateBinding Background}" BorderBrush="White" BorderThickness="1.5" CornerRadius="0">
<TextBlock Text="Pending" Foreground="White" TextAlignment="Center" FontSize="13" Margin="0,4, 0, 0" />
</Border>
The important part is:
Background="{TemplateBinding Background}"
As it stands in the question the trigger is changing the template Background property, but that property is not being used within the control template.

Categories