The Mouse Over trigger is not working on wpf button control. I want to change background and foreground of a button when the mouse is over on it.
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="#FFF2E32F" Offset="0" />
<GradientStop Color="#FF45E815" Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
Edited
I added Template but it just removes the button default MouseOver trigger and not taking place my desired foreground and background style.
I found a working solution from here. Define the style inside the button like this:
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="#FFF2E32F" Offset="0" />
<GradientStop Color="#FF45E815" Offset="1" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
Related
In the Project, there are two adjacent buttons.
The style should make the outer side of the two buttons in rounded corner buttons in WPF. Here is the button image how they should look
The below solution XAML style code makes both sides rounded. But I need the outer side rounded only.
https://stackoverflow.com/a/6746271/4002198
Thanks Yves. I am positing the full syle code so that someone can use it for the same purpose.
<Style x:Key="RoundCornerRightSelected" TargetType="{x:Type Button}">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontFamily" Value="Tahoma"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid x:Name="grid">
<Border x:Name="border" CornerRadius="0,10,10,0"
BorderBrush="Gray" BorderThickness="1">
<Border.Background>
<RadialGradientBrush GradientOrigin="0.496,1.052">
<RadialGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterX="0.5" CenterY="0.5"
ScaleX="1.5" ScaleY="1.5"/>
<TranslateTransform X="0.02" Y="0.3"/>
</TransformGroup>
</RadialGradientBrush.RelativeTransform>
<GradientStop Offset="1" Color="#0073CF"/>
<GradientStop Offset="1" Color="#0073CF"/>
</RadialGradientBrush>
</Border.Background>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
TextElement.FontWeight="Bold">
</ContentPresenter>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" TargetName="border">
<Setter.Value>
<RadialGradientBrush GradientOrigin="0.496,1.052">
<RadialGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterX="0.5"
CenterY="0.5" ScaleX="1.5" ScaleY="1.5"/>
<TranslateTransform X="0.02" Y="0.3"/>
</TransformGroup>
</RadialGradientBrush.RelativeTransform>
<GradientStop Color="#40b5f2" Offset="0.3"/>
<GradientStop Color="#40b5f2" Offset="0.3"/>
</RadialGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" TargetName="border"
Value="Gray"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" TargetName="grid" Value="0.25"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I'm trying to create a template for my buttons that have:
Border corner radius
Background as gradient
Change border color on hover
So far I got here:
<Window.Resources>
<Style TargetType="Button" x:Key="aimDark">
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Margin" Value="5,5,5,0" />
<Setter Property="Height" Value="20" />
<Setter Property="Foreground" Value="#0e0e0e" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
CornerRadius="4"
BorderBrush="#000000"
BorderThickness="1">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#006d23" Offset="0" />
<GradientStop Color="#006d23" Offset="0.05" />
<GradientStop Color="#00c741" Offset="0.45" />
<GradientStop Color="#00c741" Offset="1" />
</LinearGradientBrush>
</Border.Background>
<RenderOptions.EdgeMode>Aliased</RenderOptions.EdgeMode>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button Content="Test" Name="btn01" Style="{StaticResource aimDark}" />
</Grid>
The Problem:
First my Content in the button doesn't appear, in fact there isn't text been render in my button.
And I don't know how to change only the border color in the Hover Event.
In ControlTemplate you should specify ContentPresenter to display the Content of a Button.
<Window.Resources>
<Style TargetType="Button" x:Key="aimDark">
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Margin" Value="5,5,5,0" />
<Setter Property="Height" Value="20" />
<Setter Property="Foreground" Value="#0e0e0e" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
CornerRadius="4"
BorderBrush="#000000"
BorderThickness="1">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#006d23" Offset="0" />
<GradientStop Color="#006d23" Offset="0.05" />
<GradientStop Color="#00c741" Offset="0.45" />
<GradientStop Color="#00c741" Offset="1" />
</LinearGradientBrush>
</Border.Background>
<RenderOptions.EdgeMode>Aliased</RenderOptions.EdgeMode>
<ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
The template that you created does not have a ContentPresenter, and that's required in order to show the content (text or other). I suggest you start from the default Button template and make changes as you need.
You need a ContentPresenter to make the content of the button appear.
Also if you define a name in ControlTemplate>Border you can modify it when a action is trigger like this:
<Style x:Key="mylayout" TargetType="Button">
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Margin" Value="5,5,5,0" />
<Setter Property="Height" Value="20" />
<Setter Property="Foreground" Value="#949494" />
<Setter Property="Background" Value="the_gradient" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="4" BorderBrush="#000000" BorderThickness="1" Background="{TemplateBinding Background}" Name="border">
<ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" TargetName="border" Value="#e9eceb" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have a WPF program with a tabItems interfaces set on the left hand side.
What I want is that the tabItem keeps the colour as in the following picture:
Please notice where is the mouse pointer. When there the tabItem is coloured.
When going in another part of the interface on the right the tabItem looses the colour and gets embossed:
I am not sure if it helps posting my xaml file helps.
Basically I noticed that when the arrow goes on a datagrid on the right the tabItem is coloured when going on the free space it isn't.
Please notice that I don't want the tabItem to be of a particular colour, it has to follow the system palette and so to be in the correct system colour.
Thank you for any help.
Here is an Article from Microsoft describing how to use ColorTemplate with Triggers to solve your issue.
Here is the example from article in case in the future the link is down for some reason:
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border
Name="Border"
Margin="0,0,-4,0"
Background="{StaticResource LightBrush}"
BorderBrush="{StaticResource SolidBorderBrush}"
BorderThickness="1,1,1,1"
CornerRadius="2,12,0,0" >
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="12,2,12,2"
RecognizesAccessKey="True"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Panel.ZIndex" Value="100" />
<Setter TargetName="Border" Property="Background" Value="{StaticResource WindowBackgroundBrush}" />
<Setter TargetName="Border" Property="BorderThickness" Value="1,1,1,0" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" />
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Resources:
<LinearGradientBrush x:Key="LightBrush" StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#FFF" Offset="0.0"/>
<GradientStop Color="#EEE" Offset="1.0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
...
<SolidColorBrush x:Key="SolidBorderBrush" Color="#888" />
...
<SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />
...
<SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE" />
...
<SolidColorBrush x:Key="DisabledBorderBrush" Color="#AAA" />
...
<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />
I have a WPF datagrid. The datagrid is bound to a list of a custom type called Orders. Currently I have a toggle button for every row in the datagrid.
I only want a toggle button to be in the rowheader if the Orders' property MultiID (boolean) is true but can't get this to work.
In my DataGridRow I have tried using the commented out section in the line below which seems to make no difference as every row has a toggle button.
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Blue"/>
</Trigger>
<!--<DataTrigger Binding="{Binding MultiID}" Value="True">
<Setter Property="HeaderTemplate" Value="{StaticResource rowdetailToggleButton}"/>
</DataTrigger>-->
</Style.Triggers>
My Datagrid
<!-- The data grid to display orders-->
<DataGrid DataContext="{Binding OrderBlock}"
x:Name="dataGridOrders"
ItemsSource="{Binding Orders}"
RowStyle="{StaticResource DG_Row}"
RowDetailsTemplate="{StaticResource DG_RowDetail}"
RowHeaderStyle="{StaticResource DG_RowHeader}"
RowDetailsVisibilityChanged="dataGridOrders_RowDetailsVisibilityChanged">
<DataGrid.RowHeaderTemplate>
<DataTemplate>
<ToggleButton x:Name="RowHeaderToggleButton"
Click="RowHeaderToggleButton_Click"
Cursor="Hand"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Orders.MultiID}" Value="False">
<Setter TargetName="RowHeaderToggleButton" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGrid.RowHeaderTemplate>
My DataGridRowHeader
<!-- Data Grid row with toggle button -->
<Style x:Key="DG_RowHeader" TargetType="{x:Type DataGridRowHeader}">
<Setter Property="Width" Value="35"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRowHeader}">
<Border x:Name="DGRH_Border"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Offset="0" Color="LightGray"/>
<GradientStop Offset="1" Color="WhiteSmoke"/>
</LinearGradientBrush>
</Border.Background>
<ContentPresenter Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
My DataGridRow
<!-- Data grid formatting Grid Row template -->
<Style x:Key="DG_Row" TargetType="{x:Type DataGridRow}">
<Setter Property="Opacity" Value="1"/>
<Setter Property="Padding" Value="3,2,2,3"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRow}">
<Border x:Name="DGR_Border"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True">
<Border.Background>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="Transparent"/>
<GradientStop Offset="1" Color="Silver"/>
</LinearGradientBrush>
</Border.Background>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding StatusGood}" Value="Send">
<Setter TargetName="DGR_Border" Property="Background" Value="{StaticResource brushRowSend}"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Blue"/>
</Trigger>
<!--<DataTrigger Binding="{Binding MultiID}" Value="True">
<Setter Property="HeaderTemplate" Value="{StaticResource rowdetailToggleButton}"/>
</DataTrigger>-->
</Style.Triggers>
</Style>
you can put the DataTrigger in your DataTemplate you defined for your RowHeaderTemplate
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding DataContext.MultiID,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridRow}}" Value="false">
<Setter TargetName="RowHeaderToggleButton" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
You can use .Net build-in IValueConverter itself.
Add this line into resources
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
And use it in on your button like this
<DataGrid.RowHeaderTemplate>
<DataTemplate>
<ToggleButton x:Name="RowHeaderToggleButton"
Visibility="{Binding MultiID, Converter={StaticResource BooleanToVisibilityConverter}}"
Click="RowHeaderToggleButton_Click"
Cursor="Hand"/>
</DataTemplate>
</DataGrid.RowHeaderTemplate>
I am trying to add a text shadow to cell text when the row is selected.
UPDATE:
This is what I have now:
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
<Setter Property="RenderOptions.ClearTypeHint" Value="Enabled" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ContentPresenter x:Name="CellContent" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="CellContent" Property="TextOptions.TextFormattingMode" Value="Display" />
<Setter TargetName="CellContent" Property="RenderOptions.ClearTypeHint" Value="Enabled" />
<Setter TargetName="CellContent" Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="2" BlurRadius="2" Color="Black" RenderingBias="Quality" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
It adds shadow to text only (just what I want) and when the row is selected (just what I want). The only problem is now that I am losing subpixel antialiasing:
The selected row is the one below with blueish background. It is now using some kind of gray antialiasing which make it look bad. I tried to set RenderOptions.ClearTypeHint without success. How do I enable it so that it looks as sharp and clear as the rows without selection?
This is how the gray antialiasing looks in 100% size (blurry):
The background of the cell is preventing you from seeing the effect. Just set the background like this, but I don't know if you appreciate the result:
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="2"
BlurRadius="2"
Color="Black"
RenderingBias="Quality"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
Edit
Maybe this is better because it gives you more control:
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<ContentPresenter x:Name="CellContent"/>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="CellContent" Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="2"
BlurRadius="2"
Color="Black"
RenderingBias="Quality"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>