Basic WPF ToggleButton Template - c#

I require a toggle button that has not border when IsChecked = False and has a simple 1pt border of a certain color when IsChecked = True. I have the following style but my border when the button IsChecked = True is being set to Transparent (using Snoop to inspect)
<Style x:Key="InfoToggleButton"
TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="#EEEEF2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border CornerRadius="0"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter x:Name="contentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="BorderBrush" Value="#007ACC"/>
<Setter Property="BorderThickness" Value="1"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The button works and displays properly, but when I check/click it, the border does not get displayed.
I implement this style like
<ToggleButton Grid.Column="0"
Style="{StaticResource InfoToggleButton}"
IsChecked="{Binding IsDisplayingBetInfo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Content="{Binding BetInfoIconSource}"/>
How can I get a simple toggle button with border?
Thanks for your time.

I've figured out the problem and the solution but don't exactly know why it happens.
Problem: Some value other than {x:Null} must be set as the content of the toggle button.
Solution: However, a blank string can be set as the content.
My reasoning: When no content is set, the ContentPresenter is null and thus cannot be clicked.
The problem can be solved by setting the default content to "" like this:
<Style x:Key="InfoToggleButton"
TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="#EEEEF2"/>
<Setter Property="Content" Value=""/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border CornerRadius="0"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter x:Name="contentPresenter"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="BorderBrush" Value="#007ACC"/>
<Setter Property="BorderThickness" Value="1"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

you have to assign a name at the Border tag like in this way
<Border x:Name="MyBorderName"...
then the you have to assign the TargetName at the property.
Example
<Setter TargetName="MyBorderName" Property="BorderBrush" Value="#007ACC"/>
<Setter TargetName="MyBorderName" Property="BorderThickness" Value="1"/>
Otherwise WPF does not know who to assign the Property BorderBrush and BorderThickness

Related

WPF ToggleButton not changing colour when checked

I am trying to make a style for ToggleBox so that it changes colour when clicked, I have successfully given it a dropdown shadow on mouse over but for some reason when I click it instead of going into the checked state it stays stuck on the mouse over state.
It's XAML is:
<!--Primary toggle button style-->
<Style x:Key="PrimaryRoundedToggleButton" TargetType="ToggleButton">
<Setter Property="Margin" Value="5"/>
<Setter Property="Width" Value="180"/>
<Setter Property="Height" Value="30"/>
<Setter Property="Background" Value="#E08827"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="15"/>
<Setter Property="FontWeight" Value="DemiBold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border CornerRadius="4" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border CornerRadius="4" Background="{TemplateBinding Background}">
<Border.Effect>
<DropShadowEffect BlurRadius="4" ShadowDepth="3" Direction="300" Opacity="0.5"/>
</Border.Effect>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border CornerRadius="4" Background="#58585a">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
And the event handler is:
private void primaryToggleButton_Checked(object sender, RoutedEventArgs e)
{
primaryToggleButton.Content = "Restarting...";
serviceStatusChangeTimeout = Int32.Parse(ConfigurationManager.AppSettings.Get("serviceStatusChangeTimeout"));
websiteStatusChangeTimeout = Int32.Parse(ConfigurationManager.AppSettings.Get("websiteStatusChangeTimeout"));
MidTier.ServiceRestart(serviceStatusChangeTimeout);
Thread.Sleep(1000);
cacheBuilderStatus.Source = new BitmapImage(new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox-complete.png"));
MidTier.CheckLastModified();
MidTier.webSiteRestart();
MidTier.applicationPoolRecycle();
primaryToggleButton.IsChecked = false;
}
I am also trying to have it change the text in the button as well, but I remember finding how to do that in XAML so I will try and dig that up again before I ask that question.
Thank you.
So your button stays in the mouse over state because there is no trigger for when the mouse is not over (<Trigger Property="IsMouseOver" Value="false"><!--reset things--></Trigger>). With you have to have multiple triggers and on and off you may need to look into MultiDataTrigger. This isn't a need at the moment for you, but I see that it may soon be.
How can I provide multiple conditions for data trigger in WPF?
You should do a trigger when the value of IsMouseOver is false.
Also I would suggest you to override the template and do what you need:
<Setter Property="Template">
...
</ControlTemplate>
And mark ControlTemplate.Triggers for your triggers.

remove blue highlight on buttons wpf

I am making a WPF project. While running the application, as I take my cursor to a button, it gets highlighted by blue color filled inside it.
Now, I want to remove this highlight...
How do I do so?
The link isn't working for me, so I can't see exactly what you are getting at, but I assume that you're trying to change that default blue-ish gradient. You need to override the template for the button in a style, and then you can customize it to look however you want. You can't just set the background color or use triggers to change it without overriding the template, because the default template has some extra stuff in it to show that gradient effect.
Here is an example of a button I have used before that is fairly straightforward. This example uses a trigger to change the foreground color of the button when it is pressed, but will never change the background color.
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="White"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="Foreground" Value="{StaticResource BrushBtnText}"/>
<Setter Property="Margin" Value="8,4,8,4"/>
<Setter Property="Padding" Value="6"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="{StaticResource BrushBorderLight}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Margin="{TemplateBinding Margin}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="{StaticResource BrushBtnText}"/>
</Trigger>
</Style.Triggers>
</Style>
Also, if you're interested, here is what the button's default template is:
<Style TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Themes:ButtonChrome x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RenderDefaulted="{TemplateBinding IsDefaulted}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Themes:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="RenderDefaulted" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Actually, I found the thing where I was going wrong. Whenever my pointer goes to a button, does not change the background of the button or even the foreground of the button, but it changes the background of the border.
So, while overwriting the button style, actually the border of the background has to be overwritten and not the button foreground or the background.
Here is the answer to this question : How to Disable MouseOver Effects

Remove Border around Button

I've been trying to remove the Border around a Button and also change the Colour of the Button's Background when the mouse hovers over it.
Here is what I have:
<Button Name="Home" Content="Home" HorizontalAlignment="Left" Width="75" Click="Button_Click_Home" Background="#FF252525" FontFamily="/VideoManager;component/#Myriad Pro" FontSize="13.333" Foreground="White" BorderThickness="5">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderThickness="0"/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF36290A"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
The issue is that regardless of what I set BorderThickness to, the Button disappears. Also the Button is not changing to the colour I specified with the Trigger.
I also tried simply using a Style Setter but found this had no effect on my Button.
<Style TargetType="{x:Type Button}">
<Setter Property="BorderThickness" Value="0"/>
</Style>
You need to define following ControlTemplate and remove Style Trigger.
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="border"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="border"
Property="Background"
Value="#FF36290A" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
I have tried this and this is working.
I have a style that I use to remove the default Windows style from buttons ; I'm sure you can use it or use it to achieve what you want. As it is, it just makes a button with absolutely no border, no background, no margins, nothing, just play with the template to achieve what you want :
<Style x:Key="NoChromeButton" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid x:Name="Chrome" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
<Setter Property="Opacity" TargetName="Chrome" Value="0.5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
It is not mine but I don't remember where I found it, so sorry if the author come by !
You could also take the default button template from MSDN and tweak it.

Remove default Hover Blue color in a Wpf button [duplicate]

I'm trying to disable the MouseOver effect on buttons, or at least change the colour of it, in WPF.
I'm using the following style:
<Style x:Key="Borderless" TargetType="{x:Type Button}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Button Background="{TemplateBinding Control.Background}"
Focusable="False">
<ContentPresenter
Margin="{TemplateBinding Control.Padding}"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
RecognizesAccessKey="True"
Content="{TemplateBinding ContentControl.Content}" />
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
in Window.Resources, which I thought would override all the default behaviours. But it doesn't.
Any suggestions?
Look what your control template boils down to:
<ControlTemplate TargetType="{x:Type Button}">
<Button>
<ContentPresenter/>
</Button>
</ControlTemplate>
You're saying, "I want to replace the look of my button with... a button." The usage of the ControlTemplate is to replace the visual tree of a control. So you are replacing the visual tree of the existing button with another button. If you want to start a button from scratch, try using the SimpleStyles button:
<Style TargetType="{x:Type Button}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="MinHeight" Value="23"/>
<Setter Property="MinWidth" Value="75"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Border" CornerRadius="2" BorderThickness="1"
Background="#C0C0C0"
BorderBrush="#404040">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter TargetName="Border"
Property="BorderBrush" Value="#202020" />
</Trigger>
<Trigger Property="IsDefaulted" Value="true">
<Setter TargetName="Border"
Property="BorderBrush" Value="#202020" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border"
Property="Background" Value="#808080" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border"
Property="Background" Value="#E0E0E0" />
<Setter TargetName="Border"
Property="BorderBrush" Value="#606060" />
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border"
Property="Background" Value="#EEEEEE" />
<Setter TargetName="Border"
Property="BorderBrush" Value="#AAAAAA" />
<Setter Property="Foreground" Value="#888888"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Notice that this template creates a button the simplest possible way: a border that contains the button content. It does not use another button embedded inside the template.

Transparent button background in WPF using style

I've found this topic about setting the border of a button to transparent.
This works fine, but I want to use this for the button background and not the border.
Solution in link which I've put in <Window.Resources>...</Window.Resources>:
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green"/>
<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="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
Source: How do you change Background for a Button MouseOver in WPF?
How can edit this code so I can use this to set the background of my button to transparent and not the border of it?
Try this snippet for a transparent button:
<Button Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" BorderThickness="0">
<-- PUT BUTTON CONTENT HERE e.g. a Image -->
</Button>
Found the solution for my issue:
Apparently you have to add the triggers within the ControlTemplate under ControlTemplate.Trigger. Andd after you've done that the thing with borders is that you have to set a TargetName in the Border tag and then set the reference (-> TargetName="XXXXX") to the properties which you've named in the border tag.
So:
<Window.Resources>
<Style x:Key="MenuButton" TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Height" Value="40" />
<Setter Property="Width" Value="Auto" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Margin" Value="45,0,0,0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border Name="MenuBorder" SnapsToDevicePixels="True" BorderBrush="Black" Background="{TemplateBinding Background}" BorderThickness="0,0,0,2" >
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsFocused" Value="True">
<Setter Property="Background" Value="Transparent"/>
<Setter TargetName="MenuBorder" Property="BorderBrush" Value="#FFED6A2B" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Change this line
<Setter Property="Background" Value="Red"/>
to
<Setter Property="Background" Value="Transparent"/>
Use this in C# code
Button btn = new Button() {BorderBrush=System.Windows.Media.Brushes.Transparent,
BorderThickness = new Thickness(0)};
or
yourBtn.BorderBrush=System.Windows.Media.Brushes.Transparent;
yourBtn.BorderThickness =new Thickness(0);

Categories