コンテキストメニューイベント、ContextualMenuManipulator と ContextualMenuPopulateEvent を使用して、ユーザーがラベルを右クリックするなど、特定のアクションを実行するときに一連の選択肢を表示できます。
コンテキストメニューを有効にするには、ビジュアル要素に ContextualMenuManipulator をアタッチします。このマニピュレーターは、右ボタンの Mouse Up イベントかメニューの Key Up イベントのいずれかの後にコンテキストメニューを表示します。ContextualMenuManipulator マニピュレーターは、ContextualMenuPopulateEvent に応答するコールバックも追加します。
以下のコード例では、ビジュアル要素にコンテキストメニューを追加します。メニューの項目は 1 つだけです。
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 イベントを送信します。イベントは伝播経路に沿って移動します。つまり、ビジュアルツリーのルートからイベントターゲットまで、次に、ビジュアルツリーをルートへと上昇します。伝播経路に沿って、ContextualMenuPopulateEvent イベントのコールバックを持つ要素は、コンテキストメニューの項目を追加、削除、または更新できます。
要素が ContextualMenuPopulateEvent を受け取ると、[DropdownMenu.InsertAction()](../ScriptReference/UIElements.DropdownMenu.InsertAction] または DropdownMenu.AppendAction(.html) を呼び出して、コンテキストメニューにメニュー項目を追加します。[`DropdownMenu.InsertAction()`](../ScriptReference/UIElements.DropdownMenu.InsertAction] と DropdownMenu.AppendAction(.html) は 2 つのコールバックをパラメーターとして受け取ります。最初のコールバックは、ユーザーがメニューの項目を選択したときに実行されます。2 番目のコールバックはメニューを表示する前に実行され、メニュー項目が有効かどうかをチェックします。
それらのコールバックは両方とも MenuAction をパラメーターとして受け取ります。MenuAction はメニュー項目を表し、以下のようなプロパティを持ちます。
MenuAction.userData には、AppendAction() または InsertAction() で使用されるユーザーデータへのリファレンスが含まれます。MenuAction.eventInfo には、コンテキストメニューを表示するイベントに関する情報が含まれます。イベントへ応答するアクションの MenuAction.eventInfo を使用してください。例えば、マウスの位置を使用して、選択したコンテキストメニュー項目に基づいて、オブジェクトを作成し配置することができます。以下の例では、2 つのラベルを持つカスタムの Editor ウィンドウを作成し、各ラベルにコンテキストメニューを追加します。この例は、コンテキストメニューを追加、削除、更新する方法を示しています。
任意のテンプレートで Unity プロジェクトを作成します。
Project ウィンドウに、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);
});
}
}
この例をライブで見るには、メニューから Window > UI Toolkit > ContextualMenuDemo を選択します。