Windows dans Xamarin.Mac

Cet article traite de l’utilisation de fenêtres et de 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 fichiers storyboards et .xib, et leur utilisation par programmation.

Lorsque vous travaillez avec 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 dans le 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 :

  1. Pour fournir une zone dans laquelle les vues et les contrôles peuvent être placés et gérés.
  2. Pour accepter et répondre aux événements en réponse à l’interaction utilisateur avec le clavier et la souris.

Windows peut être utilisé dans un état sans mode (par exemple, un éditeur de texte qui peut ouvrir plusieurs documents à la fois) ou Modal (par exemple, une boîte de dialogue d’exportation qui doit être ignorée avant que l’application puisse continuer).

Les panneaux sont un type spécial de Fenêtre (sous-classe de la classe de base NSWindow ), qui servent généralement une fonction auxiliaire dans une application, comme les fenêtres utilitaires telles que les inspecteurs de format texte et le sélecteur de couleurs système.

Modification d’une fenêtre dans Xcode

Dans cet article, nous allons aborder les principes fondamentaux de l’utilisation de Windows et panneaux dans une application Xamarin.Mac. Il est fortement suggéré que vous travaillez tout d’abord dans l’article Hello, Mac , en particulier les sections Introduction to Xcode and Interface Builder et Outlets and Actions , car elle couvre les concepts et techniques clés que nous utiliserons dans cet article.

Vous pouvez également examiner les classes /méthodes C# exposantes dans Objective-Cla section du document interne Xamarin.Mac, ainsi que les Register Export instructions utilisées pour connecter vos classes C# à des objets et des Objective-C éléments d’interface utilisateur.

Présentation des fenêtres

Comme indiqué ci-dessus, une fenêtre fournit une zone dans laquelle les vues et les contrôles peuvent être placés et gérés et répondent aux événements en fonction de l’interaction utilisateur (via le clavier ou la souris).

Selon Apple, il existe cinq types principaux 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 principale 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 d’autres fenêtres et fournit des outils ou des contrôles que les utilisateurs peuvent utiliser pendant l’ouverture des documents. Dans certains cas, un panneau peut être translucide (par exemple, lors de l’utilisation de grands graphiques).
  • Boîte de dialogue : une boîte de dialogue s’affiche en réponse à une action utilisateur et fournit généralement des façons dont les utilisateurs peuvent effectuer l’action. Une boîte de dialogue nécessite une réponse de l’utilisateur avant de pouvoir être fermée. (Voir Utilisation de boîtes de dialogue)
  • Alertes : une alerte est un type spécial de dialogue qui s’affiche lorsqu’un problème grave se produit (par exemple, une erreur) ou un avertissement (par exemple, la préparation à la suppression d’un fichier). Étant donné qu’une alerte est une boîte de dialogue, elle nécessite également une réponse 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 main, clé et inactive

Windows dans une application Xamarin.Mac peut regarder et se comporter différemment en fonction de la façon dont l’utilisateur interagit actuellement avec eux. La fenêtre principale du document ou de l’application qui est actuellement axée sur 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é (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 clé (s’ils sont séparés) sont toujours actives, Les fenêtres inactives sont ouvertes qui ne sont pas au premier plan. Par exemple, une application éditeur de texte peut avoir plusieurs documents ouverts à la fois, seule la fenêtre principale serait active, toutes les autres seraient inactives.

Pour plus d’informations, consultez la section À propos de Windows des thèmes de conception macOS d’Apple.

Fenêtres d’affectation de noms

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 en cours d’exécution 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 instructions suivantes :

  • Utilisez le nom de votre application pour le titre d’une fenêtre principale et non-document.
  • Nommez une nouvelle fenêtre untitledde document. Pour le premier nouveau document, n’ajoutez pas de nombre au titre (par untitled 1exemple). Si l’utilisateur crée un autre document avant d’enregistrer et de titler le premier, appelez cette fenêtre untitled 2, untitled 3etc.

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 masquer tout en plein écran, y compris la barre de menus de l’application (qui peut être révélée en déplaçant le curseur en haut de l’écran) pour fournir une interaction sans distraction avec son contenu.

Apple suggère les instructions suivantes :

  • Déterminez s’il est judicieux qu’une fenêtre soit en 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 règle générale, 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 terminer la tâche.
  • Si possible, évitez l’interaction du Finder pendant que 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 principale.

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 actif ou la sélection (par exemple, le sélecteur de couleurs système) :

Panneau de couleurs

Les panneaux peuvent être spécifiques à l’application ou à l’échelle du système. Les panneaux spécifiques à l’application flottent en haut des fenêtres de document de l’application et disparaissent lorsque l’application est en arrière-plan. 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 instructions suivantes :

  • En général, utilisez un panneau standard, les panneaux transparents ne doivent être utilisés qu’avec parcimonie et pour des tâches graphiquement intensives.
  • Envisagez d’utiliser un panneau pour permettre aux utilisateurs d’accéder facilement aux contrôles ou informations importants qui affectent directement leur tâche.
  • Masquer et afficher les panneaux selon les 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 auxiliaires et des options qui affectent le document actif ou la sélection en tant qu’inspecteurs qui font partie de la fenêtre principale (comme l’application Pages ci-dessous), au lieu d’utiliser Windows panneau :

Exemple d’inspecteur

Pour plus d’informations, consultez la section Panneaux des thèmes de conception macOS d’Apple.

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 votre conception windows, dans le Explorateur de solutions, double-cliquez sur le Main.storyboard fichier :

Sélection du storyboard principal

Cela ouvre la conception de fenêtre dans le Générateur d’interface de Xcode :

Modification de l’interface utilisateur dans 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 s’affiche dans la barre de titre de la fenêtre.
  • Enregistrement automatique : il s’agit de la clé qui sera utilisée pour ider 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 unifié et barre d’outils : si la fenêtre inclut une barre d’outils, si elle fait partie de la barre de titre.
  • Mode Contenu de taille complète : 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.
  • Textured - Les fenêtres texturées peuvent utiliser des effets (comme la vibrance) 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 comporte-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 comporte-t-elle un bouton masquer/afficher la barre d’outils.
  • Pouvant être restauré : la position et les paramètres de la fenêtre sont automatiquement enregistrés et restaurés.
  • Visible au lancement : la fenêtre s’affiche automatiquement lorsque le .xib fichier est chargé.
  • Masquer lors de la désactivation : la fenêtre est masquée lorsque l’application entre en arrière-plan.
  • Libérer quand elle est fermée : la fenêtre est vidée de la mémoire lorsqu’elle est fermée.
  • Info-bulles Always Display : les info-bulles s’affichent constamment.
  • Recalcule la boucle d’affichage : l’ordre d’affichage recalculé avant le dessin de la fenêtre.
  • Espaces, Exposé et Cyclisme - Tous définissent le comportement de la fenêtre dans ces environnements macOS.
  • Plein écran : détermine si cette fenêtre peut entrer 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 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 :

Taille et emplacement par défaut

À 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 principal personnalisé

Pour pouvoir créer des points de sortie et des actions pour 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 :

  1. Ouvrez le Storyboard de l’application dans le Générateur d’interface de Xcode.

  2. Sélectionnez l’aire NSWindowController de conception.

  3. Basculez vers la vue Identity Inspector et entrez WindowController en tant que nom de classe :

    Définition du nom de la classe

  4. Enregistrez vos modifications et revenez à Visual Studio pour Mac à synchroniser.

  5. Un WindowController.cs fichier sera ajouté à votre projet dans le Explorateur de solutions dans Visual Studio pour Mac :

    Sélection du contrôleur windows

  6. Rouvrez le Storyboard dans le Générateur d’interface de Xcode.

  7. Le WindowController.h fichier sera disponible pour une utilisation :

    Modification du fichier WindowController.h

Ajout d’éléments d’interface utilisateur

Pour définir le contenu d’une fenêtre, faites glisser des 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 du Générateur d’interface pour créer et activer des contrôles.

Par exemple, nous allons faire glisser une barre d’outils de l’inspecteur de bibliothèque vers la fenêtre dans l’Éditeur d’interface :

Sélection d’une barre d’outils dans la bibliothèque

Ensuite, faites glisser dans une vue texte et dimensionnez-la pour remplir la zone sous la barre d’outils :

Ajout d’une vue de texte

É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 :

Contraintes d’édition

En cliquant sur les quatre faisceaux d’I rouges en haut de l’éditeur et en cliquant sur Ajouter 4 contraintes, nous expliquons à l’affichage texte de coller aux coordonnées X,Y données et augmenter ou réduire horizontalement et verticalement à mesure que la fenêtre est redimensionnée.

Enfin, exposez l’affichage texte au code à l’aide d’un point de sortie (veillez à sélectionner le ViewController.h fichier) :

Configuration d’un point de sortie

Enregistrez vos modifications et revenez à Visual Studio pour Mac pour vous synchroniser avec Xcode.

Pour plus d’informations sur l’utilisation des points de vente et des actions, consultez notre documentation de sortie et d’action .

Flux de travail de fenêtre standard

Pour toute fenêtre que vous créez et utilisez dans votre application Xamarin.Mac, le processus est essentiellement identique à ce que nous venons de faire ci-dessus :

  1. Pour les nouvelles fenêtres qui ne sont pas automatiquement ajoutées par défaut à votre projet, ajoutez une nouvelle définition de fenêtre au projet. Cela sera abordé en détail ci-dessous.
  2. Double-cliquez sur le Main.storyboard fichier pour ouvrir la conception de fenêtre pour la modification dans le Générateur d’interface de Xcode.
  3. Faites glisser une nouvelle fenêtre dans la conception de l’interface utilisateur et accrochez la fenêtre dans la fenêtre principale à l’aide de Segues (pour plus d’informations, consultez la section Segues de notre documentation Working with Storyboards).
  4. Définissez les propriétés de fenêtre requises dans l’inspecteur d’attribut et l’inspecteur de taille.
  5. Faites glisser les contrôles nécessaires pour générer votre interface et les configurer dans l’inspecteur d’attribut.
  6. Utilisez l’inspecteur de taille pour gérer le redimensionnement de vos éléments d’interface utilisateur.
  7. Exposez les éléments d’interface utilisateur de la fenêtre au code C# via des points de sortie et des actions.
  8. Enregistrez vos modifications et revenez à Visual Studio pour Mac pour vous synchroniser avec Xcode.

Maintenant que nous avons créé une fenêtre de base, nous allons examiner les processus classiques qu’une application Xamarin.Mac effectue lors de l’utilisation de 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 :

Exemple de fenêtre en cours d’exécution

Étant donné que nous avons modifié la conception de cette fenêtre ci-dessus, elle inclut désormais un contrôle de barre d’outils et d’affichage de texte par défaut. La section suivante du Info.plist fichier est chargée d’afficher cette fenêtre :

Modification d’Info.plist

La liste déroulante De l’interface principale est utilisée pour sélectionner le Storyboard qui sera utilisé comme interface utilisateur principale de l’application (dans ce cas Main.storyboard).

Un contrôleur de vue est automatiquement ajouté au projet pour contrôler que Windows principal s’affiche (ainsi que son affichage principal). Il est défini dans le ViewController.cs fichier et attaché au propriétaire du fichier dans le Générateur d’interface sous l’inspecteur d’identité :

Définition du propriétaire du fichier

Pour notre fenêtre, nous aimerions qu’elle ait un titre lorsqu’elle untitled s’ouvre pour la première fois. Nous allons donc remplacer la ViewWillAppear méthode dans l’apparence ViewController.cs suivante :

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

    // Set Window Title
    this.View.Window.Title = "untitled";
}

Remarque

La propriété de Title la fenêtre est définie dans la ViewWillAppear méthode au lieu de la ViewDidLoad méthode, car, bien que la vue puisse être chargée en mémoire, elle n’est pas encore instanciée entièrement. L’accès à 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 câblée à la propriété.

Fermeture par programmation d’une fenêtre

Il peut arriver que vous souhaitiez fermer par programmation une fenêtre dans une application Xamarin.Mac, autre que d’avoir l’utilisateur à cliquer sur le bouton Fermer de la fenêtre ou à l’aide d’un élément de menu. macOS fournit deux façons différentes de fermer un NSWindow programme : PerformClose et Close.

PerformClose

Appeler la PerformClose méthode d’un NSWindow simule l’utilisateur en cliquant 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' WillClose , elle est déclenchée avant la fermeture de la fenêtre. Si l’événement est retourné 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 l’instance MyWindow NSWindow . Si elle a réussi, la fenêtre est fermée, sinon le son de l’alerte est émis et le reste ouvert.

Clôture

Appeler la Close méthode d’un NSWindow ne simule pas l’utilisateur en cliquant sur le bouton Fermer de la fenêtre en mettant momentanément en surbrillance le bouton, il ferme simplement la fenêtre.

Une fenêtre ne doit pas être visible pour être fermée et une NSWindowWillCloseNotification notification est publiée dans le Centre de notification par défaut pour la fenêtre fermée.

La Close méthode diffère de deux façons importantes de la PerformClose méthode :

  1. Il n’essaie pas de déclencher l’événement WillClose .
  2. Il ne simule pas l’utilisateur en cliquant sur le bouton Fermer en mettant momentanément en surbrillance le bouton.

Par exemple :

MyWindow.Close();

Ferme l’instance MyWindow NSWindow .

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 le widget Fermer :

Fenêtre avec le marqueur modifié

Si l’utilisateur tente de fermer la fenêtre ou quitte l’application Mac pendant 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 permettre à l’utilisateur d’enregistrer ses modifications en premier :

Feuille d’enregistrement affichée lorsque la fenêtre est fermée

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;

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 surveiller la fermeture d’une fenêtre par l’utilisateur et leur permettre d’enregistrer le contenu modifié à l’avance, vous devez créer une sous-classe et NSWindowDelegate 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 une 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 vérifier 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-la 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 dispose d’un menu Fichier avec un nouvel élément automatiquement câblé à 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, la rend la fenêtre principale et clé, et la définit comme titre. Maintenant, si nous exécutons notre application, puis sélectionnez Nouveau dans le menu Fichier , une nouvelle fenêtre d’éditeur s’ouvre et s’affiche :

Une nouvelle fenêtre sans titre a été ajoutée

Si nous ouvrez le menu Windows , vous pouvez voir que l’application suit et gère automatiquement nos fenêtres ouvertes :

Menu Fenêtres

Pour plus d’informations sur l’utilisation des menus dans une application Xamarin.Mac, consultez notre documentation sur l’utilisation des menus .

Obtention de la fenêtre active actuellement

Dans une application Xamarin.Mac qui peut ouvrir plusieurs fenêtres (documents), il arrive que vous deviez obtenir la fenêtre la plus active et la plus haute (fenêtre clé). Le code suivant retourne la fenêtre de clé :

var window = NSApplication.SharedApplication.KeyWindow;

Elle peut être appelée dans n’importe quelle classe ou méthode qui doit accéder à la fenêtre active, clé. 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 que votre application Xamarin.Mac a actuellement ouvertes. Par exemple, pour voir si un fichier que l’utilisateur souhaite ouvrir est déjà ouvert dans une fenêtre de sortie.

La NSApplication.SharedApplication propriété gère 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 cassons chaque fenêtre retournée dans la classe personnalisée ViewController dans notre application et testez 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 apportons cette fenêtre à l’avant.

Ajustement de la taille de la fenêtre dans le code

Il arrive que l’application ait besoin de 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 ajuster son origine pour conserver la fenêtre dans le 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 au fur et à mesure que vous descendez vers la droite. Dans macOS, les coordonnées augmentent de la valeur vers le haut à 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 et un emplacement windows 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 honoré et vous serez en mesure de rendre la fenêtre plus grande ou inférieure à ces limites.

Modifications apportées à la taille des fenêtres 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 le 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 les éléments suivants :

Inspecteur d’identité

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 modifications de taille dynamique. 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 terminé 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 d’une fenêtre et du fichier représenté

Lorsque vous utilisez des fenêtres qui représentent des documents, a une DocumentEdited propriété qui, NSWindow si elle est définie, true affiche un petit point dans le bouton Fermer pour indiquer à l’utilisateur que le fichier a été modifié et qu’il 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 analysons également l’événement WillClose sur la fenêtre et vérifions l’état de la DocumentEdited propriété. S’il est true nécessaire de donner à l’utilisateur la possibilité d’enregistrer les modifications dans le fichier. Si nous exécutons notre application et entrez du texte, le point s’affiche :

Fenêtre modifiée

Si vous essayez de fermer la fenêtre, vous recevez une alerte :

Affichage d’une boîte de dialogue Enregistrer

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 s’agit path d’une chaîne représentant le fichier ouvert). 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 :

Boîte de dialogue Ouverte

Le fichier s’affiche et le titre est défini avec l’icône du fichier :

Contenu d’un fichier chargé

Ajout d’une nouvelle fenêtre à un projet

Outre la fenêtre de document principale, une application Xamarin.Mac peut avoir besoin d’afficher d’autres types de fenêtres à l’utilisateur, telles que préférences ou panneaux d’inspecteur.

Pour ajouter une nouvelle fenêtre, procédez comme suit :

  1. Dans le Explorateur de solutions, double-cliquez sur le Main.storyboard fichier pour l’ouvrir pour modification dans le Générateur d’interface de Xcode.

  2. Faites glisser un nouveau contrôleur de fenêtre à partir de la bibliothèque et déposez-le sur l’aire de conception :

    Sélection d’un nouveau contrôleur de fenêtre dans la bibliothèque

  3. Dans l’inspecteur d’identité, entrez PreferencesWindow l’ID storyboard :

    Définition de l’ID de table de montage séquentiel

  4. Concevez votre interface :

    Conception de l’interface utilisateur

  5. Ouvrez le menu De l’application (MacWindows), sélectionnez Préférences..., Cliquez sur Le contrôle et faites glisser vers la nouvelle fenêtre :

    Création d’un segue

  6. Sélectionnez Afficher dans le menu contextuel.

  7. Enregistrez vos modifications et revenez à Visual Studio pour Mac à synchroniser avec Xcode.

Si nous exécutons le code et sélectionnez les préférences... dans le menu Application, la fenêtre s’affiche :

Un exemple de menu préférences

Utilisation de panneaux

Comme indiqué au début de cet article, un panneau flotte au-dessus d’autres fenêtres et fournit des outils ou des contrôles que les utilisateurs peuvent utiliser pendant l’ouverture des documents.

Tout 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 :

  1. Ajoutez une nouvelle définition de fenêtre au projet.
  2. Double-cliquez sur le .xib fichier pour ouvrir la conception de fenêtre pour la modification dans le Générateur d’interface de Xcode.
  3. Définissez les propriétés de fenêtre requises dans l’inspecteur d’attribut et l’inspecteur de taille.
  4. Faites glisser les contrôles nécessaires pour générer votre interface et les configurer dans l’inspecteur d’attribut.
  5. Utilisez l’inspecteur de taille pour gérer le redimensionnement de vos éléments d’interface utilisateur.
  6. Exposez les éléments d’interface utilisateur de la fenêtre au code C# via des points de sortie et des actions.
  7. Enregistrez vos modifications et revenez à Visual Studio pour Mac pour vous synchroniser avec Xcode.

Dans l’inspecteur d’attributs, vous disposez des options suivantes spécifiques aux panneaux :

Inspecteur d’attribut

  • Style - 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 clé.
  • Document Modal - Si document modal , le panneau flotte uniquement au-dessus des fenêtres de l’application, sinon il flotte au-dessus de tous.

Pour ajouter un nouveau panneau, procédez comme suit :

  1. Dans le Explorateur de solutions, cliquez avec le bouton droit sur le projet, puis sélectionnez Ajouter>un nouveau fichier....

  2. Dans la boîte de dialogue Nouveau fichier, sélectionnez Xamarin.Mac>Cocoa Window with Controller :

    Ajout d’un nouveau contrôleur de fenêtre

  3. Entrez DocumentPanel comme Nom, puis cliquez sur le bouton Nouveau.

  4. Double-cliquez sur le DocumentPanel.xib fichier pour l’ouvrir pour modification dans le Générateur d’interface :

    Modification du panneau

  5. Supprimez la fenêtre existante et faites glisser un panneau de l’inspecteur de bibliothèque dans l’éditeur d’interface :

    Suppression de la fenêtre existante

  6. Raccordez le panneau jusqu’à la sortie de la fenêtre - Propriétaire - du fichier :

    Faire glisser vers le haut le panneau

  7. Basculez vers l’inspecteur d’identité et définissez la classe du panneau sur DocumentPanel:

    Définition de la classe du panneau

  8. Enregistrez vos modifications et revenez à Visual Studio pour Mac à synchroniser avec Xcode.

  9. Modifiez le DocumentPanel.cs fichier et modifiez la définition de classe en procédant comme suit :

    public partial class DocumentPanel : NSPanel

  10. 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 :

Panneau d’une application en cours d’exécution

Important

Les fenêtres du panneau ont été déconseillées par Apple et doivent être remplacées par les interfaces Inspector.

Résumé

Cet article a examiné en détail l’utilisation de Windows et 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 Panneaux dans le code C#.