Custom Style Button With Modified Background - c#

I have a Button that I want to have an Orange Background with a White Foreground. When I mouse over the Button I would like it to display in DarkOrange. This is the Style I am using at the moment.
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="DarkOrange"/>
</Trigger>
</Style.Triggers>
</Style>
If I don't modify the original Background color of the my Button this style works fine. For example;
<Button Grid.Row="2" Content="SIGN IN" />
has no issues. However, when I want to change the default Background of the Button, i.e
<Button Grid.Row="2" Content="SIGN IN" Background="Orange"/>
the style does not work. I assume this is because I am now overriding the Background property that the IsMouseOver is attempting to change.
Is there a way I can achieve both a modified default Background and a IsMouseOver effect? I have also tried setting <Border Background="Orange"> but to no effect still.

You could just add a setter to your Style instead of adding a Background property to your Button. Like this:
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Orange"/>
<Setter Property="Template">
...
</Setter>
<Style.Triggers>
...
</Style.Triggers>
</Style>
Here is an another example of how to use it.

<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate x:Name="Border" TargetType="{x:Type Button}">
<Border x:Name="Border" Background="{TemplateBinding Background}">
<ContentPresenter x:Name="CP" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="CP" Property="TextBlock.Foreground" Value="White"/>
<Setter TargetName="Border" Property="Background" Value="DarkOrange"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This working fine with
<Button Grid.Row="2" Content="SIGN IN" Background="Orange"/>

Related

Hover rounded corner button change its background color using ResourceDictionary

I have created a ResourceDictionary style sheet that have a style named btn_default.
I plan to use it on all the buttons in my program. My problem is that when I hover the button then the background-color doesnt change. The font color changes.
button_default
button_default:hover
I tried in my code to change the "Setter Property="Background" Value="#b5b5b5"", however I guess that doesnt affect the Border-tag, but the Style-tag?
ResourceDictionary
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MSDNSample">
<!-- Btn default -->
<Style x:Key="btn_default" TargetType="{x:Type Button}">
<Setter Property="FontFamily" Value="Calibri"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Foreground" Value="#d9d9d9" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="5" BorderThickness="1" Padding="6,4,6,4" Background="#6c6c6c" BorderBrush="#393939">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#b5b5b5"/>
<Setter Property="Foreground" Value="#000000" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- //Btn default -->
</ResourceDictionary>
Main
<Button x:Name="buttonExplorer" Content="Explorer" Style="{StaticResource btn_default}" Margin="0,0,6,0" />
<Button x:Name="buttonProcess" Content="Process" Style="{StaticResource btn_default}" Margin="0,0,6,0" />
You should declare Background property of Border using TemplateBinding extension and set Background value in Style setter, otherwise it'll never be updated
<Style x:Key="btn_default" TargetType="{x:Type Button}">
<Setter Property="FontFamily" Value="Calibri"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Foreground" Value="#d9d9d9" />
<Setter Property="Background" Value="#6c6c6c"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="5" BorderThickness="1" Padding="6,4,6,4" BorderBrush="#393939" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#b5b5b5"/>
<Setter Property="Foreground" Value="#000000" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Override property of custom control style in XAML

I borrowed some code from some other guy here on Stack Overflow. I have two PasswordBoxes. I want the first one to show "Password" and the second one to show "Re-enter Password". I don't want to rewrite the complete style all over again if the only difference is the text in the TextBlock. How can I override and change the value of the TextBlock, if the TargetType has to be PasswordBox? I'm trying to create a second style that is based on the first one, and then change it from there, but I'm not sure about the syntax.
This one works fine:
<Style x:Name="customPWBStyle" x:Key="customPasswordBox"
TargetType="{x:Type PasswordBox}">
<Setter Property="helper:PasswordBoxMonitor.IsMonitoring"
Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type PasswordBox}">
<Border Name="Bd"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
SnapsToDevicePixels="true">
<Grid>
<ScrollViewer x:Name="PART_ContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<TextBlock Text="Password"
Margin="4, 2, 0, 0"
Foreground="Gray"
Visibility="Collapsed"
Name="txtPrompt" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled"
Value="false">
<Setter TargetName="Bd"
Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="helper:PasswordBoxMonitor.PasswordLength" Value="0">
<Setter Property="Visibility" TargetName="txtPrompt" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
But I want to create another style identical, but the only difference has to be the TextBlock that has to say "Re-enter password"
This is what I got so far:
<Style x:Key="reEnterPasswordBox" BasedOn="{StaticResource customPasswordBox}" TargetType="{x:Type PasswordBox}">
<Style.Resources>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="Re-enter Password"></Setter>
</Style>
</Style.Resources>
</Style>
However it does not work. I can see that theres a name for the TextBlock, which is txtPrompt, but I'm not sure if its possible to use that as a reference for chaning the value of the TextBlock.
I would recommend to create a special dependency property in customPasswordBox, e.g. InputHint. (If you can't change customPasswordBox code, make a custom attached dependency property - like helper:PasswordBoxMonitor.IsMonitoring. Attached DPs are great for parametrizing templates)
When you have a property, set default value via Setter, and then bind TextBlock to it via TemplateBinding.
<Style x:Name="customPWBStyle" x:Key="customPasswordBox"
TargetType="{x:Type PasswordBox}">
<Setter Property="helper:PasswordBoxMonitor.IsMonitoring" Value="True"/>
<Setter Property="InputHint" Value="Password"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type PasswordBox}">
<Border Name="Bd"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
SnapsToDevicePixels="true">
<Grid>
<ScrollViewer x:Name="PART_ContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<TextBlock Text="{TemplateBinding InputHint}"
Margin="4, 2, 0, 0"
Foreground="Gray"
Visibility="Collapsed"
Name="txtPrompt" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled"
Value="false">
<Setter TargetName="Bd"
Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="helper:PasswordBoxMonitor.PasswordLength" Value="0">
<Setter Property="Visibility" TargetName="txtPrompt" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
to make another style, change only Setter for InputHint:
<Style x:Key="reEnterPasswordBox" BasedOn="{StaticResource customPasswordBox}" TargetType="{x:Type PasswordBox}">
<Setter Property="InputHint" Value="Re-enter Password"/>
</Style>
Parts of template are not easily reachable for modification, even with implicit styles

ToggleButton Trigger IsChecked Doesn't Change Background

I have a ToggleButton with a red background. I need to set a green background when the toggle button is checked.
I've tried this:
<ToggleButton Content="Test 001" Name="btn03" Height="20">
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="Background" Value="#ff0000" />
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="#00ff00" />
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
But instead a green color I get a light blue color (I think is the default color of my
system).
What I'm doing wrong and how to fix it?
WPF 4.0 doesen't allow this. Look here for a different approach:
<Grid>
<Grid.Resources>
<Style x:Key="ToggleButtonStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="border" Background="Red">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Background" TargetName="border" Value="Green"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<ToggleButton Content="ToggleButton" Style="{StaticResource ToggleButtonStyle}"/>
</Grid>

How to set a borderless button which changes its color when mouse hovering in WPF

I want to override all my button's style to a borderless grayish button which highlights when hover on.
I wrote like below:
If I remove the template section (I even have no idea of what does it do), the button will have a border even if I have set BorderThickness to 0.
But if I keep the template section, the button will not change its background color at all.
So what can I do to keep both features and why my xaml won't work?
BTW, where can I find a full list of properties/triggers that I can set for certain type of control like button?
<Style TargetType="{x:Type Button}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Background" Value="{StaticResource TitleBrush}" />
<Setter Property="Foreground" Value="{StaticResource WhiteTextBrush}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ContentPresenter Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource HoverBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
Why BorderThickness value not reflected to control?
https://stackoverflow.com/a/16649319/440030
Why your xaml won't work?
Because, you set Template property of button with a simple content presenter, So Button ignore all control property and reflect your template. One way is improve your Template property with a by example label:
<ControlTemplate TargetType="{x:Type Button}">
<Label Content="{TemplateBinding Content}"
Background="{TemplateBinding Background}"
Foreground="{TemplateBinding Foreground}"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="Black"/>
</ControlTemplate>
Try something like this it will work
<Grid>
<Grid.Resources>
<ControlTemplate x:Key="buttonTemplate" TargetType="{x:Type Button}">
<Grid>
<Rectangle x:Name="Rect" Width="100" Height="100" Fill="Aqua"/>
<Viewbox>
<ContentControl Margin="20" Content="{TemplateBinding Content}"/>
</Viewbox>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Rect" Property="Fill" Value="Orange"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Grid.Resources>
<Button Template="{StaticResource buttonTemplate}">OK</Button>
</Grid>

How to change the color of ellipse at mouse over of button WPF (c# ,wpf)

I have added an ellipse on a button.
but as of now on mouse over of that button I need to change the background.
so colould not able to do with normal trigger i.e with setting background property on mouse over event.
<Style x:Key="RButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse x:Name="Elipse1" Fill="Red" ></Ellipse>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value = "Orange"/>
</Trigger>
</Style.Triggers>
</Style>
You can use TemplateBinding inside template to bind Button.Background property and set default value as another Setter of your Style
<Style x:Key="RButton" TargetType="Button">
<Setter Property="Background" Value="Red"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse x:Name="Elipse1" Fill="{TemplateBinding Background}" />
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Orange"/>
</Trigger>
</Style.Triggers>
</Style>
or, if you don't want to use Button.Background property, you can target Ellipse by name
<Setter TargetName="Elipse1" Property="Background" Value="Orange"/>
Try this Style:
<Style x:Key="RButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse x:Name="Elipse1" Fill="Red" ></Ellipse>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" Value = "Orange" TargetName="Elipse1" ></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Categories

Resources