【问题标题】:How to add custom animations to a ContextMenuStrip?如何将自定义动画添加到 ContextMenuStrip?
【发布时间】:2021-10-12 22:22:20
【问题描述】:

有没有办法在打开 ContextMenuStrip 时创建动画,就像在这张图片中一样?

这个动画是 WhatsApp 右键单击​​的。我不知道该怎么做。

【问题讨论】:

    标签: c# vb.net winforms animation contextmenustrip


    【解决方案1】:

    您可以将 AnimateWindow 函数与 ToolStrips 一起使用,其中包括 ContextMenuStrip 类,因为它们都有句柄。
    例如,您可以重现处理控件的 MouseDown 事件的 OP 中显示的动画:

    Private Sub SomeControl_MouseDown(sender As Object, e As MouseEventArgs) Handles SomeControl.MouseDown
        If e.Button = MouseButtons.Right Then
            Dim ctrl = DirectCast(sender, Control)
            Dim cms = ContextMenuStrip1
            cms.Location = MousePosition
            AnimateWindow(cms.Handle, 250, AW_VER_POSITIVE Or AW_HOR_POSITIVE)
            cms.Show(ctrl, ctrl.PointToClient(MousePosition))
        End If
    End Sub
    

    这意味着您必须处理每个需要动画 ContextMenuStrip 的控件的 MouseDown 事件。如果只是一个,可能还可以接受。或者一堆可以共享相同 MouseDown 事件的控件。
    但是不能将动画应用到 Form 中的所有控件,例如将 ContextMenuStrip 设置为 Form 类。

    可能最好构建一个自定义控件,继承 ContextMenuStrip。
    然后,您可以添加一些允许配置 ContextMenuStrip 行为的属性,添加一些受支持的动画。

    我要添加一些:

    • OpenDownwards:在 OP 的示例图片中
    • OpenUpwards:相反
    • Expand:从中心展开菜单

    幻灯片(不言自明):

    • SlideToRight, SlideToLeft
    • SlideDownwards, SlideUpwards

    新的公共属性:

    • AnimationTime:动画的速度,单位毫秒
    • AnimationType:动画类型。组合框选择器
    • AnimateInDesigner:在表单设计器中为 ContextMenuStrip 设置动画。使它更容易配置它,因为动画是在设计时显示的。
      默认关闭,设置为True开启。您可能希望在配置控件后将其关闭。

    Imports System.ComponentModel
    Imports System.Runtime.InteropServices
    Imports System.Windows.Forms
    
    <DesignerCategory("code")>
    Public Class ContextMenuStripAnimated
        Inherits ContextMenuStrip
    
        ' Don't remove
        Public Sub New()
        End Sub
    
        Public Sub New(container As IContainer)
            Me.New()
            If container Is Nothing Then
                Throw New ArgumentNullException("container is null")
            End If
            container.Add(Me)
        End Sub
    
        Protected Overrides Sub OnOpening(e As CancelEventArgs)
            If Not DesignMode OrElse AnimateInDesigner Then
                Dim result = AnimateWindow(Handle, AnimationTime, AnimationType)
            End If
            MyBase.OnOpening(e)
        End Sub
    
        <DefaultValue(False)>
        Public Property AnimateInDesigner As Boolean = False
    
        <DefaultValue(AnimationMode.OpenDownwards)>
        Public Property AnimationType As AnimationMode = AnimationMode.OpenDownwards
    
        <DefaultValue(250)>
        Public Property AnimationTime As UInteger = 250
    
        <Flags()>
        Public Enum AnimationMode As UInteger
            OpenDownwards = AW_HOR_POSITIVE Or AW_VER_POSITIVE
            OpenUpwards = AW_HOR_NEGATIVE Or AW_VER_NEGATIVE
            Expand = AW_CENTER
            SlideToRight = AW_SLIDE Or AW_HOR_POSITIVE
            SlideToLeft = AW_SLIDE Or AW_HOR_NEGATIVE
            SlideDownwards = AW_SLIDE Or AW_VER_POSITIVE
            SlideUpwards = AW_SLIDE Or AW_VER_NEGATIVE
        End Enum
    
    #Region "NativeMethods"
    
        Private Const AW_HOR_POSITIVE As UInteger = &H1
        Private Const AW_HOR_NEGATIVE As UInteger = &H2
        Private Const AW_VER_POSITIVE As UInteger = &H4
        Private Const AW_VER_NEGATIVE As UInteger = &H8
        Private Const AW_CENTER As UInteger = &H10
        Private Const AW_HIDE As UInteger = &H10000
        Private Const AW_ACTIVATE As UInteger = &H20000
        Private Const AW_SLIDE As UInteger = &H40000
        Private Const AW_BLEND As UInteger = &H80000
    
        <DllImport("user32.dll", SetLastError:=true)>
        Private Shared Function AnimateWindow(hwnd As IntPtr, time As UInteger, flags As AnimationMode) As Boolean
        End Function
    
    #End Region
    End Class
    

    要将这个新控件添加到工具箱:

    • 在项目中添加一个类,命名为ContextMenuStripAnimated
    • 复制此处显示的所有代码,包括Imports 指令
    • 将其粘贴到新的 Class 文件中,替换其中的所有内容
    • 构建项目
    • 在 ToolBox 中找到新的 Control 并将其添加到 Form

    C#版本,以防万一

    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    [DesignerCategory("code")]
    public class ContextMenuStripAnimated : ContextMenuStrip
    {
        public ContextMenuStripAnimated() { }
    
        public ContextMenuStripAnimated(IContainer container) : this()
        {
            if (container == null) {
                throw new ArgumentNullException("container is null");
            }
            container.Add(this);
        }
    
        protected override void OnOpening(CancelEventArgs e)
        {
            if (!DesignMode || AnimateInDesigner) {
                var result = AnimateWindow(Handle, AnimationTime, AnimationType);
            }
            base.OnOpening(e);
        }
    
        [DefaultValue(false)]
        public bool AnimateInDesigner { get; set; } = false;
    
        [DefaultValue(250)]
        public uint AnimationTime { get; set; } = 250;
    
        [DefaultValue(AnimationMode.OpenDownwards)]
        public AnimationMode AnimationType { get; set; } = AnimationMode.OpenDownwards;
    
        [Flags]
        public enum AnimationMode : uint
        {
            OpenDownwards = AW_HOR_POSITIVE | AW_VER_POSITIVE,
            OpenUpwards = AW_HOR_NEGATIVE | AW_VER_NEGATIVE,
            Expand = AW_CENTER,
            SlideToRight = AW_SLIDE | AW_HOR_POSITIVE,
            SlideToLeft = AW_SLIDE | AW_HOR_NEGATIVE,
            SlideDownwards = AW_SLIDE | AW_VER_POSITIVE,
            SlideUpwards = AW_SLIDE | AW_VER_NEGATIVE
        }
    
        private const uint AW_HOR_POSITIVE = 0x1;
        private const uint AW_HOR_NEGATIVE = 0x2;
        private const uint AW_VER_POSITIVE = 0x4;
        private const uint AW_VER_NEGATIVE = 0x8;
        private const uint AW_CENTER = 0x10;
        private const uint AW_HIDE = 0x10000;
        private const uint AW_ACTIVATE = 0x20000;
        private const uint AW_SLIDE = 0x40000;
        private const uint AW_BLEND = 0x80000;
    
        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool AnimateWindow(IntPtr hwnd, uint time, AnimationMode flags);
    }
    

    【讨论】:

    • 哇,它就像魔法一样。它就像一个魅力,亲爱的吉米,谢谢你的帮助。最好的从不休息,你是最好的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-28
    • 2010-09-21
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    相关资源
    最近更新 更多