Menüs in Xamarin.Mac

In diesem Artikel wird die Arbeit mit Menüs in einer Xamarin.Mac-Anwendung behandelt. Es beschreibt das Erstellen und Standard Enthalten von Menüs und Menüelementen in Xcode und Interface Builder und die programmgesteuerte Arbeit mit ihnen.

Beim Arbeiten mit C# und .NET in einer Xamarin.Mac-Anwendung haben Sie Zugriff auf die gleichen Kakaomenüs, in Objective-C denen ein Entwickler arbeitet und Xcode ausführt. Da Xamarin.Mac direkt in Xcode integriert ist, können Sie den Schnittstellen-Generator von Xcode verwenden, um Ihre Menüleisten, Menüs und Menüelemente zu erstellen und zu Standard (oder optional direkt im C#-Code zu erstellen).

Menüs sind ein integraler Bestandteil der Benutzeroberfläche einer Mac-Anwendung und werden häufig in verschiedenen Teilen der Benutzeroberfläche angezeigt:

  • Die Menüleiste der Anwendung – Dies ist das Standard Menü, das oben auf dem Bildschirm für jede Mac-Anwendung angezeigt wird.
  • Kontextmenüs – Diese werden angezeigt, wenn der Benutzer mit der rechten Maustaste klickt oder ein Element in einem Fenster klickt.
  • Die Statusleiste – Dies ist der Bereich ganz rechts auf der Anwendungsmenüleiste, der oben auf dem Bildschirm (links neben der Menüleistenuhr) angezeigt wird und nach links wächst, wenn die Elemente hinzugefügt werden.
  • Dockmenü – Das Menü für jede Anwendung im Dock, das angezeigt wird, wenn der Benutzer mit der rechten Maustaste klickt oder auf das Symbol der Anwendung klickt, oder wenn der Benutzer mit der linken Maustaste auf das Symbol klickt und die Maustaste gedrückt hält.
  • Popupschaltfläche und Pulldownlisten – Eine Popupschaltfläche zeigt ein ausgewähltes Element an und zeigt eine Liste mit Optionen an, aus denen Sie auswählen können, wenn der Benutzer darauf klickt. Eine Pulldownliste ist eine Art Popupschaltfläche, die normalerweise zum Auswählen von Befehlen verwendet wird, die für den Kontext der aktuellen Aufgabe spezifisch sind. Beide können an einer beliebigen Stelle in einem Fenster angezeigt werden.

An example menu

In diesem Artikel behandeln wir die Grundlagen der Arbeit mit Cocoa-Menüleisten, Menüs und Menüelementen in einer Xamarin.Mac-Anwendung. Es wird dringend empfohlen, dass Sie zuerst den Artikel "Hello, Mac " durcharbeiten, insbesondere die Abschnitte "Einführung in Xcode" und "Interface Builder " und "Outlets" und "Actions ", da es sich um wichtige Konzepte und Techniken handelt, die wir in diesem Artikel verwenden werden.

Möglicherweise möchten Sie sich auch die Exposing C#-Klassen /-Methoden im Objective-C Abschnitt des Xamarin.Mac Internals-Dokuments ansehen. Außerdem werden die Register C#-Klassen und Export Attribute erläutert, die zum Verketten Ihrer C#-Klassen mit Objective-C Objekten und UI-Elementen verwendet werden.

Die Menüleiste der Anwendung

Im Gegensatz zu Anwendungen, die auf dem Windows-Betriebssystem ausgeführt werden, an denen jedes Fenster über eine eigene Menüleiste verfügen kann, verfügt jede anwendung, die unter macOS ausgeführt wird, über eine einzelne Menüleiste, die am oberen Rand des Bildschirms ausgeführt wird, der für jedes Fenster in dieser Anwendung verwendet wird:

A menu bar

Elemente auf dieser Menüleiste werden basierend auf dem aktuellen Kontext oder Status der Anwendung und der Benutzeroberfläche zu einem bestimmten Zeitpunkt aktiviert oder deaktiviert. Beispiel: Wenn der Benutzer ein Textfeld auswählt, werden elemente im Menü "Bearbeiten " aktiviert, z . B. "Kopieren " und "Ausschneiden".

Gemäß Apple und standardmäßig verfügen alle macOS-Anwendungen über einen Standardsatz von Menüs und Menüelementen, die in der Menüleiste der Anwendung angezeigt werden:

  • Apple-Menü – Dieses Menü bietet Zugriff auf systemweite Elemente, die dem Benutzer jederzeit zur Verfügung stehen, unabhängig davon, welche Anwendung ausgeführt wird. Diese Elemente können vom Entwickler nicht geändert werden.
  • App-Menü – Dieses Menü zeigt den Namen der Anwendung fett an und hilft dem Benutzer zu identifizieren, welche Anwendung derzeit ausgeführt wird. Sie enthält Elemente, die für die Anwendung als Ganzes gelten und kein bestimmtes Dokument oder Prozess, z. B. das Beenden der Anwendung.
  • Menü "Datei" – Elemente zum Erstellen, Öffnen oder Speichern von Dokumenten, mit denen Ihre Anwendung arbeitet. Wenn Ihre Anwendung nicht dokumentbasiert ist, kann dieses Menü umbenannt oder entfernt werden.
  • Menü " Bearbeiten" – Enthält Befehle wie "Ausschneiden", "Kopieren" und "Einfügen" , die zum Bearbeiten oder Ändern von Elementen auf der Benutzeroberfläche der Anwendung verwendet werden.
  • Menü "Format" – Wenn die Anwendung mit Text arbeitet, enthält dieses Menü Befehle, um die Formatierung dieses Texts anzupassen.
  • Menü "Ansicht" – Enthält Befehle, die sich darauf auswirken, wie Inhalte auf der Benutzeroberfläche der Anwendung angezeigt (angezeigt) werden.
  • Anwendungsspezifische Menüs – Dies sind alle Menüs , die für Ihre Anwendung spezifisch sind (z. B. ein Lesezeichenmenü für einen Webbrowser). Sie sollten zwischen den Menüs "Ansicht" und "Fenster " auf der Leiste angezeigt werden.
  • Fenstermenü – Enthält Befehle zum Arbeiten mit Fenstern in Ihrer Anwendung sowie eine Liste der aktuellen geöffneten Fenster.
  • Hilfemenü – Wenn Ihre Anwendung Hilfe auf dem Bildschirm bereitstellt, sollte das Hilfemenü das am besten geeignete Menü auf der Leiste sein.

Weitere Informationen zur Anwendungsmenüleiste und Standardmenüs und Menüelementen finden Sie in den Richtlinien für die Menschliche Benutzeroberfläche von Apple.

Die Standardmenüleiste der Anwendung

Immer wenn Sie ein neues Xamarin.Mac-Projekt erstellen, erhalten Sie automatisch eine Standardmenüleiste der Anwendung mit den typischen Elementen, die eine macOS-Anwendung normalerweise haben würde (wie im obigen Abschnitt beschrieben). Die Standardmenüleiste Ihrer Anwendung wird in der Datei "Main.storyboard " (zusammen mit den restlichen Ui-Elemente Ihrer App) unter dem Projekt im Lösungspad definiert:

Select the main storyboard

Doppelklicken Sie auf die Datei "Main.storyboard ", um sie zum Bearbeiten im Benutzeroberflächen-Generator von Xcode zu öffnen, und Sie werden der Menü-Editor-Schnittstelle angezeigt:

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

Von hier aus können wir auf Elemente wie das Menüelement "Öffnen " im Menü "Datei " klicken und dessen Eigenschaften im Attributes Inspector bearbeiten oder anpassen:

Editing a menu's attributes

Später in diesem Artikel erfahren Sie, wie Sie Menüs und Elemente hinzufügen, bearbeiten und löschen. Jetzt möchten wir nur sehen, welche Menüs und Menüelemente standardmäßig verfügbar sind und wie sie automatisch über eine Reihe vordefinierter Verkaufsstellen und Aktionen für Code verfügbar gemacht wurden (weitere Informationen finden Sie in der Dokumentation zu Outlets und Aktionen ).

Wenn wir beispielsweise auf den Verbinden ion Inspector für das Menüelement "Öffnen" klicken, wird es automatisch mit der openDocument: Aktion verkabelt:

Viewing the attached action

Wenn Sie den ersten Responder in der Schnittstellenhierarchie auswählen und im Verbinden ion Inspector nach unten scrollen und die Definition der openDocument: Aktion sehen, an die das Menüelement "Öffnen" angefügt ist (zusammen mit mehreren anderen Standardaktionen für die Anwendung, die nicht automatisch mit Steuerelementen verkabelt werden):

Viewing all attached actions

Warum ist dies wichtig? Im nächsten Abschnitt wird gezeigt, wie diese automatisch definierten Aktionen mit anderen Cocoa-Benutzeroberflächenelementen funktionieren, um Menüelemente automatisch zu aktivieren und zu deaktivieren sowie integrierte Funktionen für die Elemente bereitzustellen.

Später verwenden wir diese integrierten Aktionen, um Elemente aus Code zu aktivieren und zu deaktivieren und unsere eigenen Funktionen bereitzustellen, wenn sie ausgewählt sind.

Integrierte Menüfunktionen

Wenn Sie eine neu erstellte Xamarin.Mac-Anwendung ausgeführt haben, bevor Sie UI-Elemente oder Code hinzufügen, werden Sie feststellen, dass einige Elemente automatisch verkabelt und für Sie aktiviert sind (mit vollständiger Funktionalität automatisch integriert), z. B. das Element "Beenden " im App-Menü :

An enabled menu item

Andere Menüelemente wie "Ausschneiden", "Kopieren" und "Einfügen " sind nicht:

Disabled menu items

Lassen Sie uns die Anwendung beenden und auf die Datei "Main.storyboard " im Lösungspad doppelklicken, um sie zum Bearbeiten im Schnittstellen-Generator von Xcode zu öffnen. Ziehen Sie als Nächstes eine Textansicht aus der Bibliothek auf den Ansichtscontroller des Fensters im Schnittstellen-Editor:

Selecting a Text View from the Library

Im Einschränkungs-Editor werden wir die Textansicht an die Ränder des Fensters anheften und mit dem Fenster verkleinern, indem wir oben im Editor auf alle vier roten I-Balken klicken und auf die Schaltfläche "4 Einschränkungen hinzufügen" klicken:

Editing the contraints

Speichern Sie Ihre Änderungen am Benutzeroberflächendesign, und wechseln Sie zurück zum Visual Studio für Mac, um die Änderungen mit Ihrem Xamarin.Mac-Projekt zu synchronisieren. Starten Sie nun die Anwendung, geben Sie Text in die Textansicht ein, markieren Sie sie, und öffnen Sie das Menü "Bearbeiten ":

The menu items are automatically enabled/disabled

Beachten Sie, dass die Elemente "Ausschneiden", "Kopieren" und "Einfügen " automatisch aktiviert und vollständig funktionsfähig sind, ohne eine einzelne Codezeile zu schreiben.

Was geht da vor? Denken Sie daran, dass die integrierten vordefinierten Aktionen, die an die Standardmenüelemente (wie oben dargestellt) verkabelt werden, die meisten Der Cocoa-Benutzeroberflächenelemente, die Teil von macOS sind, integrierte Hooks zu bestimmten Aktionen (z copy:. B. ). Wenn sie also zu einem Fenster hinzugefügt, aktiv und ausgewählt werden, werden die entsprechenden Menüelemente oder Elemente, die dieser Aktion zugeordnet sind, automatisch aktiviert. Wenn der Benutzer dieses Menüelement auswählt, wird die in das UI-Element integrierte Funktionalität aufgerufen und ausgeführt, alle ohne Entwicklereingriff.

Aktivieren und Deaktivieren von Menüs und Elementen

Standardmäßig aktiviert und deaktiviert jedes Benutzerereignis NSMenu jedes sichtbare Menü- und Menüelement basierend auf dem Kontext der Anwendung. Es gibt drei Möglichkeiten zum Aktivieren/Deaktivieren eines Elements:

  • Automatische Menüaktivierung – Ein Menüelement ist aktiviert, wenn NSMenu ein entsprechendes Objekt gefunden werden kann, das auf die Aktion reagiert, auf die das Element verkabelt ist. Die Textansicht oben, die einen integrierten Hook für die copy: Aktion enthält.
  • Benutzerdefinierte Aktionen und validateMenuItem: – Für jedes Menüelement, das an eine benutzerdefinierte Aktion eines Fensters oder Ansichtscontrollers gebunden ist, können Sie die validateMenuItem: Aktion hinzufügen und Menüelemente manuell aktivieren oder deaktivieren.
  • Manuelle Menüaktivierung – Sie legen die Enabled Eigenschaft der einzelnen NSMenuItem Elemente manuell fest, um jedes Element in einem Menü einzeln zu aktivieren oder zu deaktivieren.

Um ein System auszuwählen, legen Sie die AutoEnablesItems Eigenschaft einer .NSMenu true ist automatisch (das Standardverhalten) und false ist manuell.

Wichtig

Wenn Sie die manuelle Menüaktivierung verwenden, werden auch die von AppKit-Klassen NSTextViewgesteuerten Menüelemente nicht automatisch aktualisiert. Sie sind dafür verantwortlich, alle Elemente manuell im Code zu aktivieren und zu deaktivieren.

Verwenden von validateMenuItem

Wie oben erwähnt, können Sie für jedes Menüelement, das an eine benutzerdefinierte Aktion für Fenster- oder Ansichtscontroller gebunden ist, die validateMenuItem: Aktion hinzufügen und Menüelemente manuell aktivieren oder deaktivieren.

Im folgenden Beispiel wird die Tag Eigenschaft verwendet, um den Typ des Menüelements zu bestimmen, das von der validateMenuItem: Aktion basierend auf dem Status des markierten Texts in einem NSTextViewaktiviert/deaktiviert wird. Die Tag Eigenschaft wurde im Schnittstellen-Generator für jedes Menüelement festgelegt:

Setting the Tag property

Und der folgende Code wurde dem Ansichtscontroller hinzugefügt:

[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;
}

Wenn dieser Code ausgeführt wird und kein Text im NSTextViewBereich ausgewählt ist, sind die beiden Umbruchmenüelemente deaktiviert (auch wenn sie mit Aktionen auf dem Ansichtscontroller verbunden sind):

Showing disabled items

Wenn ein Textabschnitt ausgewählt und das Menü erneut geöffnet wird, stehen die beiden Umbruchmenüelemente zur Verfügung:

Showing enabled items

Aktivieren und Reagieren auf Menüelemente im Code

Wie wir oben gesehen haben, werden nur durch Hinzufügen bestimmter Cocoa-Benutzeroberflächenelemente zu unserem UI-Design (z. B. ein Textfeld) mehrere der Standardmenüelemente aktiviert und funktionieren automatisch, ohne Code schreiben zu müssen. Als Nächstes betrachten wir das Hinzufügen unseres eigenen C#-Codes zu unserem Xamarin.Mac-Projekt, um ein Menüelement zu aktivieren und Funktionen bereitzustellen, wenn der Benutzer es auswählt.

Angenommen, der Benutzer soll das Element "Öffnen" im Menü "Datei " verwenden können, um einen Ordner auszuwählen. Da dies eine anwendungsweite Funktion sein soll und nicht auf ein Zuweisen von Fenstern oder UI-Elementen beschränkt ist, fügen wir den Code hinzu, um dies unserem Anwendungsdelegat zu behandeln.

Doppelklicken Sie auf dem Lösungspad auf die AppDelegate.CS Datei, um sie zur Bearbeitung zu öffnen:

Selecting the app delegate

Fügen Sie unter der DidFinishLaunching-Methode folgenden Code hinzu:

[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 ();
    }
}

Lassen Sie uns die Anwendung jetzt ausführen und das Menü "Datei " öffnen:

The File menu

Beachten Sie, dass das Menüelement "Öffnen" jetzt aktiviert ist. Wenn wir es auswählen, wird das geöffnete Dialogfeld angezeigt:

An open dialog

Wenn wir auf die Schaltfläche "Öffnen " klicken, wird unsere Warnmeldung angezeigt:

An example dialog message

Die wichtigste Zeile hier war [Export ("openDocument:")], es teilt NSMenu mit, dass unser AppDelegate eine Methode void OpenDialog (NSObject sender) hat, die auf die openDocument: Aktion reagiert. Wenn Sie sich von oben erinnern, wird das Menüelement "Öffnen " automatisch mit dieser Aktion standardmäßig im Schnittstellen-Generator verkabelt:

Viewing the attached actions

Als Nächstes befassen wir uns mit dem Erstellen eines eigenen Menüs, menüelements und Aktionen und reagieren im Code darauf.

Arbeiten mit dem geöffneten Menü "Zuletzt verwendet"

Standardmäßig enthält das Menü "Datei " ein Element "Zuletzt geöffnet ", das die letzten Dateien nachverfolgt, die der Benutzer mit Ihrer App geöffnet hat. Wenn Sie eine NSDocument basierte Xamarin.Mac-App erstellen, wird dieses Menü automatisch für Sie behandelt. Für jede andere Art von Xamarin.Mac-App sind Sie dafür verantwortlich, dieses Menüelement manuell zu verwalten und darauf zu reagieren.

Um das Menü "Zuletzt geöffnet" manuell zu behandeln, müssen Sie sie zuerst darüber informieren, dass eine neue Datei mit den folgenden Optionen geöffnet oder gespeichert wurde:

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

Obwohl Ihre App nicht verwendet NSDocumentswird, verwenden Sie weiterhin das NSDocumentController Menü "Zuletzt geöffnet" Standard, indem Sie einen NSUrl mit dem Speicherort der Datei an die NoteNewRecentDocumentURL Methode der Datei SharedDocumentControllersenden.

Als Nächstes müssen Sie die OpenFile Methode des App-Delegaten überschreiben, um eine Datei zu öffnen, die der Benutzer im Menü "Zuletzt geöffnet" auswählt. Zum Beispiel:

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;
    }
}

Gibt zurück true , wenn die Datei geöffnet werden kann, andernfalls false wird dem Benutzer eine integrierte Warnung angezeigt, dass die Datei nicht geöffnet werden konnte.

Da der vom Menü "Zuletzt verwendete Öffnen" zurückgegebene Dateiname und pfad ein Leerzeichen enthalten kann, müssen wir dieses Zeichen ordnungsgemäß escapeen, bevor ein NSUrl Fehler erstellt wird. Dazu verwenden wir den folgenden Code:

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

Schließlich erstellen wir ein NSUrl Element, das auf die Datei verweist, und verwenden eine Hilfsmethode im App-Delegaten, um ein neues Fenster zu öffnen und die Datei darin zu laden:

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

Um alles zusammenzuführen, werfen wir einen Blick auf eine Beispielimplementierung in einer AppDelegate.cs Datei:

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
    }
}

Basierend auf den Anforderungen Ihrer App möchten Sie möglicherweise nicht, dass der Benutzer dieselbe Datei gleichzeitig in mehreren Fenstern öffnen kann. Wenn der Benutzer in unserer Beispiel-App eine datei auswählt, die bereits geöffnet ist (entweder aus den Menüelementen "Zuletzt geöffnet " oder "Öffnen"). Das Fenster, das die Datei enthält, wird an den Anfang gebracht.

Dazu haben wir den folgenden Code in unserer Hilfsmethode verwendet:

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;
    }
}

Wir haben unsere ViewController Klasse entwickelt, um den Pfad zur Datei in ihrer Path Eigenschaft zu speichern. Als Nächstes durchlaufen wir alle derzeit geöffneten Fenster in der App. Wenn die Datei bereits in einem der Fenster geöffnet ist, wird sie an die Vorderseite aller anderen Fenster mit folgenden Fenstern gebracht:

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

Wenn keine Übereinstimmung gefunden wird, wird ein neues Fenster mit geladener Datei geöffnet, und die Datei wird im Menü "Zuletzt geöffnet" angegeben:

// 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);

Arbeiten mit benutzerdefinierten Fensteraktionen

Genau wie die integrierten First Responder-Aktionen, die vorab an Standardmenüelemente verkabelt sind, können Sie neue, benutzerdefinierte Aktionen erstellen und mit Menüelementen im Schnittstellen-Generator verknüpfen.

Definieren Sie zunächst eine benutzerdefinierte Aktion auf einem der Fenstercontroller Ihrer App. Zum Beispiel:

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

Doppelklicken Sie als Nächstes auf die Storyboarddatei der App im Lösungspad , um sie zum Bearbeiten im Schnittstellen-Generator von Xcode zu öffnen. Wählen Sie den ersten Responder unter der Anwendungsszene aus, und wechseln Sie dann zum Attributes Inspector:

The Attributes Inspector

Klicken Sie unten im Attributes Inspector auf die + Schaltfläche, um eine neue benutzerdefinierte Aktion hinzuzufügen:

Adding a new action

Geben Sie ihm denselben Namen wie die benutzerdefinierte Aktion, die Sie auf dem Fenstercontroller erstellt haben:

Editing the action name

Ctrl-Click und Drag from a menu item to the First Responder under the Application Scene. Wählen Sie in der Popupliste die neue Aktion aus, die Sie soeben erstellt haben (defineKeyword: in diesem Beispiel):

Attaching an action

Speichern Sie die Änderungen im Storyboard, und kehren Sie zu Visual Studio für Mac zurück, um die Änderungen zu synchronisieren. Wenn Sie die App ausführen, wird das Menüelement, mit dem Sie die benutzerdefinierte Aktion verbunden haben, automatisch aktiviert/deaktiviert (basierend auf dem Fenster, in dem die Aktion geöffnet wird), und das Auswählen des Menüelements löst die Aktion aus:

Testing the new action

Hinzufügen, Bearbeiten und Löschen von Menüs

Wie wir in den vorherigen Abschnitten gesehen haben, enthält eine Xamarin.Mac-Anwendung eine vordefinierte Anzahl von Standardmenüs und Menüelementen, auf die bestimmte UI-Steuerelemente automatisch aktiviert und darauf reagieren. Darüber hinaus haben wir erfahren, wie Wir code zu unserer Anwendung hinzufügen, die auch diese Standardelemente aktivieren und darauf reagieren wird.

In diesem Abschnitt befassen wir uns mit dem Entfernen von nicht benötigten Menüelementen, der Neuorganisation von Menüs und dem Hinzufügen neuer Menüs, Menüelemente und Aktionen.

Doppelklicken Sie auf die Datei "Main.storyboard " im Lösungspad , um sie zur Bearbeitung zu öffnen:

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

Für unsere spezifische Xamarin.Mac-Anwendung werden wir das Standardmenü "Ansicht " nicht verwenden, damit wir es entfernen werden. Wählen Sie in der Schnittstellenhierarchie das Menüelement "Ansicht" aus, das Teil der Standard Menüleiste ist:

Selecting the View menu item

Drücken Sie ENTF oder RÜCKTASTE, um das Menü zu löschen. Als Nächstes verwenden wir nicht alle Elemente im Menü "Format ", und wir möchten die Elemente verschieben, die wir unter den Untermenüs verwenden werden. Wählen Sie in der Schnittstellenhierarchie die folgenden Menüelemente aus:

Highlighting multiple items

Ziehen Sie die Elemente im übergeordneten Menü aus dem Untermenü, in dem sie sich derzeit befinden:

Dragging menu items to the parent menu

Ihr Menü sollte jetzt wie folgt aussehen:

The items in the new location

Als Nächstes ziehen wir das Untermenü "Text" aus dem Menü "Format" heraus, und platzieren Sie es in der menüleiste Standard zwischen den Menüs "Format" und "Fenster":

The Text menu

Wechseln wir zurück im Menü "Format ", und löschen Sie das Untermenüelement "Schriftart ". Wählen Sie als Nächstes das Menü "Format " aus, und benennen Sie es in "Schriftart" um:

The Font menu

Als Nächstes erstellen wir ein benutzerdefiniertes Menü mit vordefinierten Ausdrücken, die beim Auswählen automatisch an den Text in der Textansicht angefügt werden. Geben Sie im Suchfeld unten im Bibliotheksinspektor "Menü" ein. Dies erleichtert das Auffinden und Arbeiten mit allen Menü-UI-Elementen:

The Library Inspector

Gehen wir nun wie folgt vor, um unser Menü zu erstellen:

  1. Ziehen Sie ein Menüelement aus dem Bibliotheksinspektor auf die Menüleiste zwischen den Menüs "Text " und "Fenster ":

    Selecting a new menu item in the Library

  2. Benennen Sie das Element "Phrasen" um:

    Setting the menu name

  3. Ziehen Sie als Nächstes ein Menü aus dem Bibliotheksinspektor:

    Selecting a menu from the Library

  4. Drop then Menu on the new Menu Item we just created and change its name to "Phrases":

    Editing the menu name

  5. Jetzt benennen wir die drei Standardmenüelemente "Adresse", "Datum" und "Gruß" um:

    The Phrases menu

  6. Fügen wir ein viertes Menüelement hinzu, indem wir ein Menüelement aus dem Bibliotheksinspektor ziehen und es "Signatur" aufrufen:

    Editing the menu item name

  7. Speichern Sie die Änderungen in der Menüleiste.

Jetzt erstellen wir eine Reihe von benutzerdefinierten Aktionen, sodass unsere neuen Menüelemente für C#-Code verfügbar gemacht werden. In Xcode wechseln wir zur Assistentenansicht :

Creating the required actions

Gehen wir wie folgt vor:

  1. Ctrl-Drag from the Address menu item to the AppDelegate.h file.

  2. Wechseln Sie den Verbinden ionstyp zu "Aktion":

    Selecting the action type

  3. Geben Sie einen Namen von "phraseAddress" ein, und drücken Sie die Schaltfläche Verbinden, um die neue Aktion zu erstellen:

    Configuring the action by entering a name.

  4. Wiederholen Sie die vorstehenden Schritte für die Menüelemente "Datum", "Begrüßung" und "Signatur ":

    The completed actions

  5. Speichern Sie die Änderungen in der Menüleiste.

Als Nächstes müssen wir eine Steckdose für unsere Textansicht erstellen, damit wir den Inhalt aus Code anpassen können. Wählen Sie die Datei ViewController.h im Assistenten-Editor aus, und erstellen Sie einen neuen Ausgang namens documentText:

Creating an outlet

Kehren Sie zu Visual Studio für Mac zurück, um die Änderungen aus Xcode zu synchronisieren. Bearbeiten Sie als Nächstes die ViewController.cs Datei, und sehen Sie wie folgt aus:

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
    }
}

Dadurch wird der Text unserer Textansicht außerhalb der ViewController Klasse verfügbar gemacht und die App-Stellvertretung informiert, wenn das Fenster den Fokus erhält oder verliert. Bearbeiten Sie nun die AppDelegate.cs Datei, und sehen Sie wie folgt aus:

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
    }
}

Hier haben wir die AppDelegate partielle Klasse erstellt, damit wir die Aktionen und Ausgänge verwenden können, die wir im Schnittstellen-Generator definiert haben. Außerdem wird ein textEditor Fenster verfügbar gemacht, um nachzuverfolgen, welches Fenster derzeit im Fokus ist.

Die folgenden Methoden werden verwendet, um unsere benutzerdefinierten Menü- und Menüelemente zu verarbeiten:

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";
}

Wenn wir nun unsere Anwendung ausführen, sind alle Elemente im Menü "Ausdruck " aktiv und fügen den Ausdruck der Textansicht hinzu, wenn sie ausgewählt ist:

An example of the app running

Nachdem wir nun die Grundlagen der Arbeit mit der Anwendungsmenüleiste unten haben, sehen wir uns das Erstellen eines benutzerdefinierten Kontextmenüs an.

Erstellen von Menüs aus Code

Neben dem Erstellen von Menüs und Menüelementen mit dem Benutzeroberflächen-Generator von Xcode kann es vorkommen, dass eine Xamarin.Mac-App ein Menü, ein Untermenü oder ein Menüelement aus Code erstellen, ändern oder entfernen muss.

Im folgenden Beispiel wird eine Klasse erstellt, um die Informationen zu den Menüelementen und Untermenüs zu enthalten, die dynamisch dynamisch erstellt werden:

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
    }
}

Hinzufügen von Menüs und Elementen

Mit dieser definierten Klasse analysiert die folgende Routine eine Auflistung von LanguageFormatCommandObjekten und erstellt rekursiv neue Menüs und Menüelemente, indem sie am Ende des vorhandenen Menüs (erstellt im Schnittstellen-Generator) angefügt werden, das übergeben wurde:

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);
    }
}

Für jedes LanguageFormatCommand Objekt mit einer leeren Title Eigenschaft erstellt diese Routine ein Trennzeichenmenüelement (eine dünne graue Linie) zwischen Menüabschnitten:

menuItem = NSMenuItem.SeparatorItem;

Wenn ein Titel bereitgestellt wird, wird ein neues Menüelement mit diesem Titel erstellt:

menuItem = new NSMenuItem (command.Title);

Wenn das LanguageFormatCommand Objekt untergeordnete LanguageFormatCommand Objekte enthält, wird ein Untermenü erstellt, und die AssembleMenu Methode wird rekursiv aufgerufen, um dieses Menü zu erstellen:

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

Für jedes neue Menüelement, das keine Untermenüs enthält, wird Code hinzugefügt, um das vom Benutzer ausgewählte Menüelement zu behandeln:

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

Testen der Menüerstellung

Wenn die folgende Auflistung von LanguageFormatCommand Objekten erstellt wurde, ist der obige Code vorhanden:

// 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)"));

Und diese Auflistung, die an die AssembleMenu Funktion übergeben wurde (wobei das Menü "Format " als Basis festgelegt wurde), würden die folgenden dynamischen Menüs und Menüelemente erstellt:

The new menu items in the running app

Entfernen von Menüs und Elementen

Wenn Sie ein Menü- oder Menüelement aus der Benutzeroberfläche der App entfernen müssen, können Sie einfach die RemoveItemAt Methode der NSMenu Klasse verwenden, indem Sie ihm den nullbasierten Index des zu entfernenden Elements zuordnen.

Um beispielsweise die Menüs und Menüelemente zu entfernen, die von der obigen Routine erstellt wurden, können Sie den folgenden Code verwenden:

public void UnpopulateFormattingMenu(NSMenu menu) {

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

Im Fall des obigen Codes werden die ersten vier Menüelemente im Schnittstellen-Generator von Xcode erstellt und entfernt, sodass sie nicht dynamisch entfernt werden.

Kontextmenüs

Kontextmenüs werden angezeigt, wenn der Benutzer mit der rechten Maustaste klickt oder auf ein Element in einem Fenster klickt. Standardmäßig verfügen mehrere der in macOS integrierten UI-Elemente bereits über Kontextmenüs (z. B. die Textansicht). Es kann jedoch vorkommen, dass wir unsere eigenen benutzerdefinierten Kontextmenüs für ein UI-Element erstellen möchten, das wir einem Fenster hinzugefügt haben.

Bearbeiten wir die Datei "Main.storyboard" in Xcode, und fügen Sie unserem Design ein Fensterfenster hinzu, legen Sie die Klasse im Identitätsinspektor auf "NSPanel" fest, fügen Sie dem Menü "Fenster" ein neues Assistentenelement hinzu, und fügen Sie es mithilfe einer Show Segue an das neue Fenster an:

Setting the segue type in the Main dot storyboard file.

Gehen wir wie folgt vor:

  1. Ziehen Sie eine Beschriftung aus dem Bibliotheksinspektor in das Fenster "Panel ", und legen Sie dessen Text auf "Eigenschaft" fest:

    Editing the label's value

  2. Ziehen Sie als Nächstes ein Menü aus dem Bibliotheksinspektor auf den Ansichtscontroller in der Ansichtshierarchie, und benennen Sie die drei Standardmenüelemente Dokument, Text und Schriftart um:

    The required menu items

  3. Ziehen Sie nun ctrl-drag from the Property Label in the Menu:

    Dragging to create a segue

  4. Wählen Sie im Popupdialogfeld "Menü" aus:

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

  5. Legen Sie aus dem Identitätsinspektor die Klasse des Ansichtscontrollers auf "PanelViewController" fest:

    Setting the segue class

  6. Wechseln Sie zurück zu Visual Studio für Mac, um die Synchronisierung zu synchronisieren, und kehren Sie dann zum Schnittstellen-Generator zurück.

  7. Wechseln Sie zum Assistenten-Editor , und wählen Sie die Datei "PanelViewController.h " aus.

  8. Erstellen einer Aktion für das Menüelement "Dokument" mit dem Namen propertyDocument:

    Configuring the action named propertyDocument.

  9. Wiederholen Sie das Erstellen von Aktionen für die Neu Standard menüelemente:

    Repeating actions for the remaining menu items.

  10. Erstellen Sie schließlich eine Steckdose für die Eigenschaftsbezeichnung namens propertyLabel:

    Configuring the outlet

  11. Speichern Sie Ihre Änderungen, und kehren Sie zu Visual Studio für Mac zurück, um mit Xcode zu synchronisieren.

Bearbeiten Sie die PanelViewController.cs Datei, und fügen Sie den folgenden Code hinzu:

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";
}

Wenn wir nun die Anwendung ausführen und mit der rechten Maustaste auf die Eigenschaftenbeschriftung im Bereich klicken, wird unser benutzerdefiniertes Kontextmenü angezeigt. Wenn wir im Menü auswählen und elementieren, ändert sich der Wert der Bezeichnung:

The contextual menu running

Als Nächstes sehen wir uns das Erstellen von Statusleistenmenüs an.

Statusleistenmenüs

Statusleistenmenüs zeigen eine Sammlung von Statusmenüelementen an, die dem Benutzer Interaktion mit oder Feedback bieten, z. B. ein Menü oder ein Bild, das den Zustand einer Anwendung widerspiegelt. Das Statusleistenmenü einer Anwendung ist aktiviert und aktiv, auch wenn die Anwendung im Hintergrund ausgeführt wird. Die systemweite Statusleiste befindet sich auf der rechten Seite der Anwendungsmenüleiste und ist die einzige Statusleiste, die derzeit in macOS verfügbar ist.

Lassen Sie uns unsere AppDelegate.cs Datei bearbeiten und die DidFinishLaunching Methode wie folgt aussehen:

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; bietet uns Zugriff auf die systemweite Statusleiste. var item = statusBar.CreateStatusItem (NSStatusItemLength.Variable); erstellt ein neues Statusleistenelement. Von dort aus erstellen wir ein Menü und eine Reihe von Menüelementen und fügen das Menü an das soeben erstellte Statusleistenelement an.

Wenn die Anwendung ausgeführt wird, wird das neue Statusleistenelement angezeigt. Wenn Sie ein Element aus dem Menü auswählen, wird der Text in der Textansicht geändert:

The status bar menu running

Als Nächstes sehen wir uns das Erstellen von benutzerdefinierten Dockmenüelementen an.

Benutzerdefinierte Dockmenüs

Das Dockmenü wird für Die Mac-Anwendung angezeigt, wenn der Benutzer mit der rechten Maustaste klickt oder auf das Symbol der Anwendung im Dock klickt:

A custom dock menu

Erstellen wir nun ein benutzerdefiniertes Dockmenü für unsere Anwendung, indem wir Folgendes ausführen:

  1. Klicken Sie in Visual Studio für Mac mit der rechten Maustaste auf das Projekt der Anwendung, und wählen Sie "Neue Datei hinzufügen>" aus... Wählen Sie im Dialogfeld "Neue Datei" die Option "Xamarin.Mac>Empty Interface Definition" aus, verwenden Sie "DockMenu" für den Namen, und klicken Sie auf die Schaltfläche "Neu", um die neue DockMenu.xib-Datei zu erstellen:

    Adding an empty interface definition

  2. Doppelklicken Sie im Lösungspad auf die Datei DockMenu.xib, um sie zur Bearbeitung in Xcode zu öffnen. Erstellen eines neuen Menüs mit den folgenden Elementen: Adresse, Datum, Begrüßung und Signatur

    Laying out the UI

  3. Als Nächstes verbinden wir unsere neuen Menüelemente mit unseren vorhandenen Aktionen, die wir im Abschnitt "Menüs hinzufügen", "Bearbeiten" und "Löschen von Menüs" für unser benutzerdefiniertes Menü erstellt haben. Wechseln Sie zum Verbinden ion Inspector, und wählen Sie den ersten Responder in der Schnittstellenhierarchie aus. Scrollen Sie nach unten, und suchen Sie die phraseAddress: Aktion. Ziehen Sie eine Linie aus dem Kreis dieser Aktion auf das Menüelement "Adresse ":

    Dragging a line to the Address menu item.

  4. Wiederholen Sie diesen Vorgang für alle anderen Menüelemente, die sie an ihre entsprechenden Aktionen anfügen:

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

  5. Wählen Sie als Nächstes die Anwendung in der Schnittstellenhierarchie aus. Ziehen Sie im Verbinden ion Inspector eine Linie aus dem Kreis auf dem dockMenu Auslass in das soeben erstellte Menü:

    Dragging the wire up the outlet

  6. Speichern Sie Ihre Änderungen, und wechseln Sie zurück zu Visual Studio für Mac, um mit Xcode zu synchronisieren.

  7. Doppelklicken Sie auf die Datei "Info.plist ", um sie zur Bearbeitung zu öffnen:

    Editing the Info.plist file

  8. Klicken Sie unten auf dem Bildschirm auf die Registerkarte "Quelle ":

    Selecting the Source view

  9. Klicken Sie auf "Neuen Eintrag hinzufügen", klicken Sie auf die grüne Plusschaltfläche, legen Sie den Eigenschaftennamen auf "AppleDockMenu" und den Wert auf "DockMenu" fest (der Name unserer neuen XIB-Datei ohne die Erweiterung):

    Adding the DockMenu item

Wenn wir nun unsere Anwendung ausführen und mit der rechten Maustaste auf das Symbol im Dock klicken, werden unsere neuen Menüelemente angezeigt:

An example of the dock menu running

Wenn wir eines der benutzerdefinierten Elemente aus dem Menü auswählen, wird der Text in unserer Textansicht geändert.

Popupschaltfläche und Pulldownlisten

Eine Popupschaltfläche zeigt ein ausgewähltes Element an und zeigt eine Liste der Optionen an, aus denen Sie auswählen können, wenn der Benutzer darauf klickt. Eine Pulldownliste ist eine Art Popupschaltfläche, die normalerweise zum Auswählen von Befehlen verwendet wird, die für den Kontext der aktuellen Aufgabe spezifisch sind. Beide können an einer beliebigen Stelle in einem Fenster angezeigt werden.

Erstellen wir nun eine benutzerdefinierte Popupschaltfläche für unsere Anwendung, indem wir Folgendes ausführen:

  1. Bearbeiten Sie die Datei "Main.storyboard" in Xcode, und ziehen Sie eine Popupschaltfläche aus dem Bibliotheksinspektor in das Fenster "Panel", das wir im Abschnitt "Kontextmenüs" erstellt haben:

    Adding a popup button

  2. Hinzufügen eines neuen Menüelements und Festlegen der Titel der Elemente im Popup auf: Adresse, Datum, Begrüßung und Signatur

    Configuring the menu items

  3. Als Nächstes verbinden wir unsere neuen Menüelemente mit den vorhandenen Aktionen, die wir im Abschnitt "Menüs hinzufügen", "Bearbeiten" und "Löschen von Menüs" für unser benutzerdefiniertes Menü erstellt haben. Wechseln Sie zum Verbinden ion Inspector, und wählen Sie den ersten Responder in der Schnittstellenhierarchie aus. Scrollen Sie nach unten, und suchen Sie die phraseAddress: Aktion. Ziehen Sie eine Linie aus dem Kreis dieser Aktion auf das Menüelement "Adresse ":

    Dragging to wire up an action

  4. Wiederholen Sie diesen Vorgang für alle anderen Menüelemente, die sie an ihre entsprechenden Aktionen anfügen:

    All required actions

  5. Speichern Sie Ihre Änderungen, und wechseln Sie zurück zu Visual Studio für Mac, um mit Xcode zu synchronisieren.

Wenn wir nun unsere Anwendung ausführen und ein Element aus dem Popup auswählen, ändert sich der Text in der Textansicht:

An example of the popup running

Sie können Pulldownlisten auf die gleiche Weise wie Popupschaltflächen erstellen und damit arbeiten. Anstatt an vorhandene Aktionen anzufügen, könnten Sie ihre eigenen benutzerdefinierten Aktionen wie für unser Kontextmenü im Abschnitt "Kontextmenüs " erstellen.

Zusammenfassung

Dieser Artikel hat einen detaillierten Blick auf die Arbeit mit Menüs und Menüelementen in einer Xamarin.Mac-Anwendung gemacht. Zuerst haben wir die Menüleiste der Anwendung untersucht, dann haben wir uns mit dem Erstellen von Kontextmenüs befasst, als Nächstes haben wir Statusleistenmenüs und benutzerdefinierte Dockmenüs untersucht. Schließlich wurden Popupmenüs und Pulldownlisten behandelt.