相关文章推荐
安静的西装  ·  c++ - 如何使用 Windows ...·  1 年前    · 
有腹肌的夕阳  ·  No thread-bound ...·  1 年前    · 
奔放的水煮肉  ·  解决HttpServletRequest ...·  2 年前    · 
WPF上位机自定义控件系列:切换按钮WxToggleButton

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"/>