Windows in Xamarin.Mac
In diesem Artikel wird die Arbeit mit Fenstern und Panels in einer Xamarin.Mac-Anwendung behandelt. Es beschreibt das Erstellen von Fenstern und Panels im Xcode- und Schnittstellen-Generator, das Laden aus Storyboards und XIB-Dateien und die programmgesteuerte Arbeit mit ihnen.
Wenn Sie mit C# und .NET in einer Xamarin.Mac-Anwendung arbeiten, haben Sie Zugriff auf dasselbe Windows und dieselben Panels, 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 Windows und Panels zu erstellen und zu verwalten (oder optional direkt in C#-Code zu erstellen).
Basierend auf ihrem Zweck kann eine Xamarin.Mac-Anwendung ein oder mehrere Windows auf dem Bildschirm präsentieren, um die angezeigten Informationen zu verwalten und zu koordinieren und damit zu arbeiten. Die Hauptfunktionen eines Fensters sind:
- Um einen Bereich bereitzustellen, in dem Ansichten und Steuerelemente platziert und verwaltet werden können.
- Um Ereignisse als Reaktion auf Benutzerinteraktionen sowohl mit der Tastatur als auch mit der Maus anzunehmen und darauf zu reagieren.
Windows kann in einem Moduslosen Zustand verwendet werden (z. B. ein Text-Editor, der mehrere Dokumente gleichzeitig geöffnet haben kann) oder modal (z. B. ein Dialogfeld "Exportieren", das geschlossen werden muss, bevor die Anwendung fortgesetzt werden kann).
Panels sind eine spezielle Art von Window (eine Unterklasse der Basisklasse NSWindow
), die in der Regel eine Hilfsfunktion in einer Anwendung bedient, z. B. Hilfsfenster wie Textformatinspektoren und Systemfarbauswahl.
In diesem Artikel werden die Grundlagen der Arbeit mit Windows und Panels in einer Xamarin.Mac-Anwendung behandelt. 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 Verfügbarmachen von C#-Klassen /-Methoden im Objective-CAbschnitt des Xamarin.Mac Internals-Dokuments ansehen, und es werden die befehle Export
erläutert, die Register
zum Verketten Ihrer C#-Klassen mit Objective-C Objekten und UI-Elementen verwendet werden.
Einführung in Fenster
Wie oben erwähnt, bietet ein Fenster einen Bereich, in dem Ansichten und Steuerelemente platziert und verwaltet werden können und auf Ereignisse basierend auf Benutzerinteraktionen (entweder über Tastatur oder Maus) reagiert.
Laut Apple gibt es fünf Haupttypen von Windows in einer macOS-App:
- Dokumentfenster – Ein Dokumentfenster enthält dateibasierte Benutzerdaten wie z. B. eine Kalkulationstabelle oder ein Textdokument.
- App-Fenster – Ein App-Fenster ist das Hauptfenster einer Anwendung, die nicht dokumentbasiert ist (z. B. die Kalender-App auf einem Mac).
- Panel – Ein Panel wird über anderen Fenstern schwebt und stellt Tools oder Steuerelemente bereit, mit denen Benutzer arbeiten können, während Dokumente geöffnet sind. In einigen Fällen kann ein Panel transluzent sein (z. B. beim Arbeiten mit großen Grafiken).
- Dialogfeld – Ein Dialogfeld wird als Reaktion auf eine Benutzeraktion angezeigt und bietet in der Regel Möglichkeiten, wie Benutzer die Aktion ausführen können. Ein Dialogfeld erfordert eine Antwort des Benutzers, bevor es geschlossen werden kann. (Siehe Arbeiten mit Dialogfeldern)
- Warnungen – Eine Warnung ist ein spezieller Dialogfeldtyp, der angezeigt wird, wenn ein schwerwiegendes Problem auftritt (z. B. ein Fehler) oder als Warnung (z. B. das Vorbereiten des Löschens einer Datei). Da es sich bei einer Warnung um ein Dialogfeld handelt, ist auch eine Benutzerantwort erforderlich, bevor sie geschlossen werden kann. (Siehe Arbeiten mit Warnungen)
Weitere Informationen finden Sie im Abschnitt "Informationen zu Windows" der MacOS-Designdesigns von Apple.
Haupt-, Schlüssel- und inaktive Fenster
Windows in einer Xamarin.Mac-Anwendung kann anders aussehen und verhalten, je nachdem, wie der Benutzer derzeit mit ihnen interagiert. Das wichtigste Dokument- oder App-Fenster, das derzeit den Fokus der Aufmerksamkeit des Benutzers hat, wird als Hauptfenster bezeichnet. In den meisten Fällen ist dieses Fenster auch das Schlüsselfenster (das Fenster, das derzeit Benutzereingaben akzeptiert). Dies ist jedoch nicht immer der Fall, z. B. könnte eine Farbauswahl geöffnet sein und das Schlüsselfenster sein, mit dem der Benutzer interagiert, um den Status eines Elements im Dokumentfenster zu ändern (was weiterhin das Hauptfenster wäre).
Haupt- und Schlüsselfenster (sofern sie getrennt sind) sind immer aktiv, inaktive Windows sind geöffnete Fenster, die sich nicht im Vordergrund befinden. Beispielsweise könnte eine Text-Editor-Anwendung mehrere Dokumente gleichzeitig geöffnet haben, nur das Hauptfenster wäre aktiv, alle anderen wären inaktiv.
Weitere Informationen finden Sie im Abschnitt "Informationen zu Windows" der MacOS-Designdesigns von Apple.
Benennen von Fenstern
Ein Fenster kann eine Titelleiste anzeigen und wenn der Titel angezeigt wird, ist es in der Regel der Name der Anwendung, der Name des Dokuments, an dem gearbeitet wird, oder die Funktion des Fensters (z. B. Inspektor). Einige Anwendungen zeigen keine Titelleiste an, da sie erkennbar sind und nicht mit Dokumenten funktionieren.
Apple schlägt die folgenden Richtlinien vor:
- Verwenden Sie den Anwendungsnamen für den Titel eines Hauptfensters, das kein Dokument ist.
- Nennen Sie ein neues Dokumentfenster
untitled
. Fügen Sie für das erste neue Dokument keine Nummer an den Titel an (z. Buntitled 1
. ). Wenn der Benutzer vor dem Speichern und Titieren des ersten Dokuments ein weiteres neues Dokument erstellt, rufen Sie dieses Fensteruntitled 2
,untitled 3
usw. auf.
Weitere Informationen finden Sie im Abschnitt "Benennen von Windows" der macOS-Designdesigns von Apple.
Vollbildfenster
In macOS kann das Fenster einer Anwendung im Vollbildmodus alles ausblenden, einschließlich der Anwendungsmenüleiste (die durch Bewegen des Cursors an den oberen Rand des Bildschirms eingeblendet werden kann), um eine ablenkende interaktion mit dem Inhalt zu ermöglichen.
Apple schlägt die folgenden Richtlinien vor:
- Bestimmen Sie, ob es sinnvoll ist, dass ein Fenster im Vollbildmodus angezeigt wird. Anwendungen, die kurze Interaktionen (z. B. einen Rechner) bereitstellen, sollten keinen Vollbildmodus bereitstellen.
- Zeigen Sie die Symbolleiste an, wenn die Vollbildaufgabe dies erfordert. In der Regel ist die Symbolleiste ausgeblendet, während sie sich im Vollbildmodus befindet.
- Das Vollbildfenster sollte alle Features aufweisen, die Benutzer benötigen, um die Aufgabe abzuschließen.
- Vermeiden Sie nach Möglichkeit die Finder-Interaktion, während sich der Benutzer in einem Vollbildfenster befindet.
- Nutzen Sie den erweiterten Bildschirmbereich, ohne den Fokus von der Hauptaufgabe weg zu verschieben.
Weitere Informationen finden Sie im Abschnitt "Windows Im Vollbildmodus" der macOS-Designdesigndesigns von Apple.
Panels
Ein Panel ist ein Hilfsfenster, das Steuerelemente und Optionen enthält, die sich auf das aktive Dokument oder die Auswahl auswirken (z. B. die Systemfarbauswahl):
Panels können app-spezifisch oder systemweit sein. App-spezifische Panels werden über dem oberen Rand der Dokumentfenster der Anwendung angezeigt und verschwinden, wenn sich die Anwendung im Hintergrund befindet. Systemweite Panels (z. B. der Schriftartenbereich ) werden unabhängig von der Anwendung über allen geöffneten Fenstern schweben.
Apple schlägt die folgenden Richtlinien vor:
- Im Allgemeinen sollten transparente Panels nur sparsam und grafisch intensiv verwendet werden.
- Erwägen Sie die Verwendung eines Panels, um Benutzern einfachen Zugriff auf wichtige Steuerelemente oder Informationen zu ermöglichen, die sich direkt auf ihre Aufgabe auswirken.
- Blenden Sie Panels nach Bedarf aus, und zeigen Sie sie an.
- Panels sollten immer Titelleisten enthalten.
- Panels sollten keine aktive Minimierungsschaltfläche enthalten.
Inspektoren
Die meisten modernen macOS-Anwendungen enthalten Hilfssteuerelemente und -optionen, die sich auf das aktive Dokument oder die Auswahl als Inspektoren auswirken, die Teil des Hauptfensters sind (wie die unten gezeigte Seiten-App ), anstatt Panel-Windows zu verwenden:
Weitere Informationen finden Sie im Abschnitt "Panels" der macOS-Designdesigndesigns von Apple.
Erstellen und Verwalten von Fenstern in Xcode
Wenn Sie eine neue Xamarin.Mac Cocoa-Anwendung erstellen, erhalten Sie standardmäßig ein standardmäßig leeres Fenster. Diese Fenster werden in einer .storyboard
Datei definiert, die automatisch im Projekt enthalten ist. Doppelklicken Sie zum Bearbeiten des Fensterentwurfs im Projektmappen-Explorer auf die Main.storyboard
Datei:
Dadurch wird das Fensterdesign im Schnittstellen-Generator von Xcode geöffnet:
Im Attributinspektor gibt es mehrere Eigenschaften, mit denen Sie Das Fenster definieren und steuern können:
- Titel – Dies ist der Text, der in der Titelleiste des Fensters angezeigt wird.
- AutoSpeichern – Dies ist der Schlüssel , der verwendet wird, um das Fenster zu idieren, wenn es sich um Position und Einstellungen handelt, die automatisch gespeichert werden.
- Titelleiste – Zeigt das Fenster eine Titelleiste an.
- Einheitlicher Titel und Symbolleiste – Wenn das Fenster eine Symbolleiste enthält, sollte es Teil der Titelleiste sein.
- Inhaltsansicht in voller Größe – Ermöglicht die Anzeige des Inhaltsbereichs des Fensters unter der Titelleiste.
- Schatten – Hat das Fenster einen Schatten.
- Texturen - Texturfenster können Effekte (z. B. Vibranz) verwenden und durch Ziehen an eine beliebige Stelle im Körper verschoben werden.
- Schließen – Verfügt das Fenster über eine Schaltfläche zum Schließen.
- Minimieren – Verfügt das Fenster über eine Schaltfläche zum Minimieren.
- Ändern der Größe – Verfügt das Fenster über ein Steuerelement zum Ändern der Größe.
- Symbolleistenschaltfläche – Verfügt das Fenster über eine Schaltfläche zum Ausblenden/Anzeigen der Symbolleiste.
- Wiederherstellbar – Ist die Position und Einstellungen des Fensters automatisch gespeichert und wiederhergestellt.
- Beim Start sichtbar – Wird das Fenster automatisch angezeigt, wenn die
.xib
Datei geladen wird. - Beim Deaktivieren ausblenden – Ist das Fenster ausgeblendet, wenn die Anwendung in den Hintergrund wechselt.
- Beim Schließen freigeben – Wird das Fenster aus dem Arbeitsspeicher gelöscht, wenn es geschlossen wird.
- QuickInfos immer anzeigen – Werden die QuickInfos ständig angezeigt.
- Berechnet die Ansichtsschleife neu – Wird die Ansichtsreihenfolge neu berechnet, bevor das Fenster gezeichnet wird.
- Räume, Exposé und Radfahren – Alle definieren, wie sich das Fenster in diesen macOS-Umgebungen verhält.
- Vollbild – Bestimmt, ob dieses Fenster in den Vollbildmodus wechseln kann.
- Animation – Steuert den Für das Fenster verfügbaren Animationstyp.
- Darstellung – Steuert die Darstellung des Fensters. Für jetzt gibt es nur ein Erscheinungsbild, Aqua.
Weitere Details finden Sie in der Apple-Dokumentation "Einführung in Windows " und "NSWindow ".
Festlegen der Standardgröße und -position
Um die Anfangsposition des Fensters festzulegen und die Größe zu steuern, wechseln Sie zum Größeninspektor:
Von hier aus können Sie die Anfangsgröße des Fensters festlegen, ihm eine minimale und maximale Größe zugeben, die anfängliche Position auf dem Bildschirm festlegen und die Rahmen um das Fenster steuern.
Festlegen eines benutzerdefinierten Hauptfenstercontrollers
Um Outlets und Aktionen erstellen zu können, um UI-Elemente für C#-Code verfügbar zu machen, muss die Xamarin.Mac-App einen benutzerdefinierten Fenstercontroller verwenden.
Gehen Sie folgendermaßen vor:
Öffnen Sie das Storyboard der App im Schnittstellen-Generator von Xcode.
Wählen Sie das
NSWindowController
Design-Surface aus.Wechseln Sie zur Ansicht "Identitätsinspektor", und geben Sie
WindowController
als Klassenname ein:Speichern Sie Ihre Änderungen, und kehren Sie zum synchronisierenden Visual Studio für Mac zurück.
WindowController.cs
In Visual Studio für Mac wird Ihrem Projekt eine Datei im Projektmappen-Explorer hinzugefügt:Öffnen Sie das Storyboard im Schnittstellen-Generator von Xcode erneut.
Die
WindowController.h
Datei steht zur Verwendung zur Verfügung:
Hinzufügen von UI-Elementen
Um den Inhalt eines Fensters zu definieren, ziehen Sie Steuerelemente aus dem Bibliotheksinspektor auf den Schnittstellen-Editor. Weitere Informationen zur Verwendung des Schnittstellen-Generators zum Erstellen und Aktivieren von Steuerelementen finden Sie in unserer Dokumentation zur Einführung in Xcode und Schnittstellen-Generator .
Als Beispiel ziehen wir eine Symbolleiste aus dem Bibliotheksinspektor in das Fenster im Schnittstellen-Editor:
Ziehen Sie als Nächstes in eine Textansicht , und skalieren Sie ihn, um den Bereich unter der Symbolleiste auszufüllen:
Da die Textansicht verkleinern und wachsen soll, während sich die Größe des Fensters ändert, wechseln wir zum Einschränkungs-Editor , und fügen Sie die folgenden Einschränkungen hinzu:
Wenn Sie oben im Editor auf die vier roten I-Balken klicken und auf "4 Einschränkungen hinzufügen" klicken, teilen wir der Textansicht mit, dass sie sich an den angegebenen X,Y-Koordinaten halten und horizontal und vertikal verkleinern, während die Größe des Fensters geändert wird.
Machen Sie schließlich die Textansicht mit einem Outlet für Code verfügbar (stellen Sie sicher, dass Sie die ViewController.h
Datei auswählen):
Speichern Sie Ihre Änderungen, und wechseln Sie zurück zu Visual Studio für Mac, um mit Xcode zu synchronisieren.
Weitere Informationen zum Arbeiten mit Outlets und Aktionen finden Sie in unserer Outlet- und Action-Dokumentation.
Standardfensterworkflow
Für jedes Fenster, mit dem Sie in Ihrer Xamarin.Mac-Anwendung arbeiten, ist der Prozess im Grunde identisch mit dem, was wir gerade oben gemacht haben:
- Fügen Sie für neue Fenster, die dem Projekt nicht automatisch hinzugefügt werden, eine neue Fensterdefinition zum Projekt hinzu. Dies wird im Folgenden ausführlich erläutert.
- Doppelklicken Sie auf die
Main.storyboard
Datei, um das Fensterdesign zur Bearbeitung im Benutzeroberflächen-Generator von Xcode zu öffnen. - Ziehen Sie ein neues Fenster in das Design der Benutzeroberfläche, und verbinden Sie das Fenster mithilfe von Segues in das Hauptfenster (weitere Informationen finden Sie im Abschnitt "Segues" unserer Dokumentation "Arbeiten mit Storyboards").
- Legen Sie alle erforderlichen Fenstereigenschaften im Attributinspektor und im Größeninspektor fest.
- Ziehen Sie das Shape in die Steuerelemente, die zum Erstellen der Benutzeroberfläche erforderlich sind, und konfigurieren Sie sie im Attributinspektor.
- Verwenden Sie den Größeninspektor , um die Größenänderung für Ihre UI-Elemente zu behandeln.
- Machen Sie die UI-Elemente des Fensters über Outlets und Aktionen für C#-Code verfügbar.
- Speichern Sie Ihre Änderungen, und wechseln Sie zurück zu Visual Studio für Mac, um mit Xcode zu synchronisieren.
Nachdem wir nun ein einfaches Fenster erstellt haben, werden wir uns die typischen Prozesse ansehen, die eine Xamarin.Mac-Anwendung beim Arbeiten mit Fenstern ausführt.
Anzeigen des Standardfensters
Standardmäßig zeigt eine neue Xamarin.Mac-Anwendung automatisch das Fenster an, das beim Starten in der MainWindow.xib
Datei definiert ist:
Da wir den Entwurf dieses Fensters oben geändert haben, enthält es jetzt ein Standardmäßiges Symbolleisten- und Textansichtssteuerelement . Der folgende Abschnitt in der Datei ist für die Info.plist
Anzeige dieses Fensters verantwortlich:
Das Dropdownmenü "Hauptschnittstelle " wird verwendet, um das Storyboard auszuwählen, das als Haupt-App-UI (in diesem Fall Main.storyboard
) verwendet wird.
Dem Projekt wird automatisch ein Ansichtscontroller hinzugefügt, um das angezeigte Hauptfenster (zusammen mit der primären Ansicht) zu steuern. Sie wird in der ViewController.cs
Datei definiert und dem Besitzer der Datei im Schnittstellen-Generator unter dem Identitätsinspektor angefügt:
Für unser Fenster möchten wir, dass es beim ersten Öffnen einen Titel untitled
hat, damit wir die Methode in der ViewWillAppear
ViewController.cs
folgenden Abbildung überschreiben:
public override void ViewWillAppear ()
{
base.ViewWillAppear ();
// Set Window Title
this.View.Window.Title = "untitled";
}
Hinweis
Die Eigenschaft des Fensters Title
wird in der ViewWillAppear
Methode anstelle der ViewDidLoad
Methode festgelegt, da die Ansicht zwar in den Arbeitsspeicher geladen wird, aber noch nicht vollständig instanziiert wird. Der Zugriff auf die Title
Eigenschaft in der ViewDidLoad
Methode wird eine null
Ausnahme erhalten, da das Fenster noch nicht erstellt und mit der Eigenschaft verkabelt wurde.
Programmgesteuertes Schließen eines Fensters
Es kann vorkommen, dass Sie ein Fenster programmgesteuert in einer Xamarin.Mac-Anwendung schließen möchten, außer dass der Benutzer auf die Schaltfläche "Schließen" des Fensters oder ein Menüelement klickt. macOS bietet zwei verschiedene Möglichkeiten zum programmgesteuerten Schließen eines NSWindow
Programms: PerformClose
und Close
.
PerformClose
Durch Aufrufen der PerformClose
Methode eines Elements NSWindow
wird simuliert, dass der Benutzer auf die Schaltfläche "Schließen" des Fensters klickt, indem er die Schaltfläche im Moment hervorhebt und dann das Fenster schließt.
Wenn die Anwendung das NSWindow
WillClose
Ereignis implementiert, wird es ausgelöst, bevor das Fenster geschlossen wird. Wenn das Ereignis zurückgegeben false
wird, wird das Fenster nicht geschlossen. Wenn das Fenster nicht über eine Schaltfläche "Schließen " verfügt oder aus irgendeinem Grund nicht geschlossen werden kann, gibt das Betriebssystem den Benachrichtigungssound aus.
Zum Beispiel:
MyWindow.PerformClose(this);
Würde versuchen, die MyWindow
NSWindow
Instanz zu schließen. Wenn dies erfolgreich war, wird das Fenster geschlossen, andernfalls wird der Benachrichtigungssound ausgegeben und bleibt geöffnet.
Abschließen
Wenn Sie die Close
Methode einer Methode aufrufenNSWindow
, wird der Benutzer nicht simuliert, auf die Schaltfläche "Schließen" des Fensters zu klicken, indem er die Schaltfläche im Moment hervorhebt, das Fenster wird einfach geschlossen.
Ein Fenster muss nicht sichtbar sein, um geschlossen zu werden, und eine NSWindowWillCloseNotification
Benachrichtigung wird für das geschlossene Fenster im Standardbenachrichtigungscenter veröffentlicht.
Die Close
Methode unterscheidet sich auf zwei wichtige Arten von der PerformClose
Methode:
- Es wird nicht versucht, das
WillClose
Ereignis auszuheben. - Es simuliert nicht, dass der Benutzer auf die Schaltfläche "Schließen " klickt, indem er die Schaltfläche im Moment hervorhebung.
Zum Beispiel:
MyWindow.Close();
Würde die MyWindow
NSWindow
Instanz schließen.
Geänderter Fensterinhalt
In macOS hat Apple eine Möglichkeit bereitgestellt, den Benutzer darüber zu informieren, dass der Inhalt eines Fensters (NSWindow
) vom Benutzer geändert wurde und gespeichert werden muss. Wenn das Fenster geänderten Inhalt enthält, wird ein kleiner schwarzer Punkt im "Schließen"-Widget angezeigt:
Wenn der Benutzer versucht, das Fenster zu schließen oder die Mac-App zu beenden, während nicht gespeicherte Änderungen am Inhalt des Fensters vorhanden sind, sollten Sie ein Dialogfeld oder ein modales Blatt präsentieren und dem Benutzer erlauben, seine Änderungen zuerst zu speichern:
Markieren eines Fensters als geändert
Verwenden Sie den folgenden Code, um ein Fenster als geänderten Inhalt zu markieren:
// Mark Window content as modified
Window.DocumentEdited = true;
Und nachdem die Änderung gespeichert wurde, löschen Sie das geänderte Flag mit:
// Mark Window content as not modified
Window.DocumentEdited = false;
Speichern von Änderungen vor dem Schließen eines Fensters
Um zu beobachten, ob der Benutzer ein Fenster schließt und ihm das Speichern von geänderten Inhalten im Voraus zulässt, müssen Sie eine Unterklasse von NSWindowDelegate
und überschreiben deren WindowShouldClose
Methode. Zum Beispiel:
using System;
using AppKit;
using System.IO;
using Foundation;
namespace SourceWriter
{
public class EditorWindowDelegate : NSWindowDelegate
{
#region Computed Properties
public NSWindow Window { get; set;}
#endregion
#region constructors
public EditorWindowDelegate (NSWindow window)
{
// Initialize
this.Window = window;
}
#endregion
#region Override Methods
public override bool WindowShouldClose (Foundation.NSObject sender)
{
// is the window dirty?
if (Window.DocumentEdited) {
var alert = new NSAlert () {
AlertStyle = NSAlertStyle.Critical,
InformativeText = "Save changes to document before closing window?",
MessageText = "Save Document",
};
alert.AddButton ("Save");
alert.AddButton ("Lose Changes");
alert.AddButton ("Cancel");
var result = alert.RunSheetModal (Window);
// Take action based on result
switch (result) {
case 1000:
// Grab controller
var viewController = Window.ContentViewController as ViewController;
// Already saved?
if (Window.RepresentedUrl != null) {
var path = Window.RepresentedUrl.Path;
// Save changes to file
File.WriteAllText (path, viewController.Text);
return true;
} else {
var dlg = new NSSavePanel ();
dlg.Title = "Save Document";
dlg.BeginSheet (Window, (rslt) => {
// File selected?
if (rslt == 1) {
var path = dlg.Url.Path;
File.WriteAllText (path, viewController.Text);
Window.DocumentEdited = false;
viewController.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
viewController.View.Window.RepresentedUrl = dlg.Url;
Window.Close();
}
});
return true;
}
return false;
case 1001:
// Lose Changes
return true;
case 1002:
// Cancel
return false;
}
}
return true;
}
#endregion
}
}
Verwenden Sie den folgenden Code, um eine Instanz dieses Delegaten an das Fenster anzufügen:
// Set delegate
Window.Delegate = new EditorWindowDelegate(Window);
Speichern von Änderungen vor dem Schließen der App
Schließlich sollte Ihre Xamarin.Mac-App überprüfen, ob einer seiner Windows-Inhalte geänderten Inhalt enthält, und dem Benutzer das Speichern der Änderungen vor dem Beenden gestatten. Bearbeiten Sie dazu Die AppDelegate.cs
Datei, überschreiben Sie die ApplicationShouldTerminate
Methode, und stellen Sie sicher, dass sie wie folgt aussieht:
public override NSApplicationTerminateReply ApplicationShouldTerminate (NSApplication sender)
{
// See if any window needs to be saved first
foreach (NSWindow window in NSApplication.SharedApplication.Windows) {
if (window.Delegate != null && !window.Delegate.WindowShouldClose (this)) {
// Did the window terminate the close?
return NSApplicationTerminateReply.Cancel;
}
}
// Allow normal termination
return NSApplicationTerminateReply.Now;
}
Arbeiten mit mehreren Fenstern
Die meisten dokumentbasierten Mac-Anwendungen können mehrere Dokumente gleichzeitig bearbeiten. Ein Text-Editor kann z. B. mehrere Textdateien gleichzeitig zur Bearbeitung öffnen. Standardmäßig verfügt eine neue Xamarin.Mac-Anwendung über ein Menü "Datei ", bei dem ein neues Element automatisch mit der newDocument:
Aktion verkabelt wird.
Der folgende Code aktiviert dieses neue Element und ermöglicht es dem Benutzer, mehrere Kopien des Hauptfensters zu öffnen, um mehrere Dokumente gleichzeitig zu bearbeiten.
Bearbeiten Sie die AppDelegate.cs
Datei, und fügen Sie die folgende berechnete Eigenschaft hinzu:
public int UntitledWindowCount { get; set;} =1;
Verwenden Sie dies, um die Anzahl der nicht gespeicherten Dateien nachzuverfolgen, damit wir dem Benutzer Feedback geben können (gemäß den Richtlinien von Apple wie oben beschrieben).
Fügen Sie als Nächstes die folgende Methode hinzu:
[Export ("newDocument:")]
void NewDocument (NSObject sender) {
// Get new window
var storyboard = NSStoryboard.FromName ("Main", null);
var controller = storyboard.InstantiateControllerWithIdentifier ("MainWindow") as NSWindowController;
// Display
controller.ShowWindow(this);
// Set the title
controller.Window.Title = (++UntitledWindowCount == 1) ? "untitled" : string.Format ("untitled {0}", UntitledWindowCount);
}
Dieser Code erstellt eine neue Version unseres Fenstercontrollers, lädt das neue Fenster, macht es zum Haupt- und Schlüsselfenster und legt ihn zum Titel fest. Wenn wir nun unsere Anwendung ausführen und im Menü "Datei" die Option "Neu" auswählen, wird ein neues Editorfenster geöffnet und angezeigt:
Wenn wir das Windows-Menü öffnen, können Sie sehen, dass die Anwendung automatisch unsere geöffneten Fenster nachverfolgt und verarbeitet:
Weitere Informationen zum Arbeiten mit Menüs in einer Xamarin.Mac-Anwendung finden Sie in unserer Dokumentation zum Arbeiten mit Menüs .
Abrufen des aktuell aktiven Fensters
In einer Xamarin.Mac-Anwendung, die mehrere Fenster (Dokumente) öffnen kann, gibt es Zeiten, in denen Sie das aktuelle, oberste Fenster (das Schlüsselfenster) abrufen müssen. Der folgende Code gibt das Schlüsselfenster zurück:
var window = NSApplication.SharedApplication.KeyWindow;
Sie kann in einer beliebigen Klasse oder Methode aufgerufen werden, die auf das aktuelle Schlüsselfenster zugreifen muss. Wenn derzeit kein Fenster geöffnet ist, wird es zurückgegeben null
.
Zugreifen auf alle App-Fenster
Es kann vorkommen, dass Sie auf alle Fenster zugreifen müssen, die Ihre Xamarin.Mac-App derzeit geöffnet hat. Um beispielsweise festzustellen, ob eine Datei, die der Benutzer öffnen möchte, bereits in einem beendenden Fenster geöffnet ist.
Die NSApplication.SharedApplication
Verwaltet eine Windows
Eigenschaft, die ein Array aller geöffneten Fenster in Ihrer App enthält. Sie können dieses Array durchlaufen, um auf alle aktuellen Fenster der App zuzugreifen. Zum Beispiel:
// 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;
}
}
Im Beispielcode werden jedes zurückgegebene Fenster in die benutzerdefinierte Klasse in unserer App umgewandelt und der Wert einer benutzerdefinierten ViewController
Path
Eigenschaft anhand des Pfads einer Datei getestet, die der Benutzer öffnen möchte. Wenn die Datei bereits geöffnet ist, bringen wir dieses Fenster in den Vordergrund.
Anpassen der Fenstergröße im Code
Es gibt Zeiten, in denen die Anwendung die Größe eines Fensters im Code ändern muss. Zum Ändern der Größe und Neupositionierung eines Fensters passen Sie die Eigenschaft an Frame
. Beim Anpassen der Größe eines Fensters müssen Sie in der Regel auch den Ursprung anpassen, damit das Fenster aufgrund des Koordinatensystems von macOS an derselben Position bleibt.
Im Gegensatz zu iOS, in dem die obere linke Ecke steht (0,0), verwendet macOS ein mathematisches Koordinatensystem, in dem die untere linke Ecke des Bildschirms steht (0,0). In iOS erhöhen sich die Koordinaten, während Sie nach unten nach rechts navigieren. In macOS erhöhen sich die Koordinaten nach oben nach rechts.
Im folgenden Beispielcode wird die Größe eines Fensters geändert:
nfloat y = 0;
// Calculate new origin
y = Frame.Y - (768 - Frame.Height);
// Resize and position window
CGRect frame = new CGRect (Frame.X, y, 1024, 768);
SetFrame (frame, true);
Wichtig
Wenn Sie eine Fenstergröße und -position im Code anpassen, müssen Sie sicherstellen, dass Sie die mindesten und maximalen Größen berücksichtigen, die Sie im Schnittstellen-Generator festgelegt haben. Dies wird nicht automatisch berücksichtigt, und Sie können das Fenster größer oder kleiner machen als diese Grenzwerte.
Überwachen von Fenstergrößenänderungen
Es kann vorkommen, dass Sie Änderungen an der Größe eines Fensters in Ihrer Xamarin.Mac-App überwachen müssen. Um z. B. Inhalte neu zu zeichnen, um die neue Größe anzupassen.
Um Größenänderungen zu überwachen, stellen Sie zunächst sicher, dass Sie dem Fenstercontroller im Schnittstellen-Generator von Xcode eine benutzerdefinierte Klasse zugewiesen haben. Beispiel: MasterWindowController
Bearbeiten Sie als Nächstes die benutzerdefinierte Window Controller-Klasse, und überwachen Sie das DidResize
Ereignis im Fenster des Controllers, um über Änderungen der Livegröße benachrichtigt zu werden. Zum Beispiel:
public override void WindowDidLoad ()
{
base.WindowDidLoad ();
Window.DidResize += (sender, e) => {
// Do something as the window is being live resized
};
}
Optional können Sie das DidEndLiveResize
Ereignis verwenden, um nur benachrichtigt zu werden, nachdem der Benutzer die Änderung der Fenstergröße abgeschlossen hat. Beispiel:
public override void WindowDidLoad ()
{
base.WindowDidLoad ();
Window.DidEndLiveResize += (sender, e) => {
// Do something after the user's finished resizing
// the window
};
}
Festlegen des Titels und der dargestellten Datei eines Fensters
Wenn Sie mit Fenstern arbeiten, die Dokumente darstellen, weist eine DocumentEdited
Eigenschaft auf, die festgelegt ist, NSWindow
dass true
ein kleiner Punkt in der Schaltfläche "Schließen" angezeigt wird, um dem Benutzer einen Hinweis darauf zu geben, dass die Datei geändert wurde und vor dem Schließen gespeichert werden soll.
Lassen Sie uns unsere ViewController.cs
Datei bearbeiten und die folgenden Änderungen vornehmen:
public bool DocumentEdited {
get { return View.Window.DocumentEdited; }
set { View.Window.DocumentEdited = value; }
}
...
public override void ViewWillAppear ()
{
base.ViewWillAppear ();
// Set Window Title
this.View.Window.Title = "untitled";
View.Window.WillClose += (sender, e) => {
// is the window dirty?
if (DocumentEdited) {
var alert = new NSAlert () {
AlertStyle = NSAlertStyle.Critical,
InformativeText = "We need to give the user the ability to save the document here...",
MessageText = "Save Document",
};
alert.RunModal ();
}
};
}
public override void AwakeFromNib ()
{
base.AwakeFromNib ();
// Show when the document is edited
DocumentEditor.TextDidChange += (sender, e) => {
// Mark the document as dirty
DocumentEdited = true;
};
// Overriding this delegate is required to monitor the TextDidChange event
DocumentEditor.ShouldChangeTextInRanges += (NSTextView view, NSValue[] values, string[] replacements) => {
return true;
};
}
Außerdem überwachen wir das WillClose
Ereignis im Fenster und überprüfen den Status der DocumentEdited
Eigenschaft. Wenn es erforderlich ist true
, dem Benutzer die Möglichkeit zu geben, die Änderungen in der Datei zu speichern. Wenn wir unsere App ausführen und Text eingeben, wird der Punkt angezeigt:
Wenn Sie versuchen, das Fenster zu schließen, erhalten Sie eine Benachrichtigung:
Wenn Sie ein Dokument aus einer Datei laden, legen Sie den Titel des Fensters mithilfe der window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
Methode auf den Namen der Datei fest (vorausgesetzt, es handelt sich um eine Zeichenfolge, path
die die geöffnete Datei darstellt). Darüber hinaus können Sie die URL der Datei mithilfe der window.RepresentedUrl = url;
Methode festlegen.
Wenn die URL auf einen dateityp zeigt, der vom Betriebssystem bekannt ist, wird das Symbol in der Titelleiste angezeigt. Wenn der Benutzer mit der rechten Maustaste auf das Symbol klickt, wird der Pfad zur Datei angezeigt.
Bearbeiten Sie die AppDelegate.cs
Datei, und fügen Sie die folgende Methode hinzu:
[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) {
var path = url.Path;
// 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.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
viewController.View.Window.RepresentedUrl = url;
}
}
}
Wenn wir nun unsere App ausführen, wählen Sie im Menü "Datei" die Option "Öffnen" aus, wählen Sie im Dialogfeld "Öffnen" eine Textdatei aus, und öffnen Sie sie:
Die Datei wird angezeigt, und der Titel wird mit dem Symbol der Datei festgelegt:
Hinzufügen eines neuen Fensters zu einem Projekt
Neben dem Hauptdokumentfenster muss möglicherweise eine Xamarin.Mac-Anwendung dem Benutzer andere Fenstertypen anzeigen, z. B. Einstellungen oder Inspektorbereiche.
Gehen Sie wie folgt vor, um ein neues Fenster hinzuzufügen:
Doppelklicken Sie im Projektmappen-Explorer auf die
Main.storyboard
Datei, um sie zum Bearbeiten im Schnittstellen-Generator von Xcode zu öffnen.Ziehen Sie einen neuen Fenstercontroller aus der Bibliothek , und legen Sie ihn auf der Entwurfsoberfläche ab:
Geben Sie im Identitätsinspektor die Storyboard-ID
PreferencesWindow
ein:Entwerfen Sie Ihre Benutzeroberfläche:
Öffnen Sie das App-Menü (
MacWindows
), wählen Sie "Einstellungen" aus ..., klicken Sie mit gedrückter CTRL-TASTE, und ziehen Sie es in das neue Fenster:Wählen Sie im Popupmenü "Anzeigen" aus.
Speichern Sie Ihre Änderungen, und kehren Sie zu Visual Studio für Mac zurück, um mit Xcode zu synchronisieren.
Wenn wir den Code ausführen und im Anwendungsmenü die Einstellungen auswählen, wird das Fenster angezeigt:
Arbeiten mit Panels
Wie zu Beginn dieses Artikels erwähnt, wird ein Panel über anderen Fenstern angezeigt und stellt Tools oder Steuerelemente bereit, mit denen Benutzer arbeiten können, während Dokumente geöffnet sind.
Genau wie jeder andere Fenstertyp, mit dem Sie in Ihrer Xamarin.Mac-Anwendung arbeiten, ist der Prozess im Grunde identisch:
- Fügen Sie dem Projekt eine neue Fensterdefinition hinzu.
- Doppelklicken Sie auf die
.xib
Datei, um das Fensterdesign zur Bearbeitung im Benutzeroberflächen-Generator von Xcode zu öffnen. - Legen Sie alle erforderlichen Fenstereigenschaften im Attributinspektor und im Größeninspektor fest.
- Ziehen Sie das Shape in die Steuerelemente, die zum Erstellen der Benutzeroberfläche erforderlich sind, und konfigurieren Sie sie im Attributinspektor.
- Verwenden Sie den Größeninspektor , um die Größenänderung für Ihre UI-Elemente zu behandeln.
- Machen Sie die UI-Elemente des Fensters über Outlets und Aktionen für C#-Code verfügbar.
- Speichern Sie Ihre Änderungen, und wechseln Sie zurück zu Visual Studio für Mac, um mit Xcode zu synchronisieren.
Im Attributinspektor haben Sie die folgenden Speziellen Optionen für Panels:
- Formatvorlage – Ermöglicht Ihnen das Anpassen der Formatvorlage des Panels von: Regulärer Bereich (sieht wie ein Standardfenster aus), Hilfsprogrammbereich (hat eine kleinere Titelleiste), HUD-Panel (ist transluzent und die Titelleiste ist Teil des Hintergrunds).
- Nicht aktivieren – Bestimmt im Bereich wird zum Schlüsselfenster.
- Dokument modal – Wenn Dokument modal , wird der Bereich nur über den Fenstern der Anwendung schweben, sonst wird es vor allem schweben.
Gehen Sie wie folgt vor, um einen neuen Bereich hinzuzufügen:
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie "Neue Datei hinzufügen>" aus.
Wählen Sie im Dialogfeld "Neue Datei" die Option "Xamarin.Mac>Cocoa Window" mit Controller aus:
Geben Sie für den Namen
DocumentPanel
ein, und klicken Sie auf Neu.Doppelklicken Sie auf die
DocumentPanel.xib
Datei, um sie zum Bearbeiten im Schnittstellen-Generator zu öffnen:Löschen Sie das vorhandene Fenster, und ziehen Sie einen Bereich aus dem Bibliotheksinspektor im Schnittstellen-Editor:
Verbinden Sie den Bereich mit dem Fenster "Besitzer - " - der Datei:
Wechseln Sie zum Identitätsinspektor, und legen Sie die Klasse des Panels auf :
DocumentPanel
Speichern Sie Ihre Änderungen, und kehren Sie zu Visual Studio für Mac zurück, um mit Xcode zu synchronisieren.
Bearbeiten Sie die
DocumentPanel.cs
Datei, und ändern Sie die Klassendefinition wie folgt:public partial class DocumentPanel : NSPanel
Speichern Sie die Änderungen in der Datei.
Bearbeiten Sie die AppDelegate.cs
Datei, und stellen Sie sicher, dass die DidFinishLaunching
Methode wie folgt aussieht:
public override void DidFinishLaunching (NSNotification notification)
{
// Display panel
var panel = new DocumentPanelController ();
panel.Window.MakeKeyAndOrderFront (this);
}
Wenn wir unsere Anwendung ausführen, wird das Panel angezeigt:
Wichtig
Panel-Windows wurde von Apple veraltet und sollte durch Inspektorschnittstellen ersetzt werden.
Zusammenfassung
Dieser Artikel hat einen detaillierten Blick auf die Arbeit mit Windows und Panels in einer Xamarin.Mac-Anwendung gemacht. Wir haben die verschiedenen Typen und Verwendungen von Windows und Panels gesehen, wie Sie Windows und Panels im Schnittstellen-Generator von Xcode erstellen und verwalten und wie Sie mit Windows und Panels in C#-Code arbeiten.