使用上下文菜单事件,ContextualMenuManipulator
和 ContextualMenuPopulateEvent
,在用户执行某些操作时(例如,用户右键单击标签)显示一组选项。
要启用上下文菜单,请将 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
。例如,您可以使用鼠标位置根据选定的上下文菜单项创建和放置对象。以下示例创建一个自定义编辑器窗口,其中包含两个标签,并为每个标签添加上下文菜单。该示例演示如何添加、删除和更新上下文菜单。
使用任何模板创建一个 Unity 项目。
在 项目窗口显示 Assets
文件夹内容的窗口(项目选项卡) 更多信息
参见 术语表中,创建一个名为 Editor
的文件夹。
在 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);
});
}
}
要查看实时示例,请从菜单中选择窗口 > UI 工具包 > ContextualMenuDemo。