版本:Unity 6 (6000.0)
语言:English
过渡事件
IMGUI 事件

上下文菜单事件

使用上下文菜单事件,ContextualMenuManipulatorContextualMenuPopulateEvent,在用户执行某些操作时(例如,用户右键单击标签)显示一组选项。

启用上下文菜单

要启用上下文菜单,请将 ContextualMenuManipulator 附加到 视觉元素视觉树的一个节点,它实例化或派生自 C# VisualElement 类。您可以设置外观样式、定义行为,并将其显示在屏幕上作为 UI 的一部分。 更多信息
参见 术语表
。此操作器在右键鼠标松开事件或菜单键松开事件后显示上下文菜单。ContextualMenuManipulator 操作器还会添加一个回调,以响应 ContextualMenuPopulateEvent

以下代码示例将上下文菜单添加到视觉元素。该菜单只有一个项目。

void InstallManipulator(VisualElement element)
{
    ContextualMenuManipulator m = new ContextualMenuManipulator(MyDelegate);
    m.target = element;
}

void MyDelegate(ContextualMenuPopulateEvent event)
{
    // Modify event.menu
    event.menu.AppendAction("My action", DisplayProperties, DropdownMenu.MenuAction.AlwaysEnabled);
}

void DisplayProperties(DropdownMenu.MenuAction menuItem)
{
    // ...
}

传递给 ContextualMenuManipulator 构造函数的回调最后调用,以便子元素可以填充菜单。

操作器发送一个 ContextualMenuPopulateEvent 事件,该事件传播到目标元素层次结构。事件沿着传播路径移动:从 视觉树一个对象图,由轻量级节点组成,包含窗口或面板中的所有元素。它定义了使用 UI 工具包构建的每个 UI。
参见 术语表
的根到事件目标,然后返回到视觉树的根。沿着传播路径,具有 ContextualMenuPopulateEvent 事件回调的元素可以添加、删除或更新上下文菜单中的项目。

响应用户选择

当元素收到 ContextualMenuPopulateEvent 时,它调用 [DropdownMenu.InsertAction()](../ScriptReference/UIElements.DropdownMenu.InsertAction] 或 DropdownMenu.AppendAction(.html) 将菜单项添加到上下文菜单。[DropdownMenu.InsertAction()](../ScriptReference/UIElements.DropdownMenu.InsertAction] 和 DropdownMenu.AppendAction(.html) 将两个回调作为参数。当用户选择菜单中的项目时,第一个回调执行。第二个回调在显示菜单之前执行,并检查菜单项是否启用。

这两个回调都接收 MenuAction 作为参数。MenuAction 代表菜单项,并具有以下属性

  • MenuAction.userData 包含与 AppendAction()InsertAction() 一起使用的用户数据的引用。
  • MenuAction.eventInfo 包含有关显示上下文菜单的事件的信息。在响应事件的操作中使用 MenuAction.eventInfo。例如,您可以使用鼠标位置根据选定的上下文菜单项创建和放置对象。

示例

以下示例创建一个自定义编辑器窗口,其中包含两个标签,并为每个标签添加上下文菜单。该示例演示如何添加、删除和更新上下文菜单。

  1. 使用任何模板创建一个 Unity 项目。

  2. 项目窗口显示 Assets 文件夹内容的窗口(项目选项卡) 更多信息
    参见 术语表
    中,创建一个名为 Editor 的文件夹。

  3. Editor 窗口中,创建一个名为 ContextualMenuDemo 的 C# 脚本,并将其内容替换为以下内容

    using UnityEditor;
    using UnityEngine;
    using UnityEngine.UIElements;
    
    public class ContextualMenuDemo : EditorWindow
    {
        [MenuItem("Window/ContextualMenuDemo")]
        public static void ShowExample()
        {
            ContextualMenuDemo wnd = GetWindow<ContextualMenuDemo>();
            wnd.titleContent = new GUIContent("ContextualMenuDemo");
        }
    
        public void CreateGUI()
        {
            VisualElement root = rootVisualElement;
            VisualElement label = new Label("Right click me!");
            root.Add(label);
    
            AddANewContextMenu(label);
            InsertIntoAnExistingMenu(label);
    
            VisualElement second = new Label("Click me also!");
            root.Add(second);
    
            AddANewContextMenu(second);
            InsertIntoAnExistingMenu(second);
    
            // Override the default behavior by clearing the menu.
            ReplaceContextMenu(second);
        }
    
        void AddANewContextMenu(VisualElement element)
        {
            // The manipulator handles the right click and sends a ContextualMenuPopulateEvent to the target element.
            // The callback argument passed to the constructor is automatically registered on the target element.
            element.AddManipulator(new ContextualMenuManipulator((evt) =>
            {
                evt.menu.AppendAction("First menu item", (x) => Debug.Log("First!!!!"), DropdownMenuAction.AlwaysEnabled);
                evt.menu.AppendAction("Second menu item", (x) => Debug.Log("Second!!!!"), DropdownMenuAction.AlwaysEnabled);
            }));
        }
    
        void InsertIntoAnExistingMenu(VisualElement element)
        {
            element.RegisterCallback<ContextualMenuPopulateEvent>((evt) =>
            {
                evt.menu.AppendSeparator();
                evt.menu.AppendAction("Another action", (x) => Debug.Log("Another Action!!!!"), DropdownMenuAction.AlwaysEnabled);
            });
        }
    
        void ReplaceContextMenu(VisualElement element)
        {
            element.RegisterCallback<ContextualMenuPopulateEvent>((evt) =>
            {
                evt.menu.ClearItems();
                evt.menu.AppendAction("The only action", (x) => Debug.Log("The only action!"), DropdownMenuAction.AlwaysEnabled);
            });
        }
    
    }
    
  4. 要查看实时示例,请从菜单中选择窗口 > UI 工具包 > ContextualMenuDemo

其他资源

过渡事件
IMGUI 事件