WPF子彈頭複選框(BulletCheckBox)

效果:



Style:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    xmlns:local="clr-namespace:CheckBoxTest.Controls"
    xmlns:converter="clr-namespace:CheckBoxTest.Controls.Converter">

    <sys:Double x:Key="BulletCheckBox.FixWidth">70</sys:Double>
    <sys:Double x:Key="BulletCheckBox.FixHeight">28</sys:Double>
    <sys:Double x:Key="BulletCheckBox.Unckecked.HandleWidth">15</sys:Double>
    <sys:Double x:Key="BulletCheckBox.Ckecked.HandleWidth">21</sys:Double>
    <sys:Double x:Key="BulletCheckBox.MovePosition">40</sys:Double>
    <SolidColorBrush x:Key="BulletCheckBox.Unckecked.BorderBrush" Color="#FF333333"/>
    <SolidColorBrush x:Key="BulletCheckBox.Unckecked.Background" Color="#FFEEEEEE"/>
    <SolidColorBrush x:Key="BulletCheckBox.Unckecked.HandleBackground" Color="#FF333333"/>
    <SolidColorBrush x:Key="BulletCheckBox.Ckecked.Background" Color="#FF0078D7"/>
    <SolidColorBrush x:Key="BulletCheckBox.OutSide.Foreground" Color="#FF444444"/>


    <sys:Double x:Key="BulletCheckBox.OutsideTextFixWidth">44</sys:Double>
    <sys:Double x:Key="BulletCheckBox.OutsideTextFixHeight">20</sys:Double>
    <sys:Double x:Key="BulletCheckBox.OutsideTextMovePosition">22</sys:Double>
    <sys:Double x:Key="BulletCheckBox.Unckecked.OutsideTextHandleWidth">8</sys:Double>
    <sys:Double x:Key="BulletCheckBox.Ckecked.OutsideTextHandleWidth">12</sys:Double>
    <SolidColorBrush x:Key="BulletCheckBox.Unckecked.OutsideTextBackground" Color="#FFEEEEEE"/>

    <SolidColorBrush x:Key="BulletCheckBox.Ckecked.OutsideTextBackground" Color="#FF0078D7"/>

    <ControlTemplate x:Key="BulletCheckBox_FixTempleate" TargetType="{x:Type local:BulletCheckBox}">

        <Grid HorizontalAlignment="Left" VerticalAlignment="Center">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <Border x:Name="border" Grid.Column="1" SnapsToDevicePixels="True"
                Margin="0"
                BorderThickness="2"
                CornerRadius="12"
                Background="{StaticResource BulletCheckBox.Unckecked.Background}"
                BorderBrush="{StaticResource BulletCheckBox.Unckecked.BorderBrush}"
                Width="{StaticResource BulletCheckBox.FixWidth}"
                Height="{StaticResource BulletCheckBox.FixHeight}"
                VerticalAlignment="Stretch">
                <Grid>
                    <Border x:Name="checkHandle"
                        Margin="3,2"
                        CornerRadius="12"
                        Width="{StaticResource BulletCheckBox.Unckecked.HandleWidth}"
                        Height="{StaticResource BulletCheckBox.Unckecked.HandleWidth}"
                        SnapsToDevicePixels="True"
                        Background="{StaticResource BulletCheckBox.Unckecked.HandleBackground}"
                        HorizontalAlignment="Left">
                        <Border.RenderTransform>
                            <TranslateTransform x:Name="handleTranslate" X="0"/>
                        </Border.RenderTransform>
                    </Border>
                    <TextBlock x:Name="checkedText" Text="{TemplateBinding CheckedText}" FontSize="16"
                           HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center"
                           Margin="5,0,0,0" Visibility="Collapsed"
                           Foreground="{Binding CheckedForeground, RelativeSource={RelativeSource TemplatedParent}}"/>

                    <TextBlock x:Name="uncheckedText" Text="{TemplateBinding UncheckedText}" FontSize="16"
                           Foreground="{TemplateBinding Foreground}"
                           VerticalAlignment="Center" HorizontalAlignment="Right" TextAlignment="Center"
                           Margin="0,0,5,0" Visibility="Visible">
                    </TextBlock>
                </Grid>
            </Border>

            <TextBlock x:Name="outsideText" Grid.Column="2"
                       Text="{TemplateBinding UncheckedText}" FontSize="18"
                       HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center"
                       Margin="8,0,0,0" Visibility="Collapsed"
                       Foreground="{StaticResource BulletCheckBox.OutSide.Foreground}"/>
        </Grid>

        <ControlTemplate.Triggers>
            <DataTrigger Binding="{Binding Path=IsTextOutside, RelativeSource={RelativeSource Mode=Self}}" Value="True">
                <Setter TargetName="checkedText" Property="Visibility" Value="Collapsed"/>
                <Setter TargetName="checkedText" Property="Foreground" Value="Transparent"/>
                <Setter TargetName="uncheckedText" Property="Visibility" Value="Collapsed"/>
                <Setter TargetName="outsideText" Property="Visibility" Value="Visible"/>

                <Setter TargetName="border" Property="Width" Value="{StaticResource BulletCheckBox.OutsideTextFixWidth}"/>
                <Setter TargetName="border" Property="Height" Value="{StaticResource BulletCheckBox.OutsideTextFixHeight}"/>
                <Setter TargetName="border" Property="CornerRadius" Value="8"/>
                
                <Setter TargetName="checkHandle" Property="Width" Value="{StaticResource BulletCheckBox.Unckecked.OutsideTextHandleWidth}"/>
                <Setter TargetName="checkHandle" Property="Height" Value="{StaticResource BulletCheckBox.Unckecked.OutsideTextHandleWidth}"/>
            </DataTrigger>

            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Path=IsChecked, RelativeSource={RelativeSource Mode=Self}}" Value="True"/>
                    <Condition Binding="{Binding Path=IsTextOutside, RelativeSource={RelativeSource Mode=Self}}" Value="True"/>
                </MultiDataTrigger.Conditions>

                <Setter TargetName="border" Property="Background" Value="{StaticResource BulletCheckBox.Ckecked.OutsideTextBackground}"/>
                <Setter TargetName="border" Property="BorderBrush" Value="{StaticResource BulletCheckBox.Ckecked.OutsideTextBackground}"/>
                <Setter TargetName="checkHandle" Property="Background" Value="{StaticResource BulletCheckBox.Unckecked.OutsideTextBackground}"/>
                <Setter TargetName="checkHandle" Property="Width" Value="{StaticResource BulletCheckBox.Ckecked.OutsideTextHandleWidth}"/>
                <Setter TargetName="checkHandle" Property="Height" Value="{StaticResource BulletCheckBox.Ckecked.OutsideTextHandleWidth}"/>
                
                <MultiDataTrigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="handleTranslate" Storyboard.TargetProperty="X" To="{StaticResource BulletCheckBox.OutsideTextMovePosition}" Duration="0:0:0.2" />
                        </Storyboard>
                    </BeginStoryboard>
                </MultiDataTrigger.EnterActions>

                <MultiDataTrigger.ExitActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="handleTranslate" Storyboard.TargetProperty="X" To="0" Duration="0:0:0.2" />
                        </Storyboard>
                    </BeginStoryboard>
                </MultiDataTrigger.ExitActions>
            </MultiDataTrigger>

            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding Path=IsChecked, RelativeSource={RelativeSource Mode=Self}}" Value="True"/>
                    <Condition Binding="{Binding Path=IsTextOutside, RelativeSource={RelativeSource Mode=Self}}" Value="False"/>
                </MultiDataTrigger.Conditions>

                <Setter TargetName="checkedText" Property="Visibility" Value="Visible"/>
                <Setter TargetName="uncheckedText" Property="Visibility" Value="Collapsed"/>
                <Setter TargetName="checkHandle" Property="Background" Value="{StaticResource BulletCheckBox.Unckecked.Background}"/>
                <Setter TargetName="checkHandle" Property="Width" Value="{StaticResource BulletCheckBox.Ckecked.HandleWidth}"/>
                <Setter TargetName="checkHandle" Property="Height" Value="{StaticResource BulletCheckBox.Ckecked.HandleWidth}"/>
                <Setter TargetName="border" Property="Background" Value="{StaticResource BulletCheckBox.Ckecked.Background}"/>
                <Setter TargetName="border" Property="BorderBrush" Value="{StaticResource BulletCheckBox.Ckecked.Background}"/>
                <Setter TargetName="outsideText" Property="Text" Value="{Binding CheckedText, RelativeSource={RelativeSource TemplatedParent}}"/>
                <MultiDataTrigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="handleTranslate" Storyboard.TargetProperty="X" To="{StaticResource BulletCheckBox.MovePosition}" Duration="0:0:0.2" />
                        </Storyboard>
                    </BeginStoryboard>
                </MultiDataTrigger.EnterActions>
                <MultiDataTrigger.ExitActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="handleTranslate" Storyboard.TargetProperty="X" To="0" Duration="0:0:0.2" />
                        </Storyboard>
                    </BeginStoryboard>
                </MultiDataTrigger.ExitActions>
            </MultiDataTrigger>

            <Trigger Property="IsEnabled" Value="false">
                <Setter TargetName="border" Property="Opacity" Value="0.5"/>
                <Setter TargetName="outsideText" Property="Opacity" Value="0.5"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

    <ControlTemplate x:Key="BulletCheckBox_Templeate" TargetType="{x:Type local:BulletCheckBox}">
        <Viewbox x:Name="viewBox" Stretch="None"  HorizontalAlignment="Left" VerticalAlignment="Center">
            <Grid HorizontalAlignment="Left" VerticalAlignment="Center">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>

                <Border x:Name="border" Grid.Column="1" SnapsToDevicePixels="True"  
                Margin="0"  
                BorderThickness="2"  
                CornerRadius="12"  
                Background="{StaticResource BulletCheckBox.Unckecked.Background}"  
                BorderBrush="{StaticResource BulletCheckBox.Unckecked.BorderBrush}"  
                Width="{StaticResource BulletCheckBox.FixWidth}"  
                Height="{StaticResource BulletCheckBox.FixHeight}"  
                VerticalAlignment="Stretch">
                    <Grid>
                        <Border x:Name="checkHandle"  
                        Margin="3,2"  
                        CornerRadius="12"  
                        Width="{StaticResource BulletCheckBox.Unckecked.HandleWidth}"  
                        Height="{StaticResource BulletCheckBox.Unckecked.HandleWidth}"  
                        SnapsToDevicePixels="True"  
                        Background="{StaticResource BulletCheckBox.Unckecked.HandleBackground}"  
                        HorizontalAlignment="Left">
                            <Border.RenderTransform>
                                <TranslateTransform x:Name="handleTranslate" X="0"/>
                            </Border.RenderTransform>
                        </Border>
                        <TextBlock x:Name="checkedText" Text="{TemplateBinding CheckedText}" FontSize="16"  
                           HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center"  
                           Margin="5,0,0,0" Visibility="Collapsed"  
                           Foreground="{Binding CheckedForeground, RelativeSource={RelativeSource TemplatedParent}}"/>

                        <TextBlock x:Name="uncheckedText" Text="{TemplateBinding UncheckedText}" FontSize="16"  
                           Foreground="{TemplateBinding Foreground}"  
                           VerticalAlignment="Center" HorizontalAlignment="Right" TextAlignment="Center"  
                           Margin="0,0,5,0" Visibility="Visible">
                        </TextBlock>
                    </Grid>
                </Border>

                <TextBlock x:Name="outsideText" Grid.Column="2"  
                       Text="{TemplateBinding UncheckedText}" FontSize="18"  
                       HorizontalAlignment="Left" VerticalAlignment="Center" TextAlignment="Center"  
                       Margin="8,0,0,0" Visibility="Collapsed"  
                       Foreground="{StaticResource BulletCheckBox.OutSide.Foreground}"/>
            </Grid>
        </Viewbox>

        <ControlTemplate.Triggers>
            <DataTrigger Binding="{Binding IsViewBoxEnable,RelativeSource={RelativeSource Self}}" Value="True">
                <Setter TargetName="viewBox" Property="Stretch" Value="Uniform"/>
            </DataTrigger>

            <DataTrigger Binding="{Binding Path=IsTextOutside, RelativeSource={RelativeSource Mode=Self}}" Value="True">
                <Setter TargetName="checkedText" Property="Visibility" Value="Collapsed"/>
                <Setter TargetName="checkedText" Property="Foreground" Value="Transparent"/>
                <Setter TargetName="uncheckedText" Property="Visibility" Value="Collapsed"/>
                <Setter TargetName="outsideText" Property="Visibility" Value="Visible"/>
            </DataTrigger>

            <Trigger Property="IsChecked" Value="True">
                <Setter TargetName="checkedText" Property="Visibility" Value="Visible"/>
                <Setter TargetName="uncheckedText" Property="Visibility" Value="Collapsed"/>
                <Setter TargetName="checkHandle" Property="Background" Value="{StaticResource BulletCheckBox.Unckecked.Background}"/>
                <Setter TargetName="checkHandle" Property="Width" Value="{StaticResource BulletCheckBox.Ckecked.HandleWidth}"/>
                <Setter TargetName="checkHandle" Property="Height" Value="{StaticResource BulletCheckBox.Ckecked.HandleWidth}"/>
                <Setter TargetName="border" Property="Background" Value="{StaticResource BulletCheckBox.Ckecked.Background}"/>
                <Setter TargetName="border" Property="BorderBrush" Value="{StaticResource BulletCheckBox.Ckecked.Background}"/>
                <Setter TargetName="outsideText" Property="Text" Value="{Binding CheckedText, RelativeSource={RelativeSource TemplatedParent}}"/>
                <Trigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="handleTranslate" Storyboard.TargetProperty="X" To="{StaticResource BulletCheckBox.MovePosition}" Duration="0:0:0.2" />
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.EnterActions>
                <Trigger.ExitActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="handleTranslate" Storyboard.TargetProperty="X" To="0" Duration="0:0:0.2" />
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.ExitActions>
            </Trigger>

            <Trigger Property="IsEnabled" Value="false">
                <Setter TargetName="border" Property="Opacity" Value="0.5"/>
                <Setter TargetName="outsideText" Property="Opacity" Value="0.5"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

    <!--固定大小-->
    <Style x:Key="BulletCheckBoxFixedStyle" TargetType="{x:Type local:BulletCheckBox}">
        <Setter Property="Background" Value="#FF4A9E4A"/>
        <Setter Property="Foreground" Value="#FFAAAAAA"/>
        <Setter Property="CheckedForeground" Value="White"/>
        <Setter Property="CheckedBackground" Value="#FF0CC50C"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="Cursor" Value="Hand"/>
        <Setter Property="Width" Value="{Binding Width, RelativeSource={RelativeSource TemplatedParent}}"/>
        <Setter Property="Height" Value="{Binding Height, RelativeSource={RelativeSource TemplatedParent}}"/>
        <Setter Property="Margin" Value="1"/>
        <Setter Property="Template" Value="{StaticResource BulletCheckBox_FixTempleate}"/>
    </Style>

    <!--ViewBox可縮放-->
    <Style TargetType="{x:Type local:BulletCheckBox}">
        <Setter Property="Background" Value="#FF4A9E4A"/>
        <Setter Property="Foreground" Value="#FFAAAAAA"/>
        <Setter Property="CheckedForeground" Value="White"/>
        <Setter Property="CheckedBackground" Value="#FF0CC50C"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="Cursor" Value="Hand"/>
        <Setter Property="Width" Value="{Binding Width, RelativeSource={RelativeSource TemplatedParent}}"/>
        <Setter Property="Height" Value="{Binding Height, RelativeSource={RelativeSource TemplatedParent}}"/>
        <Setter Property="Margin" Value="0"/>
        <Setter Property="Template" Value="{StaticResource BulletCheckBox_Templeate}"/>
    </Style>
</ResourceDictionary>

CS:

public class BulletCheckBox : CheckBox
{
    static BulletCheckBox()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(BulletCheckBox), new FrameworkPropertyMetadata(typeof(BulletCheckBox)));
    }

    public BulletCheckBox()
    {
    }

    //protected override void OnChecked(RoutedEventArgs e)
    //{
    //    base.OnChecked(e);
    //}

    public static readonly DependencyProperty UncheckedTextProperty = DependencyProperty.Register(nameof(UncheckedText), typeof(string), typeof(BulletCheckBox), 
                                                                                                new PropertyMetadata(""));
    /// <summary>
    /// 默認文本(未選中)
    /// </summary>
    public string UncheckedText
    {
        get { return (string)GetValue(UncheckedTextProperty); }
        set { SetValue(UncheckedTextProperty, value); }
    }

    public static readonly DependencyProperty CheckedTextProperty = DependencyProperty.Register(nameof(CheckedText), typeof(string), typeof(BulletCheckBox), 
                                                                                            new PropertyMetadata(""));
    /// <summary>
    /// 選中狀態文本
    /// </summary>
    public string CheckedText
    {
        get { return (string)GetValue(CheckedTextProperty); }
        set { SetValue(CheckedTextProperty, value); }
    }

    public static readonly DependencyProperty CheckedForegroundProperty =
        DependencyProperty.Register(nameof(CheckedForeground), typeof(Brush), typeof(BulletCheckBox), new PropertyMetadata(Brushes.WhiteSmoke));
    /// <summary>
    /// 選中狀態前景樣式
    /// </summary>
    public Brush CheckedForeground
    {
        get { return (Brush)GetValue(CheckedForegroundProperty); }
        set { SetValue(CheckedForegroundProperty, value); }
    }

    public static readonly DependencyProperty CheckedBackgroundProperty = DependencyProperty.Register(nameof(CheckedBackground), typeof(Brush), typeof(BulletCheckBox), 
                                                            new PropertyMetadata(new SolidColorBrush(Color.FromArgb(255, 0, 120,215))));
    /// <summary>
    /// 選中狀態背景色
    /// </summary>
    public Brush CheckedBackground
    {
        get { return (Brush)GetValue(CheckedBackgroundProperty); }
        set { SetValue(CheckedBackgroundProperty, value); }
    }

    public static readonly DependencyProperty IsTextOutsideProperty = DependencyProperty.Register(nameof(IsTextOutside), typeof(bool), typeof(BulletCheckBox),
                                                            new PropertyMetadata(false));
    /// <summary>
    /// 文本顯示在外面
    /// </summary>
    public bool IsTextOutside
    {
        get { return (bool)GetValue(IsTextOutsideProperty); }
        set { SetValue(IsTextOutsideProperty, value); }
    }

    public static readonly DependencyProperty IsViewBoxEnableProperty = DependencyProperty.Register(nameof(IsViewBoxEnable), typeof(bool), typeof(BulletCheckBox),
                                                            new PropertyMetadata(false));
    /// <summary>
    /// 是否是能ViewBox縮放功能
    /// </summary>
    public bool IsViewBoxEnable
    {
        get { return (bool)GetValue(IsViewBoxEnableProperty); }
        set { SetValue(IsViewBoxEnableProperty, value); }
    }
}


使用:

<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
    <CheckBox Content="男"/>
    <TextBlock  x:Name="icon"
                                Text=""
                                FontFamily="/CheckBoxTest;component/Resources/#iconfont"
                                FontSize="30"
                                Margin="5"
                                Foreground="Red"/>
    <contros:BulletCheckBox UncheckedText="OFF" CheckedText="ON" Width="70" HorizontalAlignment="Left"/>
    <contros:BulletCheckBox UncheckedText="@_@" CheckedText="~_~"/>
    <contros:BulletCheckBox UncheckedText="OFF" CheckedText="ON" Style="{StaticResource BulletCheckBoxFixedStyle}"/>
    <contros:BulletCheckBox UncheckedText="關" CheckedText="開" 
                            IsTextOutside="True"
                            IsViewBoxEnable="True"/>
    <contros:BulletCheckBox UncheckedText="關" CheckedText="開" 
                            IsTextOutside="True"/>
    <contros:BulletCheckBox UncheckedText="關" CheckedText="開" 
                            IsTextOutside="True"
                            Style="{StaticResource BulletCheckBoxFixedStyle}"/>
    <contros:BulletCheckBox
                            IsTextOutside="True"
                            Style="{StaticResource BulletCheckBoxFixedStyle}"/>
</StackPanel>



發佈了32 篇原創文章 · 獲贊 5 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章