自定义控件【旋转按钮,带圆角的边框】

结局方案截图:

CustomToggleButton.xaml代码:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:Local="clr-namespace:CustomControls">
    <Style TargetType="{x:Type Local:CustomToggleButton}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Local:CustomToggleButton}">
                    <Grid>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup>
                                <VisualStateGroup.Transitions>
                                    <!--transition one-->
                                    <VisualTransition GeneratedDuration="0:0:0.5" To="Right">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="ToggleTransform" Storyboard.TargetProperty="Angle" To="-90" Duration="0:0:0.3" />
                                        </Storyboard>
                                    </VisualTransition>
                                    <!--transition two-->
                                    <VisualTransition GeneratedDuration="0:0:0.5" To="Left">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="ToggleTransform" Storyboard.TargetProperty="Angle" To="90" Duration="0:0:0.3" />
                                        </Storyboard>                                    
                                    </VisualTransition>
                                </VisualStateGroup.Transitions>
                                <!--group one-->
                                <VisualState x:Name="Right">
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="ToggleTransform" Storyboard.TargetProperty="Angle" To="-90" Duration="0:0:0" />
                                    </Storyboard>
                                </VisualState>
                                <!--group two-->
                                <VisualState x:Name="Left">
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="ToggleTransform" Storyboard.TargetProperty="Angle" To="90" Duration="0:0:0" />
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="auto"/>
                            <RowDefinition Height="auto"/>
                        </Grid.RowDefinitions>
                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
                                CornerRadius="{TemplateBinding CustomCornerRadius}">
                            <ContentPresenter Content="{TemplateBinding CustomContent}"/>
                        </Border>
                        <ToggleButton x:Name="btnToggle" Width="20" Height="20" RenderTransformOrigin="0.5,0.5" Grid.Row="1">
                            <ToggleButton.Template>
                                <ControlTemplate>
                                    <Grid>
                                        <Ellipse Stroke="#FFA9A9A9" Fill="AliceBlue"/>
                                        <Path Data="M1,1.5 L4.5,5 8,1.5" Stroke="#FF666666" StrokeThickness="2" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                    </Grid>
                                </ControlTemplate>
                            </ToggleButton.Template>
                            <ToggleButton.RenderTransform>
                                <RotateTransform x:Name="ToggleTransform"/>
                            </ToggleButton.RenderTransform>
                        </ToggleButton>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

Generic.xaml代码:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="pack://application:,,,/CustomControls;component/Themes/CustomToggleButton.xaml" />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

CustomToggleButton.cs代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

namespace CustomControls
{
    public class CustomToggleButton : Control
    {
        public object CustomContent
        {
            get { return (object)GetValue(CustomContentProperty); }
            set { SetValue(CustomContentProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CustomContent.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CustomContentProperty =
            DependencyProperty.Register("CustomContent", typeof(object), typeof(CustomToggleButton), null);



        public CornerRadius CustomCornerRadius
        {
            get { return (CornerRadius)GetValue(CustomCornerRadiusProperty); }
            set { SetValue(CustomCornerRadiusProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CustomCornerRadius.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CustomCornerRadiusProperty =
            DependencyProperty.Register("CustomCornerRadius", typeof(CornerRadius), typeof(CustomToggleButton), null);



        public bool IsToggle
        {
            get { return (bool)GetValue(IsToggleProperty); }
            set { SetValue(IsToggleProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsToggle.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsToggleProperty =
            DependencyProperty.Register("IsToggle", typeof(bool), typeof(CustomToggleButton),
                                        new PropertyMetadata(false));


        static CustomToggleButton()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomToggleButton),
                                                     new FrameworkPropertyMetadata(typeof(CustomToggleButton)));
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            ToggleButton toggle = GetTemplateChild("btnToggle") as ToggleButton;
            if (toggle != null)
                toggle.Click += toggle_Click;

            GotoState(false);
        }

        private void toggle_Click(object sender, RoutedEventArgs e)
        {
            IsToggle = !IsToggle;
            GotoState(true);
        }

        private void GotoState(bool flag)
        {
            if (!IsToggle)
                VisualStateManager.GoToState(this, "Left", flag);
            else
                VisualStateManager.GoToState(this, "Right", flag);
        }
    }
}

MainWindow.xaml代码:

<Window x:Class="WpfApp_New3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:CustomControls="clr-namespace:CustomControls;assembly=CustomControls">
    <Grid>
        <CustomControls:CustomToggleButton x:Name="CustomToggle" BorderBrush="DarkOrange" BorderThickness="3" CustomCornerRadius="4">
            <CustomControls:CustomToggleButton.CustomContent>
                <StackPanel Margin="6">
                    <Button Margin="3" Padding="3" Content="Button One"></Button>
                    <Button Margin="3" Padding="3" Content="Button Two"></Button>
                    <Button Margin="3" Padding="3" Content="Button Three"></Button>
                    <Button Margin="3" Padding="3" Content="Button Four"></Button>
                </StackPanel>
            </CustomControls:CustomToggleButton.CustomContent>
        </CustomControls:CustomToggleButton>
    </Grid>
</Window>
原文地址:https://www.cnblogs.com/kelei12399/p/2684888.html