Windows dans Xamarin.Mac
Cet article traite de l’utilisation des fenêtres et des panneaux dans une application Xamarin.Mac. Il décrit la création de fenêtres et de panneaux dans Xcode et Interface Builder, leur chargement à partir de storyboards et de fichiers .xib, et leur utilisation par programmation.
Lorsque vous utilisez C# et .NET dans une application Xamarin.Mac, vous avez accès aux mêmes Windows et panneaux qu’un développeur travaillant dans Objective-C et Xcode . Étant donné que Xamarin.Mac s’intègre directement à Xcode, vous pouvez utiliser le Générateur d’interface de Xcode pour créer et gérer vos Fenêtres et panneaux (ou éventuellement les créer directement en code C#).
En fonction de son objectif, une application Xamarin.Mac peut présenter un ou plusieurs Windows à l’écran pour gérer et coordonner les informations qu’elle affiche et utilise. Les fonctions principales d’une fenêtre sont les suivantes :
- Pour fournir une zone dans laquelle les vues et les contrôles peuvent être placés et gérés.
- Pour accepter et répondre aux événements en réponse à l’interaction de l’utilisateur avec le clavier et la souris.
Windows peut être utilisé dans un état sans mode (par exemple, un éditeur de texte qui peut avoir plusieurs documents ouverts à la fois) ou modal (par exemple, une boîte de dialogue Exporter qui doit être ignorée pour que l’application puisse continuer).
Les panneaux sont un type spécial de fenêtre (une sous-classe de la classe de base NSWindow
), qui sert généralement une fonction auxiliaire dans une application, telle que les fenêtres utilitaires telles que les inspecteurs de format texte et le sélecteur de couleurs système.
Dans cet article, nous allons aborder les principes fondamentaux de l’utilisation de Windows et de Panneaux dans une application Xamarin.Mac. Il est fortement recommandé de commencer par travailler sur l’article Hello, Mac , en particulier les sections Introduction to Xcode et Interface Builderet Outlets and Actions , car il couvre les concepts et techniques clés que nous allons utiliser dans cet article.
Vous pouvez également consulter la section Exposition des classes/méthodes C# du Objective-C document Xamarin.Mac Internals . Elle explique les commandes Register
et Export
utilisées pour relier vos classes C# à Objective-C des objets et des éléments d’interface utilisateur.
Présentation des fenêtres
Comme indiqué ci-dessus, une fenêtre fournit une zone dans laquelle les affichages et les contrôles peuvent être placés et gérés et répond aux événements en fonction de l’interaction de l’utilisateur (par le biais du clavier ou de la souris).
Selon Apple, il existe cinq types main de Windows dans une application macOS :
- Fenêtre de document : une fenêtre de document contient des données utilisateur basées sur des fichiers, telles qu’une feuille de calcul ou un document texte.
- Fenêtre d’application : une fenêtre d’application est la fenêtre main d’une application qui n’est pas basée sur un document (comme l’application Calendrier sur un Mac).
- Panneau : un panneau flotte au-dessus des autres fenêtres et fournit des outils ou des contrôles que les utilisateurs peuvent utiliser lorsque les documents sont ouverts. Dans certains cas, un panneau peut être translucide (par exemple quand vous travaillez avec des graphiques volumineux).
- Boîte de dialogue : une boîte de dialogue apparaît en réponse à une action de l’utilisateur et fournit généralement des moyens pour les utilisateurs d’effectuer l’action. Une boîte de dialogue nécessite une réponse de l’utilisateur avant de pouvoir être fermée. (Voir Utilisation des boîtes de dialogue)
- Alertes : une alerte est un type spécial de boîte de dialogue qui s’affiche lorsqu’un problème grave se produit (par exemple, une erreur) ou en tant qu’avertissement (par exemple, la préparation de la suppression d’un fichier). Étant donné qu’une alerte est une boîte de dialogue, elle nécessite également une réponse de l’utilisateur avant de pouvoir être fermée. (Voir Utilisation des alertes)
Pour plus d’informations, consultez la section À propos de Windows des thèmes de conception macOS d’Apple.
Fenêtres principales, à clé et inactives
Windows dans une application Xamarin.Mac peut se présenter et se comporter différemment en fonction de la façon dont l’utilisateur interagit actuellement avec eux. La fenêtre de document ou d’application la plus en tête qui est actuellement au centre de l’attention de l’utilisateur est appelée fenêtre principale. Dans la plupart des cas, cette fenêtre est également la fenêtre clé (la fenêtre qui accepte actuellement l’entrée utilisateur). Mais ce n’est pas toujours le cas, par exemple, un sélecteur de couleurs peut être ouvert et être la fenêtre Clé avec laquelle l’utilisateur interagit pour modifier l’état d’un élément dans la fenêtre de document (qui serait toujours la fenêtre principale).
Les fenêtres Main et Key (si elles sont séparées) sont toujours actives. Les fenêtres inactives sont des fenêtres ouvertes qui ne sont pas au premier plan. Par exemple, une application d’éditeur de texte peut avoir plusieurs documents ouverts à la fois, seule la fenêtre principale est active, toutes les autres sont inactives.
Pour plus d’informations, consultez la section À propos de Windows des thèmes de conception macOS d’Apple.
Nommage des fenêtres
Une fenêtre peut afficher une barre de titre et, lorsque le titre est affiché, il s’agit généralement du nom de l’application, du nom du document sur lequel l’on travaille ou de la fonction de la fenêtre (par exemple, Inspector). Certaines applications n’affichent pas de barre de titre, car elles sont reconnaissables par vue et ne fonctionnent pas avec des documents.
Apple suggère les recommandations suivantes :
- Utilisez le nom de votre application pour le titre d’une fenêtre main non-document.
- Nommez une nouvelle fenêtre
untitled
de document . Pour le premier nouveau document, n’ajoutez pas de nombre au titre (paruntitled 1
exemple). Si l’utilisateur crée un autre document avant d’enregistrer et de titiller le premier, appelez cette fenêtreuntitled 2
,untitled 3
, etc.
Pour plus d’informations, consultez la section Nommage Windows des thèmes de conception macOS d’Apple.
Fenêtres plein écran
Dans macOS, la fenêtre d’une application peut passer en plein écran en masquant tout, y compris la barre de menus de l’application (qui peut être révélée en déplaçant le curseur vers le haut de l’écran) pour fournir une interaction sans distraction avec son contenu.
Apple suggère les recommandations suivantes :
- Déterminez s’il est judicieux qu’une fenêtre passe en mode plein écran. Les applications qui fournissent de brèves interactions (comme une calculatrice) ne doivent pas fournir un mode plein écran.
- Affichez la barre d’outils si la tâche en plein écran l’exige. En général, la barre d’outils est masquée en mode plein écran.
- La fenêtre plein écran doit avoir toutes les fonctionnalités dont les utilisateurs ont besoin pour effectuer la tâche.
- Si possible, évitez d’interagir avec le Finder lorsque l’utilisateur est dans une fenêtre plein écran.
- Tirez parti de l’espace d’écran accru sans déplacer le focus de la tâche main.
Pour plus d’informations, consultez la section Windows plein écran des thèmes de conception macOS d’Apple.
Panneaux
Un panneau est une fenêtre auxiliaire qui contient des contrôles et des options qui affectent le document ou la sélection actif (par exemple, le sélecteur de couleurs système) :
Les panneaux peuvent être spécifiques à l’application ou à l’échelle du système. App-Specific Panneaux flottent au-dessus des fenêtres de document de l’application et disparaissent lorsque l’application est en arrière-plan. Les panneaux à l’échelle du système (tels que le panneau Polices ) flottent sur toutes les fenêtres ouvertes, quelle que soit l’application.
Apple suggère les recommandations suivantes :
- En général, utilisez un panneau standard, les panneaux transparents ne doivent être utilisés qu’avec parcimonie et pour les tâches gourmandes en graphiques.
- Envisagez d’utiliser un panneau pour permettre aux utilisateurs d’accéder facilement à des contrôles importants ou à des informations qui affectent directement leur tâche.
- Masquez et affichez les panneaux en fonction des besoins.
- Les panneaux doivent toujours inclure la barre de titre.
- Les panneaux ne doivent pas inclure de bouton de réduction actif.
Inspecteurs
La plupart des applications macOS modernes présentent des contrôles et des options auxiliaires qui affectent le document ou la sélection actif en tant qu’inspecteurs qui font partie de la fenêtre principale (comme l’application Pages ci-dessous), au lieu d’utiliser des fenêtres de panneau :
Pour plus d’informations, consultez la section Panneaux des thèmes de conception macOS d’Apple et notre exemple d’application MacInspector pour une implémentation complète d’une interface Inspector dans une application Xamarin.Mac.
Création et maintenance de fenêtres dans Xcode
Lorsque vous créez une application Xamarin.Mac Cocoa, vous obtenez une fenêtre vide standard par défaut. Cette fenêtre est définie dans un .storyboard
fichier automatiquement inclus dans le projet. Pour modifier la conception de vos fenêtres, dans le Explorateur de solutions, double-cliquez sur le Main.storyboard
fichier :
La conception de fenêtre s’ouvre dans le générateur d’interface de Xcode :
Dans l’inspecteur d’attributs, vous pouvez utiliser plusieurs propriétés pour définir et contrôler votre fenêtre :
- Titre : il s’agit du texte qui sera affiché dans la barre de titre de la fenêtre.
- Enregistrement automatique : il s’agit de la clé qui sera utilisée pour identifier la fenêtre lorsque sa position et ses paramètres sont automatiquement enregistrés.
- Barre de titre : la fenêtre affiche-t-elle une barre de titre.
- Titre et barre d’outils unifiés : si la fenêtre inclut une barre d’outils, doit-elle faire partie de la barre de titre.
- Affichage contenu de taille totale : permet à la zone de contenu de la fenêtre d’être sous la barre de titre.
- Ombre : la fenêtre a-t-elle une ombre.
- Texturé : les fenêtres texturées peuvent utiliser des effets (comme la vivacité) et peuvent être déplacées en faisant glisser n’importe où sur leur corps.
- Fermer : la fenêtre a-t-elle un bouton Fermer.
- Réduire : la fenêtre a-t-elle un bouton réduire.
- Redimensionner : la fenêtre a-t-elle un contrôle de redimensionnement.
- Bouton barre d’outils : la fenêtre a-t-elle un bouton masquer/afficher la barre d’outils.
- Restaurable : la position et les paramètres de la fenêtre sont-ils automatiquement enregistrés et restaurés.
- Visible au lancement : la fenêtre s’affiche-t-elle automatiquement lorsque le
.xib
fichier est chargé. - Masquer lors de la désactivation : la fenêtre est-elle masquée lorsque l’application entre en arrière-plan.
- Libérer quand elle est fermée : la fenêtre est-elle vidée de la mémoire lorsqu’elle est fermée.
- Toujours afficher les info-bulles : les info-bulles sont-elles affichées en permanence.
- Recalcule la boucle d’affichage : l’ordre d’affichage est-il recalculé avant le dessin de la fenêtre.
- Espaces, Exposé et Cycle : tous définissent le comportement de la fenêtre dans ces environnements macOS.
- Plein écran : détermine si cette fenêtre peut passer en mode plein écran.
- Animation : contrôle le type d’animation disponible pour la fenêtre.
- Apparence : contrôle l’apparence de la fenêtre. Pour l’instant, il n’y a qu’une seule apparence, Aqua.
Pour plus d’informations, consultez la documentation Présentation d’Apple sur Windows et NSWindow .
Définition de la taille et de l’emplacement par défaut
Pour définir la position initiale de votre fenêtre et contrôler sa taille, basculez vers l’inspecteur de taille :
À partir de là, vous pouvez définir la taille initiale de la fenêtre, lui donner une taille minimale et maximale, définir l’emplacement initial sur l’écran et contrôler les bordures autour de la fenêtre.
Définition d’un contrôleur de fenêtre de main personnalisé
Pour pouvoir créer des sorties et des actions afin d’exposer des éléments d’interface utilisateur au code C#, l’application Xamarin.Mac doit utiliser un contrôleur de fenêtre personnalisé.
Effectuez les actions suivantes :
Ouvrez le Storyboard de l’application dans le Générateur d’interface de Xcode.
Sélectionnez le
NSWindowController
dans l’Aire de conception.Basculez vers la vue Inspecteur d’identité et entrez
WindowController
comme Nom de la classe :Enregistrez vos modifications et revenez à Visual Studio pour Mac à synchroniser.
Un
WindowController.cs
fichier sera ajouté à votre projet dans le Explorateur de solutions de Visual Studio pour Mac :Rouvrez le storyboard dans le générateur d’interface de Xcode.
Le
WindowController.h
fichier sera disponible pour une utilisation :
Ajout d’éléments d’interface utilisateur
Pour définir le contenu d’une fenêtre, faites glisser les contrôles de l’inspecteur de bibliothèque vers l’éditeur d’interface. Consultez notre documentation Introduction à Xcode et Interface Builder pour plus d’informations sur l’utilisation d’Interface Builder pour créer et activer des contrôles.
Par exemple, faisons glisser une barre d’outils de l’inspecteur de bibliothèque vers la fenêtre de l’éditeur d’interface :
Ensuite, faites glisser un affichage texte et le dimensionner pour remplir la zone sous la barre d’outils :
Étant donné que nous voulons que l’affichage texte diminue et augmente à mesure que la taille de la fenêtre change, nous allons basculer vers l’éditeur de contraintes et ajouter les contraintes suivantes :
En cliquant sur les quatre faisceaux I rouges en haut de l’éditeur et en cliquant sur Ajouter 4 contraintes, nous disons à l’affichage de texte de s’en tenir aux coordonnées X,Y spécifiées et de croître ou de réduire horizontalement et verticalement à mesure que la fenêtre est redimensionnée.
Enfin, exposez l’affichage texte au code à l’aide d’un outlet (en veillant à sélectionner le ViewController.h
fichier) :
Enregistrez vos modifications et revenez à Visual Studio pour Mac pour synchroniser avec Xcode.
Pour plus d’informations sur l’utilisation des points de vente et des actions, consultez notre documentation outlet et action .
Flux de travail de fenêtre standard
Pour toutes les fenêtres que vous créez et utilisez dans votre application Xamarin.Mac, le processus est essentiellement le même que celui que nous venons de faire ci-dessus :
- Pour les nouvelles fenêtres qui ne sont pas ajoutées automatiquement par défaut à votre projet, ajoutez une nouvelle définition de fenêtre au projet. Cela sera abordé en détail ci-dessous.
- Double-cliquez sur le
Main.storyboard
fichier pour ouvrir la conception de fenêtre à modifier dans le Générateur d’interface de Xcode. - Faites glisser une nouvelle fenêtre dans la conception de l’interface utilisateur et raccordez la fenêtre à la fenêtre principale à l’aide de Segues (pour plus d’informations, consultez la section Segues de notre documentation Utilisation des storyboards ).
- Définissez toutes les propriétés de fenêtre requises dans l’inspecteur d’attribut et l’inspecteur de taille.
- Faites glisser les contrôles requis pour générer votre interface et configurez-les dans l’inspecteur d’attributs.
- Utilisez l’inspecteur de taille pour gérer le redimensionnement de vos éléments d’interface utilisateur.
- Exposez les éléments d’interface utilisateur de la fenêtre au code C# via des sorties et des actions.
- Enregistrez vos modifications et revenez à Visual Studio pour Mac pour synchroniser avec Xcode.
Maintenant que nous avons créé une fenêtre de base, nous allons examiner les processus typiques d’une application Xamarin.Mac quand vous utilisez windows.
Affichage de la fenêtre par défaut
Par défaut, une nouvelle application Xamarin.Mac affiche automatiquement la fenêtre définie dans le MainWindow.xib
fichier au démarrage :
Étant donné que nous avons modifié la conception de cette fenêtre ci-dessus, elle inclut désormais un contrôle Barre d’outils et Affichage de texte par défaut. La section suivante du Info.plist
fichier est chargée d’afficher cette fenêtre :
La liste déroulante Interface principale permet de sélectionner le storyboard qui sera utilisé comme interface utilisateur de l’application main (dans ce casMain.storyboard
).
Un contrôleur d’affichage est automatiquement ajouté au projet pour contrôler la fenêtre principale affichée (ainsi que son affichage principal). Il est défini dans le ViewController.cs
fichier et joint au propriétaire du fichier dans le générateur d’interface sous l’inspecteur d’identité :
Pour notre fenêtre, nous aimerions qu’elle ait un titre de untitled
lorsqu’elle s’ouvre pour la première fois. Nous allons donc remplacer la ViewWillAppear
méthode dans le ViewController.cs
pour ressembler à ce qui suit :
public override void ViewWillAppear ()
{
base.ViewWillAppear ();
// Set Window Title
this.View.Window.Title = "untitled";
}
Notes
La propriété de la Title
fenêtre est définie dans la ViewWillAppear
méthode plutôt que dans la ViewDidLoad
méthode , car, bien que la vue soit chargée en mémoire, elle n’est pas encore entièrement instanciée. En accédant à la Title
propriété dans la ViewDidLoad
méthode , nous obtiendrons une null
exception, car la fenêtre n’a pas encore été construite et connectée à la propriété.
Fermeture d’une fenêtre par programmation
Il peut arriver que vous souhaitiez fermer une fenêtre par programmation dans une application Xamarin.Mac, en dehors du fait que l’utilisateur clique sur le bouton Fermer de la fenêtre ou utilise un élément de menu. macOS offre deux façons différentes de fermer un NSWindow
par programmation : PerformClose
et Close
.
PerformClose
L’appel de la PerformClose
méthode d’un NSWindow
simule l’utilisateur qui clique sur le bouton Fermer de la fenêtre en mettant momentanément en surbrillance le bouton, puis en fermant la fenêtre.
Si l’application implémente l’événement NSWindow
de WillClose
, celui-ci est déclenché avant la fermeture de la fenêtre. Si l’événement retourne false
, la fenêtre ne sera pas fermée. Si la fenêtre n’a pas de bouton Fermer ou ne peut pas être fermée pour une raison quelconque, le système d’exploitation émet le son d’alerte.
Par exemple :
MyWindow.PerformClose(this);
Tenterait de fermer le MyWindow
NSWindow
instance. S’il réussit, la fenêtre est fermée, sinon le son d’alerte est émis et le reste ouvert.
Fermer
L’appel de la Close
méthode d’un NSWindow
ne simule pas que l’utilisateur clique sur le bouton Fermer de la fenêtre en mettant momentanément le bouton en surbrillance, il ferme simplement la fenêtre.
Une fenêtre n’a pas besoin d’être visible pour être fermée et une NSWindowWillCloseNotification
notification est publiée dans le Centre de notifications par défaut pour la fenêtre en cours de fermeture.
La Close
méthode diffère de deux manières importantes de la PerformClose
méthode :
- Il ne tente pas de déclencher l’événement
WillClose
. - Il ne simule pas que l’utilisateur clique sur le bouton Fermer en mettant momentanément le bouton en surbrillance.
Par exemple :
MyWindow.Close();
J’aimerais fermer le MyWindow
NSWindow
instance.
Contenu windows modifié
Dans macOS, Apple a fourni un moyen d’informer l’utilisateur que le contenu d’une fenêtre (NSWindow
) a été modifié par l’utilisateur et doit être enregistré. Si la fenêtre contient du contenu modifié, un petit point noir s’affiche dans son widget Fermer :
Si l’utilisateur tente de fermer la fenêtre ou de quitter l’application Mac alors qu’il y a des modifications non enregistrées dans le contenu de la fenêtre, vous devez présenter une boîte de dialogue ou une feuille modale et autoriser l’utilisateur à enregistrer d’abord ses modifications :
Marquage d’une fenêtre comme modifiée
Pour marquer une fenêtre comme ayant modifié le contenu, utilisez le code suivant :
// Mark Window content as modified
Window.DocumentEdited = true;
Et une fois la modification enregistrée, effacez l’indicateur modifié à l’aide de :
// Mark Window content as not modified
Window.DocumentEdited = false;
Enregistrement des modifications avant de fermer une fenêtre
Pour watch à l’utilisateur fermant une fenêtre et lui permettant d’enregistrer le contenu modifié au préalable, vous devez créer une sous-classe de NSWindowDelegate
et remplacer sa WindowShouldClose
méthode. Par exemple :
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
}
}
Utilisez le code suivant pour attacher un instance de ce délégué à la fenêtre :
// Set delegate
Window.Delegate = new EditorWindowDelegate(Window);
Enregistrement des modifications avant de fermer l’application
Enfin, votre application Xamarin.Mac doit case activée pour voir si l’une de ses fenêtres contient du contenu modifié et permettre à l’utilisateur d’enregistrer les modifications avant de quitter. Pour ce faire, modifiez votre AppDelegate.cs
fichier, remplacez la ApplicationShouldTerminate
méthode et faites-le ressembler à ce qui suit :
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;
}
Utilisation de plusieurs fenêtres
La plupart des applications Mac basées sur des documents peuvent modifier plusieurs documents en même temps. Par exemple, un éditeur de texte peut avoir plusieurs fichiers texte ouverts pour modification en même temps. Par défaut, une nouvelle application Xamarin.Mac a un menu Fichier avec un nouvel élément automatiquement connecté à l’actionnewDocument:
.
Le code ci-dessous active ce nouvel élément et permet à l’utilisateur d’ouvrir plusieurs copies de la fenêtre principale pour modifier plusieurs documents à la fois.
Modifiez le AppDelegate.cs
fichier et ajoutez la propriété calculée suivante :
public int UntitledWindowCount { get; set;} =1;
Utilisez-le pour suivre le nombre de fichiers non enregistrés afin que nous puissions envoyer des commentaires à l’utilisateur (conformément aux instructions d’Apple, comme indiqué ci-dessus).
Ensuite, ajoutez la méthode suivante :
[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);
}
Ce code crée une nouvelle version de notre contrôleur de fenêtre, charge la nouvelle fenêtre, en fait la fenêtre principale et la fenêtre clé et définit son titre. Maintenant, si nous exécutons notre application et que nous sélectionnons Nouveau dans le menu Fichier , une nouvelle fenêtre d’éditeur s’ouvre et s’affiche :
Si nous ouvrons le menu Windows , vous pouvez voir que l’application suit et gère automatiquement nos fenêtres ouvertes :
Pour plus d’informations sur l’utilisation des menus dans une application Xamarin.Mac, consultez notre documentation Utilisation des menus .
Obtention de la fenêtre active
Dans une application Xamarin.Mac qui peut ouvrir plusieurs fenêtres (documents), vous devez parfois obtenir la fenêtre la plus haute actuelle (la fenêtre clé). Le code suivant retourne la fenêtre de clé :
var window = NSApplication.SharedApplication.KeyWindow;
Il peut être appelé dans n’importe quelle classe ou méthode qui doit accéder à la fenêtre clé actuelle. Si aucune fenêtre n’est actuellement ouverte, elle retourne null
.
Accès à toutes les fenêtres d’application
Il peut arriver que vous deviez accéder à toutes les fenêtres actuellement ouvertes par votre application Xamarin.Mac. Par exemple, pour voir si un fichier que l’utilisateur souhaite ouvrir est déjà ouvert dans une fenêtre sortante.
Le NSApplication.SharedApplication
conserve une Windows
propriété qui contient un tableau de toutes les fenêtres ouvertes dans votre application. Vous pouvez itérer sur ce tableau pour accéder à toutes les fenêtres actuelles de l’application. Par exemple :
// 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;
}
}
Dans l’exemple de code, nous créons un cast de chaque fenêtre retournée dans la classe personnalisée ViewController
de notre application et testons la valeur d’une propriété personnalisée Path
par rapport au chemin d’accès d’un fichier que l’utilisateur souhaite ouvrir. Si le fichier est déjà ouvert, nous mettons cette fenêtre à l’avant.
Ajustement de la taille de la fenêtre dans le code
Parfois, l’application doit redimensionner une fenêtre dans le code. Pour redimensionner et repositionner une fenêtre, vous ajustez sa Frame
propriété. Lorsque vous ajustez la taille d’une fenêtre, vous devez généralement également ajuster son origine, afin de conserver la fenêtre au même emplacement en raison du système de coordonnées de macOS.
Contrairement à iOS où le coin supérieur gauche représente (0,0), macOS utilise un système de coordonnées mathématiques où le coin inférieur gauche de l’écran représente (0,0). Dans iOS, les coordonnées augmentent à mesure que vous descendez vers la droite. Dans macOS, les coordonnées augmentent en valeur vers la droite.
L’exemple de code suivant redimensionne une fenêtre :
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);
Important
Lorsque vous ajustez une taille de fenêtre et un emplacement dans le code, vous devez vous assurer que vous respectez les tailles minimales et maximales que vous avez définies dans le Générateur d’interface. Cela ne sera pas automatiquement respecté et vous pourrez rendre la fenêtre plus grande ou plus petite que ces limites.
Modification de la taille de la fenêtre de surveillance
Il peut arriver que vous deviez surveiller les modifications apportées à la taille d’une fenêtre à l’intérieur de votre application Xamarin.Mac. Par exemple, pour redessiner du contenu en fonction de la nouvelle taille.
Pour surveiller les modifications de taille, vérifiez d’abord que vous avez affecté une classe personnalisée pour le contrôleur de fenêtre dans le générateur d’interface de Xcode. Par exemple, MasterWindowController
dans ce qui suit :
Ensuite, modifiez la classe de contrôleur de fenêtre personnalisée et surveillez l’événement DidResize
sur la fenêtre du contrôleur pour être averti des changements de taille en direct. Par exemple :
public override void WindowDidLoad ()
{
base.WindowDidLoad ();
Window.DidResize += (sender, e) => {
// Do something as the window is being live resized
};
}
Si vous le souhaitez, vous pouvez utiliser l’événement DidEndLiveResize
pour être averti uniquement une fois que l’utilisateur a fini de modifier la taille de la fenêtre. Par exemple :
public override void WindowDidLoad ()
{
base.WindowDidLoad ();
Window.DidEndLiveResize += (sender, e) => {
// Do something after the user's finished resizing
// the window
};
}
Définition du titre et du fichier représenté d’une fenêtre
Lorsque vous utilisez des fenêtres qui représentent des documents, a une DocumentEdited
propriété qui, si elle est définie surtrue
, NSWindow
affiche un petit point dans le bouton Fermer pour donner à l’utilisateur une indication que le fichier a été modifié et doit être enregistré avant la fermeture.
Nous allons modifier notre ViewController.cs
fichier et apporter les modifications suivantes :
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;
};
}
Nous surveillons également l’événement WillClose
dans la fenêtre et vérifions l’état de la DocumentEdited
propriété. Si c’est true
le cas, nous devons donner à l’utilisateur la possibilité d’enregistrer les modifications apportées au fichier. Si nous exécutons notre application et entrez du texte, le point s’affiche :
Si vous essayez de fermer la fenêtre, vous recevez une alerte :
Si vous chargez un document à partir d’un fichier, définissez le titre de la fenêtre sur le nom du fichier à l’aide de la window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
méthode (étant donné qu’il path
s’agit d’une chaîne représentant le fichier en cours d’ouverture). En outre, vous pouvez définir l’URL du fichier à l’aide de la window.RepresentedUrl = url;
méthode .
Si l’URL pointe vers un type de fichier connu par le système d’exploitation, son icône s’affiche dans la barre de titre. Si l’utilisateur clique avec le bouton droit sur l’icône, le chemin d’accès au fichier s’affiche.
Modifiez le AppDelegate.cs
fichier et ajoutez la méthode suivante :
[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;
}
}
}
Maintenant, si nous exécutons notre application, sélectionnez Ouvrir... dans le menu Fichier , sélectionnez un fichier texte dans la boîte de dialogue Ouvrir et ouvrez-le :
Le fichier s’affiche et le titre est défini avec l’icône du fichier :
Ajout d’une nouvelle fenêtre à un projet
Outre la fenêtre de document main, une application Xamarin.Mac peut avoir besoin d’afficher d’autres types de fenêtres pour l’utilisateur, telles que préférences ou panneaux d’inspecteur.
Pour ajouter une nouvelle fenêtre, procédez comme suit :
Dans le Explorateur de solutions, double-cliquez sur le fichier pour l’ouvrir
Main.storyboard
et le modifier dans le générateur d’interface de Xcode.Faites glisser un nouveau contrôleur de fenêtre à partir de la bibliothèque et déposez-le sur l’aire de conception :
Dans l’inspecteur d’identité, entrez
PreferencesWindow
pour l’ID de storyboard :Concevez votre interface :
Ouvrez le menu De l’application (
MacWindows
), sélectionnez Préférences..., Control-Click et faites glisser vers la nouvelle fenêtre :Sélectionnez Afficher dans le menu contextuel.
Enregistrez vos modifications et revenez à Visual Studio pour Mac à synchroniser avec Xcode.
Si nous exécutons le code et que nous sélectionnons préférences... dans le menu Application, la fenêtre s’affiche :
Utilisation des panneaux
Comme indiqué au début de cet article, un panneau flotte au-dessus des autres fenêtres et fournit des outils ou des contrôles que les utilisateurs peuvent utiliser lorsque les documents sont ouverts.
Comme tout autre type de fenêtre que vous créez et utilisez dans votre application Xamarin.Mac, le processus est essentiellement le même :
- Ajoutez une nouvelle définition de fenêtre au projet.
- Double-cliquez sur le
.xib
fichier pour ouvrir la conception de fenêtre à modifier dans le Générateur d’interface de Xcode. - Définissez toutes les propriétés de fenêtre requises dans l’inspecteur d’attribut et l’inspecteur de taille.
- Faites glisser les contrôles requis pour générer votre interface et configurez-les dans l’inspecteur d’attributs.
- Utilisez l’inspecteur de taille pour gérer le redimensionnement de vos éléments d’interface utilisateur.
- Exposez les éléments d’interface utilisateur de la fenêtre au code C# via des sorties et des actions.
- Enregistrez vos modifications et revenez à Visual Studio pour Mac pour synchroniser avec Xcode.
Dans l’inspecteur d’attributs, vous disposez des options suivantes spécifiques aux panneaux :
- Style : vous permet d’ajuster le style du panneau à partir de : Panneau standard (ressemble à une fenêtre standard), Panneau utilitaire (a une barre de titre plus petite), Panneau HUD (est translucide et la barre de titre fait partie de l’arrière-plan).
- Non activation : détermine dans le panneau devient la fenêtre de clé.
- Document Modal : si document modal, le panneau flotte uniquement au-dessus des fenêtres de l’application, sinon il flotte avant tout.
Pour ajouter un nouveau panneau, procédez comme suit :
Dans le Explorateur de solutions, cliquez avec le bouton droit sur le projet, puis sélectionnez Ajouter un>nouveau fichier....
Dans la boîte de dialogue Nouveau fichier, sélectionnez Xamarin.Mac>Cocoa Window with Controller :
Entrez
DocumentPanel
comme Nom, puis cliquez sur le bouton Nouveau.Double-cliquez sur le fichier pour l’ouvrir
DocumentPanel.xib
pour le modifier dans Le Générateur d’interface :Supprimez la fenêtre existante et faites glisser un panneau à partir de l’inspecteur de bibliothèque dans l’éditeur d’interface :
Accrochez le panneau à lasortie de lafenêtre - Propriétaire - du fichier:
Basculez vers l’inspecteur d’identité et définissez la classe du panneau sur
DocumentPanel
:Enregistrez vos modifications et revenez à Visual Studio pour Mac à synchroniser avec Xcode.
Modifiez le
DocumentPanel.cs
fichier et remplacez la définition de classe comme suit :public partial class DocumentPanel : NSPanel
Enregistrez les modifications du fichier.
Modifiez le AppDelegate.cs
fichier et faites en sorte que la DidFinishLaunching
méthode ressemble à ce qui suit :
public override void DidFinishLaunching (NSNotification notification)
{
// Display panel
var panel = new DocumentPanelController ();
panel.Window.MakeKeyAndOrderFront (this);
}
Si nous exécutons notre application, le panneau s’affiche :
Important
Les fenêtres de panneau ont été dépréciées par Apple et doivent être remplacées par des interfaces d’inspecteur. Pour obtenir un exemple complet de création d’un inspecteur dans une application Xamarin.Mac, consultez notre exemple d’application MacInspector .
Résumé
Cet article a examiné en détail l’utilisation de Windows et de panneaux dans une application Xamarin.Mac. Nous avons vu les différents types et utilisations de Windows et panneaux, comment créer et gérer Windows et panneaux dans le Générateur d’interface de Xcode et comment utiliser Windows et les panneaux en code C#.