C# WPF 自定义控件 滑块控件 开关控件 ToggleButton Switcher

滑块效果演示如图:

 源码下载地址

https://download.csdn.net/download/shizu11zz/86934041icon-default.png?t=M85Bhttps://download.csdn.net/download/shizu11zz/86934041

直接贴源码,有帮助的话求点个赞,不过分吧:

【MainWindow.Xaml】

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPF_Test2"
        x:Class="WPF_Test2.MainWindow"
        mc:Ignorable="d" x:Name="mwindow"
        Title="MainWindow" Height="350" Width="525" Background="LightBlue">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <local:Switcher Grid.Column="0" />
        <local:Switcher Grid.Column="1" Height="60" Width="160" FontSize="28" Foreground="Red" IsChecked="True"
                        BorderThickness="1" BorderBrush="Yellow" CheckedTip=" 开"  UncheckedTip="关 "
                        BallColor="Red" Checked="sw_Checked" Unchecked="sw_Unchecked"/>
    </Grid>
</Window>

【 Generic.Xaml】

<ResourceDictionary   
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="clr-namespace:WPF_Test2">
    <local:HeightCornerRadiusConverter x:Key="hcrConverter"/>
    <local:CheckedToHidenConvert x:Key="CheckedToHidenConvert"/>
    <local:CheckedToVisbilityConvert x:Key="CheckedToVisbilityConvert"/>
    <Style x:Name="SwitcherStyle" TargetType="{x:Type local:Switcher}">
        <Setter Property="Height" Value="40"/>
        <Setter Property="Width" Value="90"/>
        <Setter Property="FontSize" Value="18"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="BorderThickness" Value="2"/>
        <Setter Property="BorderBrush" Value="White"/>
        <Setter Property="Background" Value="#ff212c7e"/>
        <Setter Property="IsChecked" Value="True"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:Switcher}">
                    <Border x:Name="bd1" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="{TemplateBinding ActualHeight ,Converter={StaticResource hcrConverter}}" 
                            Background="{TemplateBinding Background}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="1">
                        <Grid x:Name="gd1">
                            <Ellipse x:Name="e1" Grid.Column="0" Fill="{TemplateBinding BallColor}" Width="{Binding ActualHeight, RelativeSource={RelativeSource Mode=Self}}"
                                     Panel.ZIndex="1" Grid.ColumnSpan="2">
                                <UIElement.RenderTransform>
                                    <TranslateTransform X="0" x:Name="trans"/>
                                </UIElement.RenderTransform>
                                <Ellipse.Style>
                                    <Style TargetType="Ellipse">
                                        <Setter Property="Margin" Value="0,3"/>
                                        <Style.Triggers>
                                            <Trigger Property="IsMouseOver" Value="True">
                                                <Setter Property="Margin" Value="0,2"/>
                                            </Trigger>
                                        </Style.Triggers>
                                    </Style>
                                </Ellipse.Style>
                            </Ellipse>
                            <TextBlock x:Name="cTip" Margin="4,2" VerticalAlignment="Center" HorizontalAlignment="Left" 
                                       Text="{TemplateBinding CheckedTip}" Visibility="{TemplateBinding IsChecked,Converter={StaticResource CheckedToHidenConvert}}"/>
                            <TextBlock x:Name="unTip" Margin="4,2" VerticalAlignment="Center" HorizontalAlignment="Right" 
                                       Text="{TemplateBinding UncheckedTip}" Visibility="{TemplateBinding IsChecked,Converter={StaticResource CheckedToVisbilityConvert}}"/>
                        </Grid>
                    </Border>
                    <ControlTemplate.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsMouseOver"  Value="True"/>
                                <Condition Property="IsChecked" Value="False"/>
                            </MultiTrigger.Conditions>
                            <MultiTrigger.Setters>
                                <Setter Property="Background" Value="LightGray"/>
                            </MultiTrigger.Setters>
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsMouseOver" Value="True"/>
                                <Condition Property="IsChecked" Value="True"/>
                            </MultiTrigger.Conditions>
                            <MultiTrigger.Setters>
                                <Setter Property="Background" Value="#ff546ab3"/>
                            </MultiTrigger.Setters>
                        </MultiTrigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsMouseOver"  Value="False"/>
                                <Condition Property="IsChecked" Value="False"/>
                            </MultiTrigger.Conditions>
                            <MultiTrigger.Setters>
                                <Setter Property="Background" Value="Gray"/>
                            </MultiTrigger.Setters>
                        </MultiTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

【Switcher.cs】

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace WPF_Test2
{
    public class Switcher : ToggleButton
    {
        private System.Windows.Media.TranslateTransform ballMoveX;
        static Switcher()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Switcher), new FrameworkPropertyMetadata(typeof(Switcher)));
        }

        #region Propdp
        public static readonly DependencyProperty CheckedTipProperty =
            DependencyProperty.Register("CheckedTip", typeof(string), typeof(Switcher), new PropertyMetadata("ON"));
        public static readonly DependencyProperty UncheckedTipProperty =
            DependencyProperty.Register("UncheckedTip", typeof(string), typeof(Switcher), new PropertyMetadata("OFF"));
        public static readonly DependencyProperty BallColorProperty =
            DependencyProperty.Register("BallColor", typeof(Brush), typeof(Switcher), new PropertyMetadata(new SolidColorBrush(Colors.White)));
 
        public string CheckedTip
        {
            get { return (string)GetValue(CheckedTipProperty); }
            set { SetValue(CheckedTipProperty, value); }
        }

        public string UncheckedTip
        {
            get { return (string)GetValue(UncheckedTipProperty); }
            set { SetValue(UncheckedTipProperty, value); }
        }
        public Brush BallColor
        {
            get { return (Brush)GetValue(BallColorProperty); }
            set { SetValue(BallColorProperty, value); }
        }
        #endregion

        public Switcher() : base()
        {
            Checked += CheckedAnimation;
            Unchecked += UncheckedAnimation;
            Loaded += (e, s) =>
            {
                ballMoveX = ((Switcher)e).GetTemplateChild("trans") as System.Windows.Media.TranslateTransform;
                if (IsChecked != null) ballMoveX.X = (IsChecked == true ? -1 : 1) * (ActualWidth - ActualHeight) / 2;
            };
        }

        #region Animations
        DoubleAnimation ballAnima = new DoubleAnimation(0, new Duration(new TimeSpan(0, 0, 0, 0, 300)))
        {
            EasingFunction = new CubicEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut }
        };

        private void CheckedAnimation(object sender, RoutedEventArgs e)
        {
            if (!IsLoaded) e.Handled = true;//未初始化成功时,不向外传递Checked事件
            if (ballMoveX == null) return;
            ballAnima.To = -(ActualWidth - ActualHeight) / 2;
            ballMoveX.BeginAnimation(System.Windows.Media.TranslateTransform.XProperty, ballAnima);
        }
        private void UncheckedAnimation(object sender, RoutedEventArgs e)
        {
            if (!IsLoaded) e.Handled = true;//未初始化成功时,不向外传递Unchecked事件
            if (ballMoveX == null) return;
            ballAnima.To = (ActualWidth - ActualHeight) / 2;
            ballMoveX.BeginAnimation(System.Windows.Media.TranslateTransform.XProperty, ballAnima);
        }
        #endregion
    }


    #region Converters
    /// <summary>
    /// 根据控件高度设置控件圆角半径
    /// 圆角半径为高度的二分之一
    /// </summary>
    public class HeightCornerRadiusConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return 0.5 * int.Parse(value.ToString());
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    /// <summary>
    /// 当Ischecked=True时,
    /// 隐藏CheckedTip文本
    /// </summary>
    public class CheckedToVisbilityConvert : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null) return Visibility.Hidden;
            return (bool)value ? Visibility.Visible : Visibility.Hidden;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    /// <summary>
    /// 当Ischecked=False时,
    /// 隐藏UncheckedTip文本
    /// </summary>
    public class CheckedToHidenConvert : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null) return Visibility.Hidden;
            return (bool)value ? Visibility.Hidden : Visibility.Visible;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    #endregion
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值