WPF上位机自定义控件系列:切换按钮WxToggleButton
WPF 上位机自定义控件系列
- 切换按钮 WxToggleButton
增加依赖属性 Text 用于显示文本
典型的绿色(正常)、红色(异常)搭配
ToggleButtonType 类型
public enum ToggleButtonType
None,
ON_OFF,
开_关,
在线_离线,
选中_未选,
运行_待机
WxToggleButton 类
public class WxToggleButton : ToggleButton
static WxToggleButton()
DefaultStyleKeyProperty.OverrideMetadata(typeof(WxToggleButton), new FrameworkPropertyMetadata(typeof(WxToggleButton)));
/// <summary>
/// 权限等级
/// </summary>
public int AuthorityLevel
get => (int)GetValue(AuthorityLevelProperty);
set => SetValue(AuthorityLevelProperty, value);
public static readonly DependencyProperty AuthorityLevelProperty =
DependencyProperty.Register("AuthorityLevel", typeof(int), typeof(WxToggleButton), new PropertyMetadata(1, OnAuthorityLevelChanged));
/// <summary>
/// 修改权限时触发 设置 IsEnabled 的值
/// </summary>
/// <param name="d"></param>
/// <param name="e"></param>
private static void OnAuthorityLevelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
WxToggleButton obj = d as WxToggleButton;
int value = (int)obj.GetValue(AuthorityLevelMinProperty);
obj
.SetValue(IsEnabledProperty, (int)e.NewValue >= value);
/// <summary>
/// 最低使用权限
/// </summary>
public int AuthorityLevelMin
get => (int)GetValue(AuthorityLevelMinProperty);
set => SetValue(AuthorityLevelMinProperty, value);
public static readonly DependencyProperty AuthorityLevelMinProperty =
DependencyProperty.Register("AuthorityLevelMin", typeof(int), typeof(WxToggleButton), new PropertyMetadata(1, OnAuthorityLevelMinChanged));
/// <summary>
/// 修改权限时触发 设置 IsEnabled 的值
/// </summary>
/// <param name="d"></param>
/// <param name="e"></param>
private static void OnAuthorityLevelMinChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
WxToggleButton obj = d as WxToggleButton;
int value = (int)obj.GetValue(AuthorityLevelProperty);
obj.SetValue(IsEnabledProperty, value >= (int)e.NewValue);
/// <summary>
/// 中间文本
/// </summary>
public string Text
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(WxToggleButton), new PropertyMetadata(null, OnPropertyChanged));
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
d.SetValue(e.Property, e.NewValue);
/// <summary>
/// 类型
/// </summary>
public ToggleButtonType ToggleButtonType
get => (ToggleButtonType)GetValue(ToggleButtonTypeProperty);
set => SetValue(ToggleButtonTypeProperty, value);
public static readonly DependencyProperty ToggleButtonTypeProperty =
DependencyProperty.Register("ToggleButtonType", typeof(ToggleButtonType), typeof(WxToggleButton), new PropertyMetadata(ToggleButtonType.None, OnPropertyChanged));
xaml 样式
使用了两个 Ellipse,每种状态设置其中一个隐藏或者和背景色一致
<!--#region -->
<Style TargetType="{x:Type cx:WxToggleButton}">
<Setter Property="Focusable" Value="False" />
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Height" Value="NaN"/>
<Setter Property="Width" Value="120"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="Background" Value="{DynamicResource BrushDanger}"/>
<Setter Property="Foreground" Value="{DynamicResource BrushRegion}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="cx:ExtendElement.CornerRadius" Value="20"/>
<Setter Property="cx:ExtendElement.IconSize" Value="20"/>
<Setter Property="Text" Value="Off"/>
<Setter Property="IsChecked" Value="False"/>
<Setter Property="Padding" Value="3"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type cx:WxToggleButton}">
<Border x:Name="border" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
CornerRadius="{Binding Path=(cx:ExtendElement.CornerRadius), RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Ellipse Grid.Column="0" x:Name="PART_UnChecked" Width="{Binding Path=(cx:ExtendElement.IconSize), RelativeSource={RelativeSource TemplatedParent}}"
Height="{Binding Path=(cx:ExtendElement.IconSize), RelativeSource={RelativeSource TemplatedParent}}"
VerticalAlignment="Center" HorizontalAlignment="Left" Margin="2" Fill="{TemplateBinding Foreground}"/>
<TextBlock Grid.Column="1" x:Name="PART_Text" Text="{TemplateBinding Text}" Foreground="{TemplateBinding Foreground}"
VerticalAlignment="Center" TextAlignment="Center" Padding="2"/>
<Ellipse Grid.Column="2" x:Name="PART_Checked" Width="{Binding Path=(cx:ExtendElement.IconSize), RelativeSource={RelativeSource TemplatedParent}}"
Height="{Binding Path=(cx:ExtendElement.IconSize), RelativeSource={RelativeSource TemplatedParent}}"
VerticalAlignment="Center" HorizontalAlignment="Left" Margin="5,2" Fill="{TemplateBinding Foreground}"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True"/>
<Condition Property="ToggleButtonType" Value="None"/>
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="{DynamicResource BrushSuccess}"/>
<Setter TargetName="PART_UnChecked" Property="Fill" Value="{DynamicResource BrushSuccess}"/>
<Setter TargetName="PART_Checked" Property="Fill" Value="{DynamicResource BrushRegion}"/>
<Setter TargetName="PART_Text" Property="Text" Value=""/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="False"/>
<Condition Property="ToggleButtonType" Value="None"/>
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="{DynamicResource BrushDanger}"/>
<Setter
TargetName="PART_UnChecked" Property="Fill" Value="{DynamicResource BrushRegion}"/>
<Setter TargetName="PART_Checked" Property="Fill" Value="{DynamicResource BrushDanger}"/>
<Setter TargetName="PART_Text" Property="Text" Value=""/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True"/>
<Condition Property="ToggleButtonType" Value="ON_OFF"/>
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="{DynamicResource BrushSuccess}"/>
<Setter TargetName="PART_UnChecked" Property="Fill" Value="{DynamicResource BrushSuccess}"/>
<Setter TargetName="PART_Checked" Property="Fill" Value="{DynamicResource BrushRegion}"/>
<Setter TargetName="PART_Text" Property="Text" Value="ON"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="False"/>
<Condition Property="ToggleButtonType" Value="ON_OFF"/>
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="{DynamicResource BrushDanger}"/>
<Setter TargetName="PART_UnChecked" Property="Fill" Value="{DynamicResource BrushRegion}"/>
<Setter TargetName="PART_Checked" Property="Fill" Value="{DynamicResource BrushDanger}"/>
<Setter TargetName="PART_Text" Property="Text" Value="OFF"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True"/>
<Condition Property="ToggleButtonType" Value="开_关"/>
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="{DynamicResource BrushSuccess}"/>
<Setter TargetName="PART_UnChecked" Property="Fill" Value="{DynamicResource BrushSuccess}"/>
<Setter TargetName="PART_Checked" Property="Fill" Value="{DynamicResource BrushRegion}"/>
<Setter TargetName="PART_Text" Property="Text" Value="开"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="False"/>
<Condition Property="ToggleButtonType" Value="开_关"/>
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="{DynamicResource BrushDanger}"/>
<Setter TargetName="PART_UnChecked" Property="Fill" Value="{DynamicResource BrushRegion}"/>
<Setter TargetName="PART_Checked" Property="Fill" Value="{DynamicResource BrushDanger}"/>
<Setter TargetName="PART_Text" Property="Text" Value="关"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True"/>
<Condition Property="ToggleButtonType" Value="在线_离线"/>
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="{DynamicResource BrushSuccess}"/>
<Setter TargetName="PART_UnChecked" Property="Fill" Value="{DynamicResource BrushSuccess}"/>
<Setter TargetName="PART_Checked" Property="Fill" Value="{DynamicResource BrushRegion}"/>
<Setter TargetName="PART_Text" Property="Text" Value="在线"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="False"/>
<Condition Property="ToggleButtonType" Value="在线_离线"/>
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="{DynamicResource BrushDanger}"/>
<Setter TargetName="PART_UnChecked" Property="Fill" Value="{DynamicResource BrushRegion}"/>
<Setter TargetName="PART_Checked" Property="Fill" Value="{DynamicResource BrushDanger}"/>
<Setter TargetName="PART_Text" Property="Text" Value="离线"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True"/>
<Condition Property="ToggleButtonType" Value="选中_未选"/>
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="{DynamicResource BrushSuccess}"/>
<Setter TargetName="PART_UnChecked" Property="Fill" Value="{DynamicResource BrushSuccess}"/>
<Setter TargetName="PART_Checked" Property="Fill" Value="{DynamicResource BrushRegion}"/>
<Setter TargetName="PART_Text" Property="Text" Value="选中"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="False"/>
<Condition Property="ToggleButtonType" Value="选中_未选"/>
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="{DynamicResource BrushDanger}"/>
<Setter TargetName="PART_UnChecked" Property="Fill" Value="{DynamicResource BrushRegion}"/>
<Setter TargetName="PART_Checked" Property="Fill" Value="{DynamicResource BrushDanger}"/>
<Setter TargetName="PART_Text" Property="Text" Value="未选"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="True"/>
<Condition Property="ToggleButtonType" Value="运行_待机"/>
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="{DynamicResource BrushSuccess}"/>
<Setter TargetName="PART_UnChecked" Property="Fill" Value="{DynamicResource BrushSuccess}"/>
<Setter TargetName="PART_Checked" Property="Fill" Value="{DynamicResource BrushRegion}"/>
<Setter TargetName="PART_Text" Property="Text" Value="运行"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsChecked" Value="False"/>
<Condition Property="ToggleButtonType" Value="运行_待机"/>
</MultiTrigger.Conditions>
<Setter TargetName="border" Property="Background" Value="{DynamicResource BrushDanger}"/>
<Setter TargetName="PART_UnChecked" Property="Fill" Value="{DynamicResource BrushRegion}"/>
<Setter TargetName="PART_Checked" Property="Fill" Value="{DynamicResource BrushDanger}"/>
<Setter TargetName="PART_Text" Property="Text" Value="待机"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--#endregion-->
使用
<WrapPanel Margin="0,0,0,20">
<cx:WxToggleButton IsChecked="False" FontSize="24" Margin="10"/>