Recently started WPF and am very new to XAML. I'm trying to make a calculator that looks similar to the IOS one. However, after I changed the Button
to Ellipse
, the highlighting when hovered over or clicking on stopped working, if also the highlighting issue were to be fixed, how would I go about changing the colour of it?
<Button x:Name="ButtonEquals" Grid.Column="4" Grid.Row="6" Width="47" Height="47"
Content="=" Foreground="White"
BorderBrush="{x:Null}" Background="#FFFF9500">
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Fill="#FFFF9500"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
CodePudding user response:
You need to create Style
of button instead Template
. Button's template you can set inside style (read more about Style
in WPF):
<Button x:Name="ButtonEquals"
Grid.Column="4"
Grid.Row="6"
Width="47"
Height="47"
Content="=">
<Button.Style>
<Style TargetType="Button">
<!-- Here is properties for buttons with same style-->
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="Background" Value="#FFFF9500"/>
<!-- Here is your template -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse Fill="{TemplateBinding Background}"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<!-- Here is style triggers for interact with button -->
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!-- Set color as you wish -->
<Setter Property="Background" Value="LightSalmon"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
But actually, you need to create global ResourceDictionary
(read about it) and there set styles for all buttons like <Style x:Key="CalculatorButton">
for set to buttons like <Button Content="1" Style="{StaticResource CalculatorButton}"/>
CodePudding user response:
You can add a Trigger
to the ControlTemplate
and target the Ellipse
by name assigning an x:Name
and referring to it via TargetName
. This way, you can define other states as well.
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse x:Name="MyEllipse" Fill="#FFFF9500"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="True">
<Setter TargetName="MyEllipse" Property="Fill" Value="OrangeRed"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MyEllipse" Property="Fill" Value="Blue"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="MyEllipse" Property="Fill" Value="Red"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="MyEllipse" Property="Fill" Value="Gray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
This targets only the Fill
of the Ellipse
, without changing other controls in the template. However, the values are hardcoded and not changable from outside.
If you want the template to be customizable to a certain degree, then you can put it in a Style
and bind properties on the templated control using TemplateBinding
or a RelativeSource
with TemplatedParent
for two-way and special scenarios. Additionally, you can add a FocusVisualStyle
that allows to specify a template for keyboard focusing.
<Style TargetType="Button">
<Setter Property="Background" Value="#FFFF9500"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FocusVisualStyle">
<Setter.Value>
<Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Ellipse StrokeDashArray="1 2" Stroke="DarkGreen" StrokeThickness="2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse x:Name="MyEllipse" Fill="{TemplateBinding Background}"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="True">
<Setter TargetName="MyEllipse" Property="Fill" Value="OrangeRed"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MyEllipse" Property="Fill" Value="Blue"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="MyEllipse" Property="Fill" Value="Red"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="MyEllipse" Property="Fill" Value="Gray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If you want to reuse the style on multiple buttons, add it to a resource dictionary in scope and assign an x:Key
to refer to it via StaticResource
or DynamicResource
.