I want to implement a button, that have 4 stage (Stage1/Stage2/Stage3/Stage4) and I want to click on it, the text and style will change (Stage1 -> Stage2 -> Stage3 -> Stage4 -> Stage1 -> ....)
Here is my XAML button code.
<ControlTemplate x:Key="StageButton" TargetType="{x:Type Button}">
<Button
Width="102"
Tag="1"
Click="Hello_Click"
BorderThickness="0"
Background="Transparent"
Cursor="Hand">
<Border
BorderThickness="2"
BorderBrush="Gray"
CornerRadius="10"
Background="Green"
Width="100"
Height="20"
>
<TextBlock
Width="100"
Foreground="White"
FontWeight="Bold"
FontSize="12"
Padding="14 1 0 0"
Text="Stage1"
/>
</Border>
</Button>
</ControlTemplate>
Thanks for help
CodePudding user response:
<ControlTemplate
x:Key="ReconStatus"
TargetType="{x:Type Button}">
<Button
Width="102"
Tag="1"
Click="Hello_Click"
BorderThickness="0"
Background="Transparent"
Cursor="Hand">
<Border
BorderThickness="2"
BorderBrush="LightGray"
CornerRadius="10"
Background="Green"
Width="100"
Height="20"
>
<TextBlock
Width="100"
Foreground="White"
FontWeight="Bold"
FontSize="12"
TextAlignment="Center"
Text=""/>
</Border>
</Button>
</ControlTemplate>
private void Hello_Click(object sender, RoutedEventArgs e)
{
Button bu = sender as Button;
var stage = bu.Tag;
Border border = bu.Content as Border;
TextBlock tb = border.Child as TextBlock;
switch (stage)
{
case "1":
tb.Text = "Stage2";
border.Background = (SolidColorBrush)new BrushConverter().ConvertFromString(Colors.DodgerBlue.ToString());
bu.Tag = "2";
break;
case "2":
tb.Text = "Stage3";
border.Background = (SolidColorBrush)new BrushConverter().ConvertFromString(Colors.Green.ToString());
bu.Tag = "3";
break;
case "3":
tb.Text = "Stage4";
border.Background = (SolidColorBrush)new BrushConverter().ConvertFromString(Colors.DimGray.ToString());
bu.Tag = "4";
break;
case "4":
tb.Text = "Stage1";
border.Background = (SolidColorBrush)new BrushConverter().ConvertFromString("#c42a1c");
bu.Tag = "1";
break;
}
}
This code work, but as @emoacht said, it nested Button object
CodePudding user response:
You can make a custom Button
with incremental stage (starting at 1) functionality:
using System;
using System.Windows;
using System.Windows.Controls;
public class StagedButton : Button
{
public int Stage
{
get { return (int)GetValue(StageProperty); }
set { SetValue(StageProperty, value); }
}
public static readonly DependencyProperty StageProperty =
DependencyProperty.Register("Stage", typeof(int), typeof(StagedButton),
new FrameworkPropertyMetadata(1, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, null,
(d, baseValue) => Math.Min(((StagedButton)d).StageCount, Math.Max(1, (int)baseValue))));
public int StageCount
{
get { return (int)GetValue(StageCountProperty); }
set { SetValue(StageCountProperty, value); }
}
public static readonly DependencyProperty StageCountProperty =
DependencyProperty.Register("StageCount", typeof(int), typeof(StagedButton),
new PropertyMetadata(1, null,
(d, baseValue) => Math.Max(1, (int)baseValue)));
protected override void OnClick()
{
var stage = Stage;
Stage = ( stage <= StageCount) ? stage : 1;
base.OnClick();
}
}
StageCount
is the number of stages. (d, baseValue) => ...
part is to filter out invalid values.
Then define a Style for this Button
.
<Style x:Key="StagedButtonStyle" TargetType="{x:Type local:StagedButton}">
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="20"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="LightGray"/>
<Setter Property="Background" Value="#c42a1c"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="TextElement.FontWeight" Value="Bold"/>
<Setter Property="TextElement.FontSize" Value="12"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:StagedButton}">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
CornerRadius="10">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<!-- Set 4 to StageCount. -->
<Setter Property="StageCount" Value="4"/>
<Style.Triggers>
<!-- Define Background for each Stage (up to 4) except default one. -->
<Trigger Property="Stage" Value="2">
<Setter Property="Background" Value="DodgerBlue"/>
</Trigger>
<Trigger Property="Stage" Value="3">
<Setter Property="Background" Value="Green"/>
</Trigger>
<Trigger Property="Stage" Value="4">
<Setter Property="Background" Value="DimGray"/>
</Trigger>
</Style.Triggers>
</Style>
You can increase the number of stages if you wish.
Its usage will be as follows:
<local:StagedButton Style="{StaticResource StagedButtonStyle}">
<TextBlock Text="{Binding Stage, RelativeSource={RelativeSource AncestorType={x:Type local:StagedButton}}, StringFormat=Stage {0}}"/>
</local:StagedButton>