Xamarin.Mac의 메뉴

이 문서에서는 Xamarin.Mac 애플리케이션의 메뉴 작업에 대해 설명합니다. Xcode 및 Interface Builder에서 메뉴 및 메뉴 항목을 만들고 유지 관리하고 프로그래밍 방식으로 작업하는 방법에 대해 설명합니다.

Xamarin.Mac 애플리케이션에서 C# 및 .NET으로 작업할 때 개발자가 작업하는 것과 Xcode에서 수행하는 것과 동일한 Cocoa 메뉴에 Objective-C 액세스할 수 있습니다. Xamarin.Mac은 Xcode와 직접 통합되므로 Xcode의 인터페이스 작성기를 사용하여 메뉴 모음, 메뉴 및 메뉴 항목을 만들고 유지 관리할 수 있습니다(또는 필요에 따라 C# 코드에서 직접 만들 수 있음).

메뉴는 Mac 애플리케이션의 사용자 환경의 필수적인 부분이며 일반적으로 사용자 인터페이스의 다양한 부분에 표시됩니다.

  • 애플리케이션의 메뉴 모음 - 모든 Mac 애플리케이션에 대해 화면 맨 위에 표시되는 주 메뉴입니다.
  • 상황에 맞는 메뉴 - 사용자가 창에서 항목을 마우스 오른쪽 단추로 클릭하거나 컨트롤을 클릭할 때 나타납니다.
  • 상태 표시줄 - 화면 위쪽(메뉴 모음 클록의 왼쪽)에 표시되고 항목이 추가되면 왼쪽으로 증가하는 애플리케이션 메뉴 모음의 맨 오른쪽에 있는 영역입니다.
  • Dock 메뉴 - 사용자가 응용 프로그램의 아이콘을 마우스 오른쪽 단추로 클릭하거나 컨트롤을 클릭하거나 사용자가 아이콘을 마우스 왼쪽 단추로 클릭하고 마우스 단추를 누를 때 나타나는 도크의 각 애플리케이션에 대한 메뉴입니다.
  • 팝업 단추 및 풀다운 목록 - 팝업 단추는 선택한 항목을 표시하고 사용자가 클릭할 때 선택할 수 있는 옵션 목록을 표시합니다. 풀다운 목록은 일반적으로 현재 작업의 컨텍스트와 관련된 명령을 선택하는 데 사용되는 팝업 단추의 유형입니다. 둘 다 창의 아무 곳에나 나타날 수 있습니다.

An example menu

이 문서에서는 Xamarin.Mac 애플리케이션에서 Cocoa 메뉴 모음, 메뉴 및 메뉴 항목을 사용하는 기본 사항을 설명합니다. 이 문서에서 사용할 주요 개념과 기술을 다루므로 Hello, Mac 문서, 특히 Xcode 및 인터페이스 작성기 소개 및 콘센트 및 작업 섹션을 통해 작업하는 것이 좋습니다.

Xamarin.Mac Internals 문서의 섹션에 대한 C# 클래스/메서드 Objective-C노출을 살펴보고, C# 클래스 Objective-C 를 개체 및 UI 요소에 연결하는 데 사용되는 특성 및 Export 특성을 설명 Register 합니다.

애플리케이션의 메뉴 모음

모든 창에 자체 메뉴 모음을 연결할 수 있는 Windows OS에서 실행되는 애플리케이션과 달리 macOS에서 실행되는 모든 애플리케이션에는 해당 애플리케이션의 모든 창에 사용되는 화면 위쪽을 따라 실행되는 단일 메뉴 모음이 있습니다.

A menu bar

이 메뉴 모음의 항목은 지정된 순간에 애플리케이션 및 해당 사용자 인터페이스의 현재 컨텍스트 또는 상태에 따라 활성화되거나 비활성화됩니다. 예를 들어 사용자가 텍스트 필드를 선택하면 편집 메뉴의 항목(예: 복사잘라내기)이 활성화됩니다.

Apple 및 기본적으로 모든 macOS 애플리케이션에는 애플리케이션의 메뉴 모음에 표시되는 표준 메뉴 및 메뉴 항목 집합이 있습니다.

  • Apple 메뉴 - 이 메뉴는 실행 중인 애플리케이션에 관계없이 항상 사용자가 사용할 수 있는 시스템 전체 항목에 대한 액세스를 제공합니다. 개발자는 이러한 항목을 수정할 수 없습니다.
  • 앱 메뉴 - 이 메뉴는 애플리케이션의 이름을 굵게 표시하고 사용자가 현재 실행 중인 애플리케이션을 식별하는 데 도움이 됩니다. 응용 프로그램 종료와 같이 지정된 문서나 프로세스가 아닌 전체 애플리케이션에 적용되는 항목이 포함되어 있습니다.
  • 파일 메뉴 - 애플리케이션이 작동하는 문서를 만들거나 열거나 저장하는 데 사용되는 항목입니다. 애플리케이션이 문서 기반이 아닌 경우 이 메뉴의 이름을 바꾸거나 제거할 수 있습니다.
  • 편집 메뉴 - 애플리케이션의 사용자 인터페이스에서 요소를 편집하거나 수정하는 데 사용되는 잘라내기, 복사붙여넣기와 같은 명령을 저장합니다.
  • 서식 메뉴 - 애플리케이션이 텍스트와 함께 작동하는 경우 이 메뉴에는 해당 텍스트의 서식을 조정하는 명령이 있습니다.
  • 보기 메뉴 - 애플리케이션의 사용자 인터페이스에서 콘텐츠가 표시되는 방식(보기)에 영향을 주는 명령을 보유합니다.
  • 애플리케이션별 메뉴 - 애플리케이션과 관련된 모든 메뉴입니다(예: 웹 브라우저의 책갈피 메뉴). 표시줄의 보기 메뉴 사이에 표시되어야 합니다.
  • 창 메뉴 - 애플리케이션의 창 작업 명령과 현재 열려 있는 창 목록이 포함되어 있습니다.
  • 도움말 메뉴 - 애플리케이션에서 화면 도움말을 제공하는 경우 도움말 메뉴는 바에서 가장 적합한 메뉴여야 합니다.

애플리케이션 메뉴 모음과 표준 메뉴 및 메뉴 항목에 대한 자세한 내용은 Apple의 휴먼 인터페이스 지침을 참조하세요.

기본 애플리케이션 메뉴 모음

새 Xamarin.Mac 프로젝트를 만들 때마다 macOS 애플리케이션에서 일반적으로 사용할 수 있는 일반적인 항목이 있는 표준 기본 애플리케이션 메뉴 모음이 자동으로 제공됩니다(위 섹션에 설명된 대로). 애플리케이션의 기본 메뉴 모음은 Solution Pad의 프로젝트 아래에 있는 Main.storyboard 파일(앱의 나머지 UI와 함께)에 정의됩니다.

Select the main storyboard

Main.storyboard 파일을 두 번 클릭하여 Xcode의 인터페이스 작성기에서 편집할 수 있도록 열면 메뉴 편집기 인터페이스가 표시됩니다.

Editing the UI in Xcode, showing the Main dot storyboard.

여기에서 파일 메뉴에서 열기 메뉴 항목과 같은 항목을 클릭하고 특성 검사기에서 해당 속성을 편집하거나 조정할 수 있습니다.

Editing a menu's attributes

이 문서의 뒷부분에서 메뉴와 항목을 추가, 편집 및 삭제합니다. 지금은 기본적으로 사용할 수 있는 메뉴 및 메뉴 항목과 미리 정의된 콘센트 및 작업 집합을 통해 코드에 자동으로 노출되는 방법을 확인하려고 합니다(자세한 내용은 콘센트 및 작업 설명서 참조).

예를 들어 열기 메뉴 항목에 대한 연결 검사기를 클릭하면 작업에 자동으로 연결되는 것을 openDocument: 볼 수 있습니다.

Viewing the attached action

인터페이스 계층 구조에서 첫 번째 응답자를 선택하고 연결 검사기에서 아래로 스크롤하면 열기 메뉴 항목이 연결된 작업의 정의 openDocument: 가 표시됩니다(컨트롤에 자동으로 연결되지 않고 애플리케이션에 대한 몇 가지 다른 기본 작업과 함께).

Viewing all attached actions

이 기능이 왜 중요할까요? 다음 섹션에서는 이러한 자동 정의 작업이 다른 Cocoa 사용자 인터페이스 요소와 함께 작동하여 메뉴 항목을 자동으로 사용하거나 사용하지 않도록 설정하고 항목에 대한 기본 제공 기능을 제공하는 방법을 알아봅니다.

나중에 이러한 기본 제공 작업을 사용하여 코드에서 항목을 사용하거나 사용하지 않도록 설정하고 항목을 선택할 때 고유한 기능을 제공합니다.

기본 제공 메뉴 기능

UI 항목 또는 코드를 추가하기 전에 새로 만든 Xamarin.Mac 애플리케이션을 실행한 경우 메뉴의 종료 항목과 같이 일부 항목이 자동으로 유선으로 연결되고 자동으로 활성화됩니다(전체 기능이 자동으로 기본 제공됨).

An enabled menu item

잘라내기, 복사붙여넣기와 같은 다른 메뉴 항목은 다음과 같은 것이 아닙니다.

Disabled menu items

애플리케이션을 중지하고 Solution Pad에서 Main.storyboard 파일을 두 번 클릭하여 Xcode의 인터페이스 작성기에서 편집할 수 있도록 엽니다. 다음으로, 라이브러리텍스트 뷰인터페이스 편집기의 창 보기 컨트롤러로 끕니다.

Selecting a Text View from the Library

제약 조건 편집기에서 텍스트 보기를 창의 가장자리에 고정하고 편집기 맨 위에 있는 4개의 빨간색 I-빔을 모두 클릭하고 4개의 제약 조건 추가 단추를 클릭하여 창이 확장되고 축소되는 위치를 설정해 보겠습니다.

Editing the contraints

변경 내용을 사용자 인터페이스 디자인에 저장하고 Mac용 Visual Studio 다시 전환하여 변경 내용을 Xamarin.Mac 프로젝트와 동기화합니다. 이제 애플리케이션을 시작하고, 텍스트 보기에 텍스트를 입력하고, 선택하고, 편집 메뉴를 엽니다.

The menu items are automatically enabled/disabled

코드 한 줄을 작성하지 않고 도 잘라내기, 복사붙여넣기 항목이 자동으로 활성화되고 완벽하게 작동하는 방식을 확인합니다.

무슨 일이 일어나고 있는 건가요? 기본 메뉴 항목(위에서 설명한 대로)에 연결된 기본 제공 미리 정의 작업을 기억합니다. macOS의 일부인 대부분의 Cocoa 사용자 인터페이스 요소는 특정 작업(예: copy:)에 대한 후크를 기본으로 제공합니다. 따라서 창, 활성 및 선택 항목에 추가되면 해당 작업에 연결된 해당 메뉴 항목 또는 항목이 자동으로 활성화됩니다. 사용자가 해당 메뉴 항목을 선택하면 개발자 개입 없이 UI 요소에 기본 제공되는 기능이 호출되고 실행됩니다.

메뉴 및 항목 사용 및 사용 안 함

기본적으로 사용자 이벤트가 발생할 NSMenu 때마다 애플리케이션의 컨텍스트에 따라 표시되는 각 메뉴 및 메뉴 항목을 자동으로 사용하거나 사용하지 않도록 설정합니다. 항목을 사용하거나 사용하지 않도록 설정하는 세 가지 방법이 있습니다.

  • 자동 메뉴 사용 - 항목이 유선으로 연결된 작업에 응답하는 적절한 개체를 찾을 수 있는 경우 NSMenu 메뉴 항목이 활성화됩니다. 예를 들어 작업의 기본 제공 후크가 있는 위의 텍스트 뷰입니다 copy: .
  • 사용자 지정 작업 및 validateMenuItem: - 창 또는 보기 컨트롤러 사용자 지정 작업에 바인딩된 모든 메뉴 항목의 validateMenuItem: 경우 작업을 추가하고 메뉴 항목을 수동으로 사용하거나 사용하지 않도록 설정할 수 있습니다.
  • 수동 메뉴 사용 - 메뉴에서 각 항목을 개별적으로 사용하거나 사용하지 않도록 설정하도록 각 NSMenuItem 항목의 속성을 수동으로 설정합니다Enabled.

시스템을 선택하려면 .의 AutoEnablesItemsNSMenu속성을 설정합니다. true 는 자동(기본 동작)이며 false 수동입니다.

중요

수동 메뉴를 사용하도록 설정하면 AppKit 클래스 NSTextView에서 제어하는 메뉴 항목도 자동으로 업데이트되지 않습니다. 코드에서 직접 모든 항목을 사용하도록 설정하고 사용하지 않도록 설정해야 합니다.

validateMenuItem 사용

위에서 설명한 것처럼 창 또는 뷰 컨트롤러 사용자 지정 작업에 바인딩된 모든 메뉴 항목에 대해 작업을 추가하고 validateMenuItem: 메뉴 항목을 수동으로 사용하거나 사용하지 않도록 설정할 수 있습니다.

다음 예제 Tag 에서는 속성에서 선택한 텍스트의 상태에 따라 작업에 의해 validateMenuItem: 사용/사용 안 함으로 설정 될 메뉴 항목의 형식을 결정 하는 NSTextView데 사용 됩니다. 각 Tag 메뉴 항목에 대해 Interface Builder에서 속성이 설정되었습니다.

Setting the Tag property

그리고 뷰 컨트롤러에 추가된 다음 코드는 다음과 같습니다.

[Action("validateMenuItem:")]
public bool ValidateMenuItem (NSMenuItem item) {

    // Take action based on the menu item type
    // (As specified in its Tag)
    switch (item.Tag) {
    case 1:
        // Wrap menu items should only be available if
        // a range of text is selected
        return (TextEditor.SelectedRange.Length > 0);
    case 2:
        // Quote menu items should only be available if
        // a range is NOT selected.
        return (TextEditor.SelectedRange.Length == 0);
    }

    return true;
}

이 코드가 실행되고 텍스트가 선택되지 NSTextView않으면 두 개의 줄 바꿈 메뉴 항목이 비활성화됩니다(보기 컨트롤러의 작업에 연결되더라도).

Showing disabled items

텍스트 섹션을 선택하고 메뉴를 다시 열면 두 개의 줄 바꿈 메뉴 항목을 사용할 수 있습니다.

Showing enabled items

코드의 메뉴 항목 사용 및 응답

위에서 설명한 것처럼 특정 Cocoa 사용자 인터페이스 요소를 UI 디자인(예: 텍스트 필드)에 추가하는 것만으로도 코드를 작성하지 않고도 몇 가지 기본 메뉴 항목이 사용하도록 설정되고 자동으로 작동합니다. 다음으로 Xamarin.Mac 프로젝트에 자체 C# 코드를 추가하여 메뉴 항목을 사용하도록 설정하고 사용자가 선택할 때 기능을 제공하는 방법을 살펴보겠습니다.

예를 들어 사용자가 파일 메뉴에서 열기 항목을 사용하여 폴더를 선택할 수 있도록 하겠습니다. 이 함수는 애플리케이션 전체 함수가 되고 제공 창 또는 UI 요소로 제한되지 않기를 원하기 때문에 이를 처리하는 코드를 애플리케이션 대리자에게 추가하겠습니다.

Solution Pad에서 파일을 두 번 클릭하여 AppDelegate.CS 편집용으로 엽니다.

Selecting the app delegate

DidFinishLaunching 메서드 아래에 다음 코드를 추가합니다.

[Export ("openDocument:")]
void OpenDialog (NSObject sender)
{
    var dlg = NSOpenPanel.OpenPanel;
    dlg.CanChooseFiles = false;
    dlg.CanChooseDirectories = true;

    if (dlg.RunModal () == 1) {
        var alert = new NSAlert () {
            AlertStyle = NSAlertStyle.Informational,
            InformativeText = "At this point we should do something with the folder that the user just selected in the Open File Dialog box...",
            MessageText = "Folder Selected"
        };
        alert.RunModal ();
    }
}

이제 애플리케이션을 실행하고 파일 메뉴를 엽니다.

The File menu

이제 열기 메뉴 항목을 사용할 수 있습니다. 이 옵션을 선택하면 열려 있는 대화 상자가 표시됩니다.

An open dialog

열기 단추를 클릭하면 경고 메시지가 표시됩니다.

An example dialog message

여기서 핵심 줄은 [Export ("openDocument:")]AppDelegate에 작업에 응답 openDocument: 하는 메서드 void OpenDialog (NSObject sender) 가 있음을 알려줍니다NSMenu. 위에서 기억해 두면 인터페이스 작성기에서 기본적으로 열기 메뉴 항목이 이 작업에 자동으로 연결됩니다.

Viewing the attached actions

다음으로, 고유한 메뉴, 메뉴 항목 및 작업을 만들고 코드에서 응답하는 방법을 살펴보겠습니다.

최근 메뉴 열기 작업

기본적으로 파일 메뉴에는 사용자가 앱에서 연 마지막 여러 파일을 추적하는 최근 항목 열기가 포함되어 있습니다. 기반 Xamarin.Mac 앱을 만드는 NSDocument 경우 이 메뉴가 자동으로 처리됩니다. 다른 유형의 Xamarin.Mac 앱의 경우 이 메뉴 항목을 수동으로 관리하고 응답해야 합니다.

최근에 사용한 항목 열기 메뉴를 수동으로 처리하려면 먼저 다음을 사용하여 새 파일을 열거나 저장했음을 알려야 합니다.

// Add document to the Open Recent menu
NSDocumentController.SharedDocumentController.NoteNewRecentDocumentURL(url);

앱에서 사용하지 NSDocuments않더라도 파일의 위치가 있는 NSUrl 파일을 메서드로 전송하여 [최근 항목 열기] 메뉴를 유지 관리하는 데 NoteNewRecentDocumentURLSharedDocumentController계속 사용합니다NSDocumentController.

다음으로 앱 대리자의 메서드를 OpenFile 재정의하여 사용자가 [최근에 사용한 항목 열기] 메뉴에서 선택한 파일을 열어야 합니다. 예를 들어:

public override bool OpenFile (NSApplication sender, string filename)
{
    // Trap all errors
    try {
        filename = filename.Replace (" ", "%20");
        var url = new NSUrl ("file://"+filename);
        return OpenFile(url);
    } catch {
        return false;
    }
}

파일을 열 수 있으면 반환 true 하고, 그렇지 않으면 파일을 false 열 수 없다는 기본 제공 경고가 사용자에게 표시됩니다.

[최근에 사용한 항목 열기] 메뉴에서 반환된 파일 이름과 경로에 공백이 포함될 수 있으므로 이 문자를 만들기 NSUrl 전에 이 문자를 제대로 이스케이프해야 합니다. 그렇지 않으면 오류가 발생합니다. 다음 코드를 사용하여 이 작업을 수행합니다.

filename = filename.Replace (" ", "%20");

마지막으로 파일을 가리키는 파일을 만들고 NSUrl 앱 대리자의 도우미 메서드를 사용하여 새 창을 열고 파일을 로드합니다.

var url = new NSUrl ("file://"+filename);
return OpenFile(url);

모든 항목을 함께 끌어오려면 AppDelegate.cs 파일의 예제 구현을 살펴보겠습니다.

using AppKit;
using Foundation;
using System.IO;
using System;

namespace MacHyperlink
{
    [Register ("AppDelegate")]
    public class AppDelegate : NSApplicationDelegate
    {
        #region Computed Properties
        public int NewWindowNumber { get; set;} = -1;
        #endregion

        #region Constructors
        public AppDelegate ()
        {
        }
        #endregion

        #region Override Methods
        public override void DidFinishLaunching (NSNotification notification)
        {
            // Insert code here to initialize your application
        }

        public override void WillTerminate (NSNotification notification)
        {
            // Insert code here to tear down your application
        }

        public override bool OpenFile (NSApplication sender, string filename)
        {
            // Trap all errors
            try {
                filename = filename.Replace (" ", "%20");
                var url = new NSUrl ("file://"+filename);
                return OpenFile(url);
            } catch {
                return false;
            }
        }
        #endregion

        #region Private Methods
        private bool OpenFile(NSUrl url) {
            var good = false;

            // Trap all errors
            try {
                var path = url.Path;

                // Is the file already open?
                for(int n=0; n<NSApplication.SharedApplication.Windows.Length; ++n) {
                    var content = NSApplication.SharedApplication.Windows[n].ContentViewController as ViewController;
                    if (content != null && path == content.FilePath) {
                        // Bring window to front
                        NSApplication.SharedApplication.Windows[n].MakeKeyAndOrderFront(this);
                        return true;
                    }
                }

                // Get new window
                var storyboard = NSStoryboard.FromName ("Main", null);
                var controller = storyboard.InstantiateControllerWithIdentifier ("MainWindow") as NSWindowController;

                // Display
                controller.ShowWindow(this);

                // Load the text into the window
                var viewController = controller.Window.ContentViewController as ViewController;
                viewController.Text = File.ReadAllText(path);
                viewController.SetLanguageFromPath(path);
                viewController.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
                viewController.View.Window.RepresentedUrl = url;

                // Add document to the Open Recent menu
                NSDocumentController.SharedDocumentController.NoteNewRecentDocumentURL(url);

                // Make as successful
                good = true;
            } catch {
                // Mark as bad file on error
                good = false;
            }

            // Return results
            return good;
        }
        #endregion

        #region actions
        [Export ("openDocument:")]
        void OpenDialog (NSObject sender)
        {
            var dlg = NSOpenPanel.OpenPanel;
            dlg.CanChooseFiles = true;
            dlg.CanChooseDirectories = false;

            if (dlg.RunModal () == 1) {
                // Nab the first file
                var url = dlg.Urls [0];

                if (url != null) {
                    // Open the document in a new window
                    OpenFile (url);
                }
            }
        }
        #endregion
    }
}

앱의 요구 사항에 따라 사용자가 동일한 파일을 두 개 이상의 창에서 동시에 열지 않도록 할 수 있습니다. 예제 앱에서 사용자가 이미 열려 있는 파일( 최근 항목 또는 열기 메뉴 항목 중 하나)을 선택하면 파일이 포함된 창이 맨 앞으로 이동합니다.

이를 위해 도우미 메서드에서 다음 코드를 사용했습니다.

var path = url.Path;

// Is the file already open?
for(int n=0; n<NSApplication.SharedApplication.Windows.Length; ++n) {
    var content = NSApplication.SharedApplication.Windows[n].ContentViewController as ViewController;
    if (content != null && path == content.FilePath) {
        // Bring window to front
        NSApplication.SharedApplication.Windows[n].MakeKeyAndOrderFront(this);
        return true;
    }
}

속성에 파일 경로를 저장하도록 클래스를 디자인 ViewController 했습니다 Path . 다음으로, 앱에서 현재 열려 있는 모든 창을 반복합니다. 파일이 이미 창 중 하나에서 열려 있는 경우 다음을 사용하여 다른 모든 창의 맨 앞으로 가져옵니다.

NSApplication.SharedApplication.Windows[n].MakeKeyAndOrderFront(this);

일치하는 항목이 없으면 파일이 로드된 새 창이 열리고 파일은 [최근 항목 열기 ] 메뉴에 표시됩니다.

// Get new window
var storyboard = NSStoryboard.FromName ("Main", null);
var controller = storyboard.InstantiateControllerWithIdentifier ("MainWindow") as NSWindowController;

// Display
controller.ShowWindow(this);

// Load the text into the window
var viewController = controller.Window.ContentViewController as ViewController;
viewController.Text = File.ReadAllText(path);
viewController.SetLanguageFromPath(path);
viewController.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
viewController.View.Window.RepresentedUrl = url;

// Add document to the Open Recent menu
NSDocumentController.SharedDocumentController.NoteNewRecentDocumentURL(url);

사용자 지정 창 작업

표준 메뉴 항목에 미리 연결된 기본 제공 첫 번째 응답자 작업과 마찬가지로 새 사용자 지정 작업을 만들고 Interface Builder의 메뉴 항목에 연결할 수 있습니다.

먼저 앱의 창 컨트롤러 중 하나에서 사용자 지정 작업을 정의합니다. 예를 들어:

[Action("defineKeyword:")]
public void defineKeyword (NSObject sender) {
    // Preform some action when the menu is selected
    Console.WriteLine ("Request to define keyword");
}

다음으로 Solution Pad 에서 앱의 스토리보드 파일을 두 번 클릭하여 Xcode의 인터페이스 작성기에서 편집할 수 있도록 엽니다. 애플리케이션 장면 아래에서 첫 번째 응답자를 선택한 다음, 특성 검사기로 전환합니다.

The Attributes Inspector

+특성 검사기 아래쪽에 있는 단추를 클릭하여 새 사용자 지정 작업을 추가합니다.

Adding a new action

창 컨트롤러에서 만든 사용자 지정 작업과 동일한 이름을 지정합니다.

Editing the action name

컨트롤을 클릭하고 메뉴 항목에서 애플리케이션 장면 아래의 첫 번째 응답자로 끌어옵니다. 팝업 목록에서 방금 만든 새 작업을 선택합니다(defineKeyword: 이 예제에서는).

Attaching an action

변경 내용을 스토리보드에 저장하고 Mac용 Visual Studio 돌아가 변경 내용을 동기화합니다. 앱을 실행하면 사용자 지정 작업을 연결한 메뉴 항목이 자동으로 활성화/비활성화되고(작업이 열려 있는 창에 따라) 메뉴 항목을 선택하면 작업이 실행됩니다.

Testing the new action

메뉴 추가, 편집 및 삭제

이전 섹션에서 보았듯이 Xamarin.Mac 애플리케이션에는 특정 UI 컨트롤이 자동으로 활성화되고 응답하는 미리 설정된 수의 기본 메뉴 및 메뉴 항목이 함께 제공됩니다. 또한 이러한 기본 항목을 사용하도록 설정하고 응답하는 코드를 애플리케이션에 추가하는 방법도 알아보았습니다.

이 섹션에서는 필요하지 않은 메뉴 항목을 제거하고, 메뉴를 다시 구성하고, 새 메뉴, 메뉴 항목 및 작업을 추가하는 것을 살펴봅니다.

Solution Pad에서 Main.storyboard 파일을 두 번 클릭하여 편집용으로 엽니다.

Double-clicking the storyboard file to edit the UI in Xcode.

특정 Xamarin.Mac 애플리케이션의 경우 기본 보기 메뉴를 사용하지 않으므로 제거하겠습니다. 인터페이스 계층 구조에서 주 메뉴 모음의 일부인 보기 메뉴 항목을 선택합니다.

Selecting the View menu item

삭제 또는 백스페이스를 눌러 메뉴를 삭제합니다. 다음으로 서식 메뉴의 모든 항목을 사용하지 않을 것이며 하위 메뉴 아래에서 사용할 항목을 이동하려고 합니다. 인터페이스 계층 구조에서 다음 메뉴 항목을 선택합니다.

Highlighting multiple items

현재 있는 하위 메뉴에서 상위 메뉴 아래의 항목을 끕니다.

Dragging menu items to the parent menu

이제 메뉴가 다음과 같이 표시됩니다.

The items in the new location

그런 다음 서식 메뉴 아래에서 텍스트 하위 메뉴를 끌어서 서식 메뉴 사이의 주 메뉴 모음에 배치해 보겠습니다.

The Text menu

서식 메뉴로 돌아가서 글꼴 하위 메뉴 항목을 삭제해 보겠습니다. 다음으로 서식 메뉴를 선택하고 이름을 "글꼴"로 바꿉니다.

The Font menu

다음으로, 선택 시 텍스트 보기의 텍스트에 자동으로 추가되는 미리 정의 구의 사용자 지정 메뉴를 만들어 보겠습니다. 라이브러리 검사기 아래쪽의 검색 상자에 "menu"를 입력합니다. 이렇게 하면 모든 메뉴 UI 요소를 더 쉽게 찾고 작업할 수 있습니다.

The Library Inspector

이제 다음을 수행하여 메뉴를 만들어 보겠습니다.

  1. 라이브러리 검사기의 메뉴 항목을텍스트 메뉴 사이의 메뉴 모음으로 끌어다 놓습니다.

    Selecting a new menu item in the Library

  2. 항목 이름을 "Phrases"로 바꿉니다.

    Setting the menu name

  3. 그런 다음 라이브러리 검사기에서 메뉴를 끌어옵니다.

    Selecting a menu from the Library

  4. 방금 만든 새 메뉴 항목에서 메뉴를 삭제하고 이름을 "구"로 변경합니다.

    Editing the menu name

  5. 이제 세 가지 기본 메뉴 항목 "주소", "날짜" 및 "인사말"의 이름을 바꾸겠습니다.

    The Phrases menu

  6. 라이브러리 검사기에서 메뉴 항목을 끌어서 "서명"이라고 호출하여 네 번째 메뉴 항목을 추가해 보겠습니다.

    Editing the menu item name

  7. 변경 내용을 메뉴 모음에 저장합니다.

이제 새 메뉴 항목이 C# 코드에 노출되도록 사용자 지정 작업 집합을 만들어 보겠습니다. Xcode에서 도우미 보기로 전환해 보겠습니다.

Creating the required actions

다음을 수행해 보겠습니다.

  1. 주소 메뉴 항목에서 AppDelegate.h 파일로 컨트롤을 끕니다.

  2. 연결 유형을 작업으로 전환합니다.

    Selecting the action type

  3. "phraseAddress"의 이름을 입력하고 커넥트 단추를 눌러 새 작업을 만듭니다.

    Configuring the action by entering a name.

  4. 날짜, 인사말서명 메뉴 항목에 대해 위의 단계를 반복합니다.

    The completed actions

  5. 변경 내용을 메뉴 모음에 저장합니다.

다음으로 코드에서 콘텐츠를 조정할 수 있도록 텍스트 보기에 대한 콘센트를 만들어야 합니다. 도우미 편집기에서 ViewController.h 파일을 선택하고 다음과 같은 documentText새 콘센트를 만듭니다.

Creating an outlet

Mac용 Visual Studio 돌아가서 Xcode의 변경 내용을 동기화합니다. 그런 다음 ViewController.cs 파일을 편집하고 다음과 같이 표시합니다.

using System;

using AppKit;
using Foundation;

namespace MacMenus
{
    public partial class ViewController : NSViewController
    {
        #region Application Access
        public static AppDelegate App {
            get { return (AppDelegate)NSApplication.SharedApplication.Delegate; }
        }
        #endregion

        #region Computed Properties
        public override NSObject RepresentedObject {
            get {
                return base.RepresentedObject;
            }
            set {
                base.RepresentedObject = value;
                // Update the view, if already loaded.
            }
        }

        public string Text {
            get { return documentText.Value; }
            set { documentText.Value = value; }
        } 
        #endregion

        #region Constructors
        public ViewController (IntPtr handle) : base (handle)
        {
        }
        #endregion

        #region Override Methods
        public override void ViewDidLoad ()
        {
            base.ViewDidLoad ();

            // Do any additional setup after loading the view.
        }

        public override void ViewWillAppear ()
        {
            base.ViewWillAppear ();

            App.textEditor = this;
        }

        public override void ViewWillDisappear ()
        {
            base.ViewDidDisappear ();

            App.textEditor = null;
        }
        #endregion
    }
}

그러면 텍스트 보기의 텍스트가 클래스 외부에 ViewController 노출되고 창이 포커스를 얻거나 잃으면 앱 대리자에게 알립니다. 이제 AppDelegate.cs 파일을 편집하고 다음과 같이 표시합니다.

using AppKit;
using Foundation;
using System;

namespace MacMenus
{
    [Register ("AppDelegate")]
    public partial class AppDelegate : NSApplicationDelegate
    {
        #region Computed Properties
        public ViewController textEditor { get; set;} = null;
        #endregion

        #region Constructors
        public AppDelegate ()
        {
        }
        #endregion

        #region Override Methods
        public override void DidFinishLaunching (NSNotification notification)
        {
            // Insert code here to initialize your application
        }

        public override void WillTerminate (NSNotification notification)
        {
            // Insert code here to tear down your application
        }
        #endregion

        #region Custom actions
        [Export ("openDocument:")]
        void OpenDialog (NSObject sender)
        {
            var dlg = NSOpenPanel.OpenPanel;
            dlg.CanChooseFiles = false;
            dlg.CanChooseDirectories = true;

            if (dlg.RunModal () == 1) {
                var alert = new NSAlert () {
                    AlertStyle = NSAlertStyle.Informational,
                    InformativeText = "At this point we should do something with the folder that the user just selected in the Open File Dialog box...",
                    MessageText = "Folder Selected"
                };
                alert.RunModal ();
            }
        }

        partial void phrasesAddress (Foundation.NSObject sender) {

            textEditor.Text += "Xamarin HQ\n394 Pacific Ave, 4th Floor\nSan Francisco CA 94111\n\n";
        }

        partial void phrasesDate (Foundation.NSObject sender) {

            textEditor.Text += DateTime.Now.ToString("D");
        }

        partial void phrasesGreeting (Foundation.NSObject sender) {

            textEditor.Text += "Dear Sirs,\n\n";
        }

        partial void phrasesSignature (Foundation.NSObject sender) {

            textEditor.Text += "Sincerely,\n\nKevin Mullins\nXamarin,Inc.\n";
        }
        #endregion
    }
}

여기서는 Interface Builder에서 AppDelegate 정의한 작업 및 콘센트를 사용할 수 있도록 부분 클래스를 만들었습니다. 또한 현재 포커스가 textEditor 있는 창을 추적하기 위해 노출합니다.

다음 메서드는 사용자 지정 메뉴 및 메뉴 항목을 처리하는 데 사용됩니다.

partial void phrasesAddress (Foundation.NSObject sender) {

    if (textEditor == null) return;
    textEditor.Text += "Xamarin HQ\n394 Pacific Ave, 4th Floor\nSan Francisco CA 94111\n\n";
}

partial void phrasesDate (Foundation.NSObject sender) {

    if (textEditor == null) return;
    textEditor.Text += DateTime.Now.ToString("D");
}

partial void phrasesGreeting (Foundation.NSObject sender) {

    if (textEditor == null) return;
    textEditor.Text += "Dear Sirs,\n\n";
}

partial void phrasesSignature (Foundation.NSObject sender) {

    if (textEditor == null) return;
    textEditor.Text += "Sincerely,\n\nKevin Mullins\nXamarin,Inc.\n";
}

이제 애플리케이션을 실행하면 메뉴의 모든 항목이 활성화되고 선택 시 텍스트 보기에 제공 구가 추가됩니다.

An example of the app running

이제 애플리케이션 메뉴 모음을 사용하는 기본 사항을 살펴보았습니다. 이제 사용자 지정 상황에 맞는 메뉴를 만드는 방법에 대해 살펴보겠습니다.

코드에서 메뉴 만들기

Xcode의 인터페이스 작성기를 사용하여 메뉴 및 메뉴 항목을 만드는 것 외에도 Xamarin.Mac 앱이 코드에서 메뉴, 하위 메뉴 또는 메뉴 항목을 만들거나 수정하거나 제거해야 하는 경우가 있을 수 있습니다.

다음 예제에서는 즉석에서 동적으로 생성될 메뉴 항목 및 하위 메뉴에 대한 정보를 보관하는 클래스를 만듭니다.

using System;
using System.Collections.Generic;
using Foundation;
using AppKit;

namespace AppKit.TextKit.Formatter
{
    public class LanguageFormatCommand : NSObject
    {
        #region Computed Properties
        public string Title { get; set; } = "";
        public string Prefix { get; set; } = "";
        public string Postfix { get; set; } = "";
        public List<LanguageFormatCommand> SubCommands { get; set; } = new List<LanguageFormatCommand>();
        #endregion

        #region Constructors
        public LanguageFormatCommand () {

        }

        public LanguageFormatCommand (string title)
        {
            // Initialize
            this.Title = title;
        }

        public LanguageFormatCommand (string title, string prefix)
        {
            // Initialize
            this.Title = title;
            this.Prefix = prefix;
        }

        public LanguageFormatCommand (string title, string prefix, string postfix)
        {
            // Initialize
            this.Title = title;
            this.Prefix = prefix;
            this.Postfix = postfix;
        }
        #endregion
    }
}

메뉴 및 항목 추가

이 클래스가 정의된 경우 다음 루틴은 개체 컬렉션을 LanguageFormatCommand구문 분석하고 전달된 기존 메뉴(Interface Builder에서 만든)의 아래쪽에 추가하여 새 메뉴 및 메뉴 항목을 재귀적으로 작성합니다.

private void AssembleMenu(NSMenu menu, List<LanguageFormatCommand> commands) {
    NSMenuItem menuItem;

    // Add any formatting commands to the Formatting menu
    foreach (LanguageFormatCommand command in commands) {
        // Add separator or item?
        if (command.Title == "") {
            menuItem = NSMenuItem.SeparatorItem;
        } else {
            menuItem = new NSMenuItem (command.Title);

            // Submenu?
            if (command.SubCommands.Count > 0) {
                // Yes, populate submenu
                menuItem.Submenu = new NSMenu (command.Title);
                AssembleMenu (menuItem.Submenu, command.SubCommands);
            } else {
                // No, add normal menu item
                menuItem.Activated += (sender, e) => {
                    // Apply the command on the selected text
                    TextEditor.PerformFormattingCommand (command);
                };
            }
        }
        menu.AddItem (menuItem);
    }
}

빈 속성이 있는 개체 LanguageFormatCommand 의 경우 이 루틴은 메뉴 섹션 사이에 구분 기호 메뉴 항목(얇은 회색 선)을 만듭니다.Title

menuItem = NSMenuItem.SeparatorItem;

제목이 제공되면 해당 제목이 있는 새 메뉴 항목이 만들어집니다.

menuItem = new NSMenuItem (command.Title);

개체에 LanguageFormatCommand 자식 LanguageFormatCommand 개체가 포함된 경우 하위 메뉴가 만들어지고 AssembleMenu 메서드가 재귀적으로 호출되어 해당 메뉴를 빌드합니다.

menuItem.Submenu = new NSMenu (command.Title);
AssembleMenu (menuItem.Submenu, command.SubCommands);

하위 메뉴가 없는 새 메뉴 항목의 경우 사용자가 선택하는 메뉴 항목을 처리하는 코드가 추가됩니다.

menuItem.Activated += (sender, e) => {
    // Do something when the menu item is selected
    ...
};

메뉴 만들기 테스트

위의 모든 코드를 사용하여 다음 개체 컬렉션을 만든 경우 다음을 LanguageFormatCommand 수행합니다.

// Define formatting commands
FormattingCommands.Add(new LanguageFormatCommand("Strong","**","**"));
FormattingCommands.Add(new LanguageFormatCommand("Emphasize","_","_"));
FormattingCommands.Add(new LanguageFormatCommand("Inline Code","`","`"));
FormattingCommands.Add(new LanguageFormatCommand("Code Block","```\n","\n```"));
FormattingCommands.Add(new LanguageFormatCommand("Comment","<!--","-->"));
FormattingCommands.Add (new LanguageFormatCommand ());
FormattingCommands.Add(new LanguageFormatCommand("Unordered List","* "));
FormattingCommands.Add(new LanguageFormatCommand("Ordered List","1. "));
FormattingCommands.Add(new LanguageFormatCommand("Block Quote","> "));
FormattingCommands.Add (new LanguageFormatCommand ());

var Headings = new LanguageFormatCommand ("Headings");
Headings.SubCommands.Add(new LanguageFormatCommand("Heading 1","# "));
Headings.SubCommands.Add(new LanguageFormatCommand("Heading 2","## "));
Headings.SubCommands.Add(new LanguageFormatCommand("Heading 3","### "));
Headings.SubCommands.Add(new LanguageFormatCommand("Heading 4","#### "));
Headings.SubCommands.Add(new LanguageFormatCommand("Heading 5","##### "));
Headings.SubCommands.Add(new LanguageFormatCommand("Heading 6","###### "));
FormattingCommands.Add (Headings);

FormattingCommands.Add(new LanguageFormatCommand ());
FormattingCommands.Add(new LanguageFormatCommand("Link","[","]()"));
FormattingCommands.Add(new LanguageFormatCommand("Image","![](",")"));
FormattingCommands.Add(new LanguageFormatCommand("Image Link","[![](",")](LinkImageHere)"));

그리고 해당 컬렉션이 함수에 AssembleMenu 전달되고( 서식 메뉴가 기본으로 설정됨) 다음과 같은 동적 메뉴 및 메뉴 항목이 만들어집니다.

The new menu items in the running app

메뉴 및 항목 제거

앱의 사용자 인터페이스에서 메뉴 또는 메뉴 항목을 제거해야 하는 경우 제거할 항목의 NSMenu 인덱스(0부터 시작)를 제공하여 클래스의 메서드를 사용할 RemoveItemAt 수 있습니다.

예를 들어 위의 루틴에서 만든 메뉴 및 메뉴 항목을 제거하려면 다음 코드를 사용할 수 있습니다.

public void UnpopulateFormattingMenu(NSMenu menu) {

    // Remove any additional items
    for (int n = (int)menu.Count - 1; n > 4; --n) {
        menu.RemoveItemAt (n);
    }
}

위의 코드의 경우 처음 네 개의 메뉴 항목은 Xcode의 인터페이스 작성기에서 만들어지고 앱에서 사용할 수 있으므로 동적으로 제거되지 않습니다.

상황에 맞는 메뉴

상황에 맞는 메뉴는 사용자가 창에서 항목을 마우스 오른쪽 단추로 클릭하거나 컨트롤을 클릭할 때 나타납니다. 기본적으로 macOS에 기본 제공되는 여러 UI 요소에는 이미 상황에 맞는 메뉴(예: 텍스트 보기)가 연결되어 있습니다. 그러나 창에 추가한 UI 요소에 대한 사용자 지정 상황에 맞는 메뉴를 만들려는 경우가 있을 수 있습니다.

Xcode에서 Main.storyboard 파일을 편집하고, 디자인에 창 창을 추가하고, 해당 클래스ID 검사기에서 "NSPanel"로 설정하고, 메뉴에 새 도우미 항목을 추가하고, Segue 표시를 사용하여 새 창에 연결해 보겠습니다.

Setting the segue type in the Main dot storyboard file.

다음을 수행해 보겠습니다.

  1. 라이브러리 검사기에서 패널 창으로 레이블을 끌어서 해당 텍스트를 "속성"으로 설정합니다.

    Editing the label's value

  2. 그런 다음 라이브러리 검사기의 메뉴를 보기 계층 구조의 보기 컨트롤러로 끌어와 문서, 텍스트글꼴의 세 가지 기본 메뉴 항목 이름을 바꿉니다.

    The required menu items

  3. 이제 속성 레이블 에서 메뉴로 컨트롤 끌기:

    Dragging to create a segue

  4. 팝업 대화 상자에서 메뉴를 선택합니다.

    Setting the segue type by selecting menu from Outlets in the Label context menu.

  5. ID 검사기에서 뷰 컨트롤러의 클래스를 "PanelViewController"로 설정합니다.

    Setting the segue class

  6. 동기화할 Mac용 Visual Studio 다시 전환한 다음 Interface Builder로 돌아갑니다.

  7. 도우미 편집기로 전환하고 PanelViewController.h 파일을 선택합니다.

  8. 다음과 같은 문서 메뉴 항목에 대한 작업을 만듭니다propertyDocument.

    Configuring the action named propertyDocument.

  9. 나머지 메뉴 항목에 대한 만들기 작업을 반복합니다.

    Repeating actions for the remaining menu items.

  10. 마지막으로 다음과 같은 속성 레이블 에 대한 콘센트를 만듭니다 propertyLabel.

    Configuring the outlet

  11. 변경 내용을 저장하고 Mac용 Visual Studio 돌아가 Xcode와 동기화합니다.

PanelViewController.cs 파일을 편집하고 다음 코드를 추가합니다.

partial void propertyDocument (Foundation.NSObject sender) {
    propertyLabel.StringValue = "Document";
}

partial void propertyFont (Foundation.NSObject sender) {
    propertyLabel.StringValue = "Font";
}

partial void propertyText (Foundation.NSObject sender) {
    propertyLabel.StringValue = "Text";
}

이제 애플리케이션을 실행하고 패널에서 속성 레이블을 마우스 오른쪽 단추로 클릭하면 사용자 지정 상황에 맞는 메뉴가 표시됩니다. 메뉴에서 항목을 선택하면 레이블의 값이 변경됩니다.

The contextual menu running

다음으로 상태 표시줄 메뉴를 만드는 방법에 대해 살펴보겠습니다.

상태 표시줄 메뉴

상태 표시줄 메뉴에는 응용 프로그램의 상태를 반영하는 메뉴 또는 이미지와 같이 사용자에게 상호 작용 또는 피드백을 제공하는 상태 메뉴 항목의 컬렉션이 표시됩니다. 애플리케이션이 백그라운드에서 실행 중인 경우에도 애플리케이션의 상태 표시줄 메뉴가 활성화되고 활성화됩니다. 시스템 수준 상태 표시줄은 애플리케이션 메뉴 모음의 오른쪽에 있으며 현재 macOS에서 사용할 수 있는 유일한 상태 표시줄입니다.

AppDelegate.cs 파일을 편집하고 메서드를 DidFinishLaunching 다음과 같이 만들어 보겠습니다.

public override void DidFinishLaunching (NSNotification notification)
{
    // Create a status bar menu
    NSStatusBar statusBar = NSStatusBar.SystemStatusBar;

    var item = statusBar.CreateStatusItem (NSStatusItemLength.Variable);
    item.Title = "Text";
    item.HighlightMode = true;
    item.Menu = new NSMenu ("Text");

    var address = new NSMenuItem ("Address");
    address.Activated += (sender, e) => {
        PhraseAddress(address);
    };
    item.Menu.AddItem (address);

    var date = new NSMenuItem ("Date");
    date.Activated += (sender, e) => {
        PhraseDate(date);
    };
    item.Menu.AddItem (date);

    var greeting = new NSMenuItem ("Greeting");
    greeting.Activated += (sender, e) => {
        PhraseGreeting(greeting);
    };
    item.Menu.AddItem (greeting);

    var signature = new NSMenuItem ("Signature");
    signature.Activated += (sender, e) => {
        PhraseSignature(signature);
    };
    item.Menu.AddItem (signature);
}

NSStatusBar statusBar = NSStatusBar.SystemStatusBar; 에서는 시스템 전체 상태 표시줄에 액세스할 수 있습니다. var item = statusBar.CreateStatusItem (NSStatusItemLength.Variable); 는 새 상태 표시줄 항목을 만듭니다. 여기에서 메뉴와 여러 메뉴 항목을 만들고 방금 만든 상태 표시줄 항목에 메뉴를 연결합니다.

애플리케이션을 실행하면 새 상태 표시줄 항목이 표시됩니다. 메뉴에서 항목을 선택하면 텍스트 보기의 텍스트가 변경됩니다.

The status bar menu running

다음으로 사용자 지정 도크 메뉴 항목을 만드는 방법에 대해 살펴보겠습니다.

사용자 지정 도킹 메뉴

사용자가 도크에서 애플리케이션의 아이콘을 마우스 오른쪽 단추로 클릭하거나 컨트롤을 클릭하면 Mac 애플리케이션에 대한 도크 메뉴가 나타납니다.

A custom dock menu

다음을 수행하여 애플리케이션에 대한 사용자 지정 도크 메뉴를 만들어 보겠습니다.

  1. Mac용 Visual Studio 애플리케이션의 프로젝트를 마우스 오른쪽 단추로 클릭하고 AddNew> 파일을 선택합니다... 새 파일 대화 상자에서 Xamarin.MacEmpty>인터페이스 정의를 선택하고 이름에 "DockMenu"를 사용하고 새로 만들기 단추를 클릭하여 새 DockMenu.xib 파일을 만듭니다.

    Adding an empty interface definition

  2. Solution Pad에서 DockMenu.xib 파일을 두 번 클릭하여 Xcode에서 편집할 수 있도록 엽니다. 주소, 날짜, 인사말서명 항목으로 새 메뉴를 만듭니다.

    Laying out the UI

  3. 다음으로, 위의 메뉴 추가, 편집 및 삭제 섹션에서 사용자 지정 메뉴에 대해 만든 기존 작업에 새 메뉴 항목을 연결해 보겠습니다. 연결 검사기로 전환하고 인터페이스 계층 구조에서 첫 번째 응답자를 선택합니다. 아래로 스크롤하여 작업을 찾습니다 phraseAddress: . 해당 동작의 원에서 주소 메뉴 항목으로 선을 끕니다.

    Dragging a line to the Address menu item.

  4. 해당 작업에 첨부하는 다른 모든 메뉴 항목에 대해 반복합니다.

    Repeating for other menu items attaching them to their corresponding actions.

  5. 다음으로 인터페이스 계층에서 애플리케이션을 선택합니다. 연결 검사기에서 선을 콘센트의 원 dockMenu 에서 방금 만든 메뉴로 끌어옵니다.

    Dragging the wire up the outlet

  6. 변경 내용을 저장하고 Mac용 Visual Studio 다시 전환하여 Xcode와 동기화합니다.

  7. Info.plist 파일을 두 번 클릭하여 편집용으로 엽니다.

    Editing the Info.plist file

  8. 화면 아래쪽의 원본 탭을 클릭합니다.

    Selecting the Source view

  9. 새 항목 추가를 클릭하고 녹색 더하기 단추를 클릭하고 속성 이름을 "AppleDockMenu"로 설정하고 값을 "DockMenu"(확장명 없이 새 .xib 파일의 이름)로 설정합니다.

    Adding the DockMenu item

이제 애플리케이션을 실행하고 Dock에서 해당 아이콘을 마우스 오른쪽 단추로 클릭하면 새 메뉴 항목이 표시됩니다.

An example of the dock menu running

메뉴에서 사용자 지정 항목 중 하나를 선택하면 텍스트 보기의 텍스트가 수정됩니다.

팝업 단추 및 풀다운 목록

팝업 단추는 선택한 항목을 표시하고 사용자가 클릭할 때 선택할 수 있는 옵션 목록을 표시합니다. 풀다운 목록은 일반적으로 현재 작업의 컨텍스트와 관련된 명령을 선택하는 데 사용되는 팝업 단추의 유형입니다. 둘 다 창의 아무 곳에나 나타날 수 있습니다.

다음을 수행하여 애플리케이션에 대한 사용자 지정 팝업 단추를 만들어 보겠습니다.

  1. Xcode에서 Main.storyboard 파일을 편집하고 라이브러리 검사기의팝업 단추를상황에 맞는 메뉴 섹션에서 만든 패널 창으로 끕니다.

    Adding a popup button

  2. 새 메뉴 항목을 추가하고 팝업의 항목 제목을 주소, 날짜, 인사말서명으로 설정합니다.

    Configuring the menu items

  3. 다음으로, 위의 메뉴 추가, 편집 및 삭제 섹션에서 사용자 지정 메뉴에 대해 만든 기존 작업에 새 메뉴 항목을 연결해 보겠습니다. 연결 검사기로 전환하고 인터페이스 계층 구조에서 첫 번째 응답자를 선택합니다. 아래로 스크롤하여 작업을 찾습니다 phraseAddress: . 해당 동작의 원에서 주소 메뉴 항목으로 선을 끕니다.

    Dragging to wire up an action

  4. 해당 작업에 첨부하는 다른 모든 메뉴 항목에 대해 반복합니다.

    All required actions

  5. 변경 내용을 저장하고 Mac용 Visual Studio 다시 전환하여 Xcode와 동기화합니다.

이제 애플리케이션을 실행하고 팝업에서 항목을 선택하면 텍스트 보기의 텍스트가 변경됩니다.

An example of the popup running

팝업 단추와 똑같은 방식으로 풀다운 목록을 만들고 작업할 수 있습니다. 기존 작업에 연결하는 대신 상황에 맞는 메뉴 섹션의 상황에 맞는 메뉴에 대해 수행한 것처럼 고유한 사용자 지정 작업을 만들 수 있습니다.

요약

이 문서에서는 Xamarin.Mac 애플리케이션의 메뉴 및 메뉴 항목 작업에 대해 자세히 살펴보았습니다. 먼저 애플리케이션의 메뉴 모음을 살펴본 다음 상황에 맞는 메뉴를 만드는 것을 살펴본 다음 상태 표시줄 메뉴 및 사용자 지정 도크 메뉴를 검사했습니다. 마지막으로 팝업 메뉴와 풀다운 목록을 설명했습니다.