如何将自定义动画添加到 ContextMenuStrip?
Posted
技术标签:
【中文标题】如何将自定义动画添加到 ContextMenuStrip?【英文标题】:How to add custom animations to a ContextMenuStrip? 【发布时间】:2021-10-12 22:22:20 【问题描述】:有没有办法在打开 ContextMenuStrip 时创建动画,就像在这张图片中一样?
这个动画是 WhatsApp 右键单击的。我不知道该怎么做。
【问题讨论】:
【参考方案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);
【讨论】:
哇,它就像魔法一样。它就像一个魅力,亲爱的吉米,谢谢你的帮助。最好的从不休息,你是最好的。以上是关于如何将自定义动画添加到 ContextMenuStrip?的主要内容,如果未能解决你的问题,请参考以下文章