I want to change button background by clicking the button. But, I don't want to change background using click event.
I have tried in WPF and achieved it using below code:
<Style x:Key="ButtonStyle" TargetType="Button">
<Setter Property="Background"
Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border CornerRadius="3"
BorderBrush="DarkGray"
BorderThickness="1"
Background="{TemplateBinding Background}" />
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers >
<Trigger Property="IsFocused"
Value="True">
<Setter Property="BorderThickness"
Value="2"/>
<Setter Property="FontWeight"
Value="Bold"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button Content="All"
Height="20"
Width="50"
Margin="2"
Style="{StaticResource ButtonStyle}" />
Can anyone please suggest how to achieve the same functionality in UWP?
I want to change button background by clicking the button. But, I don't want to change background using click event.
For your requirement, You could realize it via use XamlBehaviors. For example:
<Button>
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Click">
<Core:ChangePropertyAction PropertyName="Background">
<Core:ChangePropertyAction.Value>
<SolidColorBrush Color="Red"/>
</Core:ChangePropertyAction.Value>
</Core:ChangePropertyAction>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
It is open source model and host all behaviors code on GitHub will allow new features and fixes to be addressed more quickly.
Related
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>
I've got a WrapPanel containing multiple Buttons.
All buttons have the same base style to define their basic appearance.
Every button has a visible border at the right side. But I want to use styles to remove the border of the last button.
I think its quite simple. WPF is new to me, so I want to understand it.
The solutions I find on the internet are for different cases. That solutions are all concerning ListBox or ItemContainer to style some list items by index.
I don't want to just add another style key to the last Button, because that's not dynamic, and the WrapPanel is dynamically populated with Buttons depending on the state of the application.
This is my code:
<Window.Resources>
<Style x:Key="lastTabStyle" TargetType="Button">
<Setter Property="BorderThickness" Value="0" />
</Style>
<Style x:Key="tabButton" TargetType="Button">
<Setter Property="Background" Value="#FF21588B" />
<Setter Property="BorderThickness" Value="0 0 1 0" />
<Setter Property="Foreground" Value="#fff" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}" Padding="20 10 20 10">
<ContentPresenter HorizontalAlignment="left" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF266095" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="tabButtonSelected" TargetType="Button">
<Setter Property="Background" Value="#FF3474B0" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}" Padding="10 8">
<ContentPresenter HorizontalAlignment="left" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
And the WrapPanel:
<WrapPanel VerticalAlignment="Bottom" x:Name="topTabs">
<Button Style="{StaticResource tabButton}">Button 1</Button>
<Button Style="{StaticResource tabButton}">Button 2</Button>
<Button Style="{StaticResource tabButton}">Button 3</Button>
</WrapPanel>
...But I want to use styles to remove the border of the last button.
Then the define another style and apply this to the last Button or simply set ("override") the BorderThickness property of the last Button:
<WrapPanel VerticalAlignment="Bottom" x:Name="topTabs">
<Button Style="{StaticResource tabButton}">Button 1</Button>
<Button Style="{StaticResource tabButton}">Button 2</Button>
<Button Style="{StaticResource tabButton}" BorderThickness="0">Button 3</Button>
</WrapPanel>
Local values take precedence over values set by styles: https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/dependency-property-value-precedence
I would like to make a game like Shakes & Fidgets. I got stuck at the Main menu, where I already overcomplicated stuff as I always do. I made a grid layout, where I will put the buttons, but every button is a picture. I use ImageBrush for every button's picture I want to create.
I would like to create ONE style for every button so they change their backgrounds based on the x:Name or x:Key they have. So a Button with x:Name or x:Key "PlayGame" would find it's as the PlayGame.png, PlayGame_Hover, PlayGame_OnClick where "PlayGame" is a variable.
In other words I would like to have a style that can filter the x:name, or x:key of a button, and uses it as a variable later on so I can do this: {StaticResource VARIABLENAME}
The Code I have now is:
<ImageBrush x:Key="PlayGame">
<ImageBrush.ImageSource>
<BitmapImage UriSource="./Pictures/PlayGameButton.png"/>
</ImageBrush.ImageSource>
</ImageBrush>
<ImageBrush x:Key="PlayGame_Hover">
<ImageBrush.ImageSource>
<BitmapImage UriSource="./Pictures/PlayGameButton_Hover.png"/>
</ImageBrush.ImageSource>
</ImageBrush>
<ImageBrush x:Key="PlayGame_OnClick">
<ImageBrush.ImageSource>
<BitmapImage UriSource="./Pictures/PlayGameButton_OnClick.png"/>
</ImageBrush.ImageSource>
</ImageBrush>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{StaticResource PlayGame}" />
<Setter Property="FontSize" Value="15" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="4" Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,0" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource PlayGame_Hover}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{StaticResource PlayGame_OnClick}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I found a not very effective solution, but not the one I actually want
You can give the Style an
x:Key="styleKey"
and you have to give the button this part:
Style="{StaticResource styleKey}"
This way you will have to make a style for every different button you want to have, but it will work, and you will be happy about it if efficency is not key.:D
I try to change the background of a toggle button everytime when it is checked or not,using 2 pictures. At runtime, the toggle button is simple and I don't see any image. This is my code:
<Canvas Height="25" Name="canvas1" Width="186" Background="White">
<ToggleButton Name="toggle1" Height="25" Padding="0" Width="27" Canvas.Left="131" Canvas.Top="0" BorderBrush="{x:Null}" Foreground="{x:Null}">
<ToggleButton.Resources>
<Style x:Key="OnOffToggleImageStyle" TargetType="ToggleButton">
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/WpfApp;component/Images/image1.png" Stretch="Uniform" TileMode="None" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/WpfApp;component/Images/image2.png" Stretch="Uniform" TileMode="None" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
Multiple things we can point here.
Firstly you're specifying the Style in ToggleButton.Resources with a x:Key. Thus it's not implicitly set. Setting a Style in resources of the item for which it applies in it's own scope is kinda weird. Rather just apply the Style directly as <ToggleButton.Style>.
Next, when working with Style.Triggers, make it a practice to specify a default Setter. This will prevent some headache for you. Also now instead of having two triggers for IsChecked=False/True, you only need one trigger as the other Background can be set as default.
Finally it seems like all you need from the ToggleButton is the IsChecked property and switch an Image. So just override the Template and provide a simple one yourself. This way you assure the behavior to stay consistent in all version of the OS and not rely on internal default template's working nicely for your customization(which wouldn't work in Windows-8 btw, what you're trying here for IsChecked=True due to internal overrides in default ControlTemplate)
So putting this all together we get:
<Style x:Key="MyToggleButtonStyle"
TargetType="ToggleButton">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/WpfApp;component/Images/image2.png"
Stretch="Uniform"
TileMode="None" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Background="{TemplateBinding Background}" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/WpfApp;component/Images/image1.png"
Stretch="Uniform"
TileMode="None" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
and apply it to your ToggleButton
<ToggleButton Name="toggle1" Height="25" Padding="0" Width="27" Canvas.Left="131" Canvas.Top="0" BorderBrush="{x:Null}" Foreground="{x:Null}" Style="{DynamicResource MyToggleButtonStyle}">
you can ofc remove the Key in the Style and make it implicitly apply to "all" ToggleButton's within the scope of the Style definition if you choose to.
Can you check if the build action for your images is Embedded Resource please?
Define the style directly for your togglebutton like below. it should fix your issue:
<ToggleButton>
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/WpfApp;component/Images/image2.png" Stretch="Uniform" TileMode="None" />
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/WpfApp;component/Images/image1.png" Stretch="Uniform" TileMode="None" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
You should remove the x:Key and it will work.
I'm new to making custom WPF controls so I'd really appreciate a little help and some explanation. Here's the situation:
I'm trying to make a custom control with the following traits:
The control must have a content presenter.
The control must have either a disabled/enabled visual state, or be tri-state, (unstarted/inprogress/finished)
The control should if possible have support for an animation based on the state (enabled/disabled)
Ideally I'd like something that I can stack nicely like this, so any suggestions for how to do this would be appreciated.
I am using Blend 3 if anyone wants me to use VSM stuff, but I have no experience with the blend 3 extension so I'd need a little guidance and explanation if possible. Thank you all of your time!
In WPF it's very easy to change the appearance and behaviour of (standard)controls. In this case you can use a checkbox as a starting point.
First make a copy of the control's template:
"img43.imageshack.us/img43/1694/36338162.png"
You will see the folowing:
"img194.imageshack.us/img194/374/89409336.png"
Now group the BulletDecorator into a Grid, move then ContentPresenter to that Grid and remove the BulletDecorator and ist children.
"img9.imageshack.us/img9/7739/74247109.png"
At this point you have a checkbox like control that only has a ContentPresenter.
Now you can use the trigger tab to set is behaviour.
"http://img43.imageshack.us/img43/3675/15279262.png"
The code:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
x:Class="WpfApplication1.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480" mc:Ignorable="d">
<Window.Resources>
<SolidColorBrush x:Key="CheckBoxFillNormal" Color="#F4F4F4"/>
<SolidColorBrush x:Key="CheckBoxStroke" Color="#8E8F8F"/>
<Style x:Key="EmptyCheckBoxFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1" Margin="1" SnapsToDevicePixels="true"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CheckRadioFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1" Margin="14,0,0,0" SnapsToDevicePixels="true"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CheckBoxStyle1" TargetType="{x:Type CheckBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="{StaticResource CheckBoxFillNormal}"/>
<Setter Property="BorderBrush" Value="{StaticResource CheckBoxStroke}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource EmptyCheckBoxFocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid x:Name="grid" Width="64.42" Height="15.96">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="13,0,0,0" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background" TargetName="grid" Value="#FF07FF00"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" TargetName="grid" Value="Red"/>
</Trigger>
<Trigger Property="IsChecked" Value="{x:Null}">
<Setter Property="Background" Value="#FFFFDD00"/>
<Setter Property="Background" TargetName="grid" Value="#FFFFF400"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<CheckBox HorizontalAlignment="Left" Margin="117,72,0,0" Style="{DynamicResource CheckBoxStyle1}" VerticalAlignment="Top" Content="CheckBox" IsThreeState="True"/>
<CheckBox HorizontalAlignment="Left" Margin="117,91.96,0,0" Style="{DynamicResource CheckBoxStyle1}" VerticalAlignment="Top" Content="CheckBox" IsThreeState="True" IsChecked="{x:Null}"/>
<CheckBox HorizontalAlignment="Left" Margin="117,111.92,0,0" Style="{DynamicResource CheckBoxStyle1}" VerticalAlignment="Top" Content="CheckBox" IsThreeState="True" IsChecked="True"/>
<CheckBox HorizontalAlignment="Left" Margin="209,72,0,0" VerticalAlignment="Top" Content="CheckBox" IsThreeState="True"/>
<CheckBox HorizontalAlignment="Left" Margin="209,92.96,0,0" VerticalAlignment="Top" Content="CheckBox" IsChecked="{x:Null}" IsThreeState="True"/>
<CheckBox HorizontalAlignment="Left" VerticalAlignment="Top" Content="CheckBox" Margin="209,111.92,0,0" IsThreeState="True" IsChecked="True"/>
</Grid>
Was this any help to you?
Greetings,
Carl