WPF之可翻转面板

1,创建翻转面板的资源字典:FlippPanel.xaml。

XML 复制代码
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:ss="clr-namespace:无外观控件"
                    xmlns:local="clr-namespace:无外观控件.Themes">
    <Style TargetType="ss:FlipPanel">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ss:FlipPanel">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="auto"></RowDefinition>
                            <RowDefinition Height="auto"></RowDefinition>
                        </Grid.RowDefinitions>
                        <!--1,为给模板添加VisualStateManager元素,模板必须使用布局面板。布局面板包含控件的两个可视化对象和VisualStateManager元素(该元素不可见)-->
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup Name="ViewStates">
                                <VisualStateGroup.Transitions>
                                    <!--两个可视对象切换时间,以及伴随的ToggleButton切换动画-->
                                    <VisualTransition To="Normal" GeneratedDuration="00:00:01">
                                        <Storyboard >
                                            <DoubleAnimation  To="0" Storyboard.TargetName="PART_Rota" Storyboard.TargetProperty="Angle" ></DoubleAnimation>
                                        </Storyboard>
                                    </VisualTransition>
                                    <VisualTransition To="Flipped" GeneratedDuration="00:00:2">
                                        <Storyboard >
                                            <DoubleAnimation  To="180" Storyboard.TargetName="PART_Rota" Storyboard.TargetProperty="Angle" ></DoubleAnimation>
                                        </Storyboard>
                                    </VisualTransition>
                                </VisualStateGroup.Transitions>
                                <VisualState Name="Normal">
                                    <Storyboard >
                                        <DoubleAnimation To="0" Storyboard.TargetName="front" Storyboard.TargetProperty="Opacity" Duration="00:00:00"></DoubleAnimation>
                                        <!--ToggleButton旋转动画不能省,否则动画异常-->
                                        <DoubleAnimation  To="0"  Storyboard.TargetName="PART_Rota" Storyboard.TargetProperty="Angle"></DoubleAnimation>
                                    </Storyboard>
                                </VisualState>
                                <VisualState Name="Flipped">
                                    <Storyboard >
                                        <DoubleAnimation To="0" Storyboard.TargetName="back" Storyboard.TargetProperty="Opacity" Duration="00:00:00"></DoubleAnimation>
                                        <!--ToggleButton旋转动画不能省,否则动画异常-->
                                        <DoubleAnimation  To="180" Storyboard.TargetName="PART_Rota" Storyboard.TargetProperty="Angle" Duration="00:00:00" ></DoubleAnimation>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Border  x:Name="front" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="{TemplateBinding CornerRadius}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                            <ContentPresenter Content="{TemplateBinding FrontContent}"></ContentPresenter>
                        </Border>
                        <Border x:Name="back" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="{TemplateBinding CornerRadius}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                            <ContentPresenter Content="{TemplateBinding BackContent}"></ContentPresenter>
                        </Border>
                        <ToggleButton  Grid.Row="1" Height="40" Name="FlipButton" RenderTransformOrigin="0.5,0.5">
                            <ToggleButton.RenderTransform>
                                <RotateTransform x:Name="PART_Rota" ></RotateTransform>
                            </ToggleButton.RenderTransform>
                            <ToggleButton.Template>
                                <ControlTemplate TargetType="ToggleButton">
                                    <ToggleButton Grid.Column="1" Grid.Row="1"  Name="FlipButton">
                                        <ToggleButton.Template>
                                            <ControlTemplate TargetType="ToggleButton">
                                                <Rectangle >
                                                    <Rectangle.Fill>
                                                        <DrawingBrush Stretch="None">
                                                            <DrawingBrush.Drawing>
                                                                <GeometryDrawing Brush="White">
                                                                    <GeometryDrawing.Pen>
                                                                        <Pen Brush="Black" Thickness="2"></Pen>
                                                                    </GeometryDrawing.Pen>
                                                                    <GeometryDrawing.Geometry>
                                                                        <GeometryGroup>
                                                                            <EllipseGeometry RadiusX="15" RadiusY="15"></EllipseGeometry>
                                                                            <CombinedGeometry GeometryCombineMode="Intersect">
                                                                                <CombinedGeometry.Geometry1>
                                                                                    <EllipseGeometry RadiusX="7.5" RadiusY="7.5"></EllipseGeometry>
                                                                                </CombinedGeometry.Geometry1>
                                                                                <CombinedGeometry.Geometry2>
                                                                                    <PathGeometry   Figures="M-7.5,0 L0,-7.5 L7.5,-7.5 L0,0 L7.5,7.5 L0,7.5 Z">
                                                                                    </PathGeometry>
                                                                                </CombinedGeometry.Geometry2>
                                                                            </CombinedGeometry>
                                                                        </GeometryGroup>
                                                                    </GeometryDrawing.Geometry>
                                                                </GeometryDrawing>
                                                            </DrawingBrush.Drawing>
                                                        </DrawingBrush>
                                                    </Rectangle.Fill>
                                                </Rectangle>
                                            </ControlTemplate>
                                        </ToggleButton.Template>
                                    </ToggleButton>
                                </ControlTemplate>
                            </ToggleButton.Template>
                        </ToggleButton>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
  • VisualStateManager只能在布局面板下进行状态管理。

2,在generic.xaml中添加资源字典FlipPanel.xaml.

XML 复制代码
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  >
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="无外观控件;component/Themes/colorpicker.xaml">
        </ResourceDictionary>
        <ResourceDictionary Source="无外观控件;component/Themes/FlipPanel.xaml"></ResourceDictionary>
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

3,编写代码

cs 复制代码
 [TemplatePart(Name = "FlipButton", Type =typeof(ToggleButton))]//该特性只是进行提示,无其他意义,可舍去
    [TemplateVisualState(GroupName = "Normal", Name = "ViewStates")]//该特性提示存在可视化切换,无其他实际意义,可舍去
    [TemplateVisualState(GroupName = "Flipped", Name = "ViewStates")]
    public class FlipPanel : Control
    {
        public static readonly DependencyProperty CornerRadiusProperty;
        public static readonly DependencyProperty FrontContentProperty;
        public static readonly DependencyProperty BackContentProperty;
        public static readonly DependencyProperty IsFlippedProperty;
        static FlipPanel()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(FlipPanel), new FrameworkPropertyMetadata(typeof(FlipPanel)));
            CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(FlipPanel));
            FrontContentProperty = DependencyProperty.Register("FrontContent", typeof(object), typeof(FlipPanel));
            BackContentProperty = DependencyProperty.Register("BackContent", typeof(object), typeof(FlipPanel));
            IsFlippedProperty = DependencyProperty.Register("IsFlipped", typeof(bool), typeof(FlipPanel));
        }
        /// <summary>
        /// 设置控件边框倒角
        /// </summary>
        public CornerRadius CornerRadius
        {
            get
            {
                return (CornerRadius)this.GetValue(CornerRadiusProperty);
            }
            set
            {
                this.SetValue(CornerRadiusProperty, value);
            }
        }
        /// <summary>
        /// 前置内容
        /// </summary>
        public object FrontContent
        {
            get
            {
                return this.GetValue(FrontContentProperty);
            }
            set
            {
                this.SetValue(FrontContentProperty, value);
            }
        }
        /// <summary>
        /// 后置内容
        /// </summary>
        public object BackContent
        {
            get
            {
                return GetValue(BackContentProperty);
            }
            set
            {
                this.SetValue(BackContentProperty, value);
            }
        }
        /// <summary>
        /// 是否翻转
        /// </summary>
        public bool IsFlipped
        {
            get
            {
                return (bool)GetValue(IsFlippedProperty);
            }
            set
            {
                SetValue(IsFlippedProperty, value);
                ChangeVisualState(true);
            }
        }
        public override void OnApplyTemplate()
        {
            ToggleButton btn = GetTemplateChild("FlipButton") as ToggleButton;
            btn.Click += Btn_Click;
            ChangeVisualState(false);
            base.OnApplyTemplate();
           
        }

        private void Btn_Click(object sender, RoutedEventArgs e)
        {
            IsFlipped = !IsFlipped;
           
        }
        void ChangeVisualState(bool useTransition)
        {
            if (IsFlipped)
            {
                VisualStateManager.GoToState(this, "Flipped", useTransition);
            }
            else
            {
                VisualStateManager.GoToState(this, "Normal", useTransition);
            }

        }
    }

4,在UI上添加控件

XML 复制代码
<local:FlipPanel Grid.Row="1" IsFlipped="True">
            <local:FlipPanel.FrontContent>
                <StackPanel>
                    <Button Content="前1"></Button>
                    <Button Content="前2"></Button>
                    <Button Content="前3"></Button>
                    <Button Content="前3"></Button>
                    <Button Content="前4"></Button>
                </StackPanel>
            </local:FlipPanel.FrontContent>
            <local:FlipPanel.BackContent>
                <StackPanel>
                    <Button Content="后1"></Button>
                    
                </StackPanel>
            </local:FlipPanel.BackContent>
        </local:FlipPanel>

5,效果

6,Demo 链接

https://download.csdn.net/download/lingxiao16888/89253829?spm=1001.2014.3001.5501

相关推荐
布莱克60518 小时前
QtWidgets 与 QML:两大 UI 开发框架的全面对比
开发语言·c++·qt·ui·架构
n87651 天前
Playwright Java WEB UI 自动化实现框架与逻辑
java·前端·ui
Cx330❀2 天前
深入浅出 Qt 绘图机制:从 QPainter 到四大图像类解析
开发语言·qt·ui·性能优化·图形渲染
Oll Correct2 天前
Adobe illustrator 案例十一:城堡图标绘制
ui·adobe·illustrator
沫璃染墨3 天前
《Qt从零入门系列(十四):QThread多线程详解——从线程创建到客户端阻塞处理》
开发语言·c++·笔记·qt·ui·交互·线程
做个文艺程序员3 天前
MQ第12篇:AI原生消息架构演进:从MQ到事件驱动的全链路设计
架构·消息队列·wpf·事件驱动架构·ai-native·cqrs
特立独行的猫a4 天前
仓颉语言GUI开发实战:用仓颉写串口/网络二合一调试助手
网络·ui·gui·harmonyos·tauri·仓颉
wuyk5554 天前
PyQt6-第05讲-QtDesigner工作流与ui文件
python·ui·pyqt
Meta Luo4 天前
UI 自动化测试中的等待、超时和异步加载怎么处理
功能测试·测试工具·ui·回归·自动化