Partager via


Vues hiérarchiques dans Xamarin.Mac

Cet article traite de l’utilisation des vues hiérarchiques dans une application Xamarin.Mac. Il décrit la création et la gestion des vues hiérarchiques dans Xcode et Interface Builder et leur utilisation par programmation.

Lorsque vous utilisez C# et .NET dans une application Xamarin.Mac, vous avez accès aux mêmes vues hiérarchiques 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 vues hiérarchiques (ou éventuellement les créer directement dans le code C#).

Un mode Plan est un type de table qui permet à l’utilisateur de développer ou de réduire les lignes de données hiérarchiques. Comme un affichage tableau, un mode Plan affiche des données pour un ensemble d’éléments connexes, avec des lignes représentant des éléments individuels et des colonnes représentant les attributs de ces éléments. Contrairement à un affichage tableau, les éléments d’un mode Plan ne se trouvent pas dans une liste plate, ils sont organisés dans une hiérarchie, comme les fichiers et les dossiers sur un disque dur.

Exemple d’exécution d’application

Dans cet article, nous allons aborder les principes fondamentaux de l’utilisation des vues hiérarchiques 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 dansObjective-Cla section du document interne Xamarin.Mac, ainsi que les RegisterExport instructions utilisées pour connecter vos classes C# à des objets et des Objective-C éléments d’interface utilisateur.

Présentation des vues hiérarchiques

Un mode Plan est un type de table qui permet à l’utilisateur de développer ou de réduire les lignes de données hiérarchiques. Comme un affichage tableau, un mode Plan affiche des données pour un ensemble d’éléments connexes, avec des lignes représentant des éléments individuels et des colonnes représentant les attributs de ces éléments. Contrairement à un affichage tableau, les éléments d’un mode Plan ne se trouvent pas dans une liste plate, ils sont organisés dans une hiérarchie, comme les fichiers et les dossiers sur un disque dur.

Si un élément d’un mode Plan contient d’autres éléments, il peut être développé ou réduit par l’utilisateur. Un élément extensible affiche un triangle de divulgation, qui pointe vers la droite lorsque l’élément est réduit et pointe vers le bas lorsque l’élément est développé. Si vous cliquez sur le triangle de divulgation, l’élément doit se développer ou réduire.

Le mode Plan (NSOutlineView) est une sous-classe de l’affichage table (NSTableView) et, par conséquent, hérite de la majeure partie de son comportement de sa classe parente. Par conséquent, de nombreuses opérations prises en charge par un affichage table, telles que la sélection de lignes ou de colonnes, le repositionnement de colonnes en faisant glisser les en-têtes de colonne, etc., sont également prises en charge par un mode Plan. Une application Xamarin.Mac contrôle ces fonctionnalités et peut configurer les paramètres de l’affichage hiérarchique (dans le code ou le Générateur d’interface) pour autoriser ou interdire certaines opérations.

Un mode Plan ne stocke pas ses propres données, au lieu de cela, il s’appuie sur une source de données (NSOutlineViewDataSource) pour fournir les lignes et les colonnes requises, selon les besoins.

Le comportement d’un mode Plan peut être personnalisé en fournissant une sous-classe du délégué en mode Plan (NSOutlineViewDelegate) pour prendre en charge la gestion des colonnes hiérarchiques, le type pour sélectionner des fonctionnalités, la sélection de lignes et la modification, le suivi personnalisé et les vues personnalisées pour des colonnes et des lignes individuelles.

Étant donné qu’un mode Plan partage une grande partie de son comportement et de ses fonctionnalités avec une vue table, vous pouvez passer par notre documentation Vues de table avant de continuer avec cet article.

Création et maintenance des vues hiérarchiques 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

Tapez outline dans la zone de recherche de l’inspecteur de bibliothèque pour faciliter la recherche des contrôles Mode Plan :

Sélection d’un mode Plan dans la bibliothèque

Faites glisser un mode Plan sur le contrôleur de vue dans l’éditeur d’interface, remplissez la zone de contenu du contrôleur de vue et définissez-le sur l’emplacement où il se réduit et augmente avec la fenêtre de l’éditeur de contrainte :

Modification des contraintes

Sélectionnez l’affichage hiérarchique dans la hiérarchie d’interface et les propriétés suivantes sont disponibles dans l’inspecteur d’attribut :

Capture d’écran montrant les propriétés disponibles dans l’inspecteur d’attribut.

  • Colonne hiérarchique : colonne de table dans laquelle les données hiérarchiques sont affichées.
  • Colonne hiérarchique automatique - Si true, la colonne hiérarchique est automatiquement enregistrée et restaurée entre les exécutions de l’application.
  • Retrait : quantité de colonnes en retrait sous un élément développé.
  • Retrait suit les cellules : si true, la marque de retrait est mise en retrait avec les cellules.
  • Enregistrement automatique des éléments développés : si true, l’état développé/réduit des éléments est automatiquement enregistré et restauré entre les exécutions de l’application.
  • Mode contenu : vous permet d’utiliser des vues (NSView) ou des cellules (NSCell) pour afficher les données dans les lignes et les colonnes. À compter de macOS 10.7, vous devez utiliser les vues.
  • Floats Group Rows - If true, l’affichage Tableau dessine les cellules groupées comme s’ils sont flottants.
  • Colonnes : définit le nombre de colonnes affichées.
  • En-têtes - Si true, les colonnes auront des en-têtes.
  • Réorganisation : sitrue, l’utilisateur peut faire glisser les colonnes dans la table.
  • Redimensionnement : si true, l’utilisateur pourra faire glisser les en-têtes de colonne pour redimensionner les colonnes.
  • Dimensionnement des colonnes : contrôle la façon dont la table dimensionne automatiquement les colonnes.
  • Mise en surbrillance : contrôle le type de mise en surbrillance du tableau lorsqu’une cellule est sélectionnée.
  • Autres lignes : si true, jamais une autre ligne aura une couleur d’arrière-plan différente.
  • Grille horizontale : sélectionne le type de bordure dessinée entre les cellules horizontalement.
  • Grille verticale : sélectionne le type de bordure dessinée entre les cellules verticalement.
  • Couleur de grille : définit la couleur de bordure de cellule.
  • Arrière-plan : définit la couleur d’arrière-plan de la cellule.
  • Sélection : vous permet de contrôler la façon dont l’utilisateur peut sélectionner des cellules dans le tableau comme suit :
    • Multiple - Si true, l’utilisateur peut sélectionner plusieurs lignes et colonnes.
    • Colonne : si truel’utilisateur peut sélectionner des colonnes.
    • Tapez Select - If true, l’utilisateur peut taper un caractère pour sélectionner une ligne.
    • Vide : si truel’utilisateur n’est pas tenu de sélectionner une ligne ou une colonne, la table n’autorise aucune sélection du tout.
  • Enregistrement automatique : nom sous lequel le format des tables est automatiquement enregistré.
  • Informations sur les colonnes : si true, l’ordre et la largeur des colonnes sont automatiquement enregistrés.
  • Sauts de ligne : sélectionnez la façon dont la cellule gère les sauts de ligne.
  • Tronque la dernière ligne visible - Si true, la cellule sera tronquée dans les données ne peut pas s’adapter à ses limites.

Important

Sauf si vous conservez une application Xamarin.Mac héritée, NSView les vues hiérarchiques basées doivent être utilisées sur NSCell les vues de table basées. NSCell est considéré comme hérité et peut ne pas être pris en charge à l’avenir.

Sélectionnez une colonne de table dans la hiérarchie d’interface et les propriétés suivantes sont disponibles dans l’inspecteur d’attribut :

Capture d’écran montrant les propriétés disponibles pour la colonne de table sélectionnée dans l’inspecteur d’attribut.

  • Titre : définit le titre de la colonne.
  • Alignement : définissez l’alignement du texte dans les cellules.
  • Police de titre : sélectionne la police du texte d’en-tête de la cellule.
  • Clé de tri : clé utilisée pour trier les données dans la colonne. Laissez vide si l’utilisateur ne peut pas trier cette colonne.
  • Sélecteur : action utilisée pour effectuer le tri. Laissez vide si l’utilisateur ne peut pas trier cette colonne.
  • Ordre : ordre de tri pour les données des colonnes.
  • Redimensionnement : sélectionne le type de redimensionnement de la colonne.
  • Modifiable : sitrue, l’utilisateur peut modifier des cellules dans un tableau basé sur des cellules.
  • Masqué : si true, la colonne est masquée.

Vous pouvez également redimensionner la colonne en faisant glisser sa poignée (centrée verticalement sur le côté droit) gauche ou droite.

Nous allons sélectionner chaque colonne dans notre affichage table et donner à la première colonne un titre et Product le deuxième Details.

Sélectionnez une vue de cellule de tableau (NSTableViewCell) dans la hiérarchie d’interface et les propriétés suivantes sont disponibles dans l’inspecteur d’attribut :

Capture d’écran montrant les propriétés disponibles pour la cellule de tableau sélectionnée dans l’inspecteur d’attribut.

Il s’agit de toutes les propriétés d’une vue standard. Vous avez également la possibilité de redimensionner les lignes de cette colonne ici.

Sélectionnez une cellule Table View (par défaut, il s’agit d’un NSTextField) dans la hiérarchie d’interface et les propriétés suivantes sont disponibles dans l’inspecteur d’attribut :

Capture d’écran montrant les propriétés disponibles pour la cellule d’affichage de tableau sélectionnée dans l’inspecteur d’attributs.

Vous aurez toutes les propriétés d’un champ de texte standard à définir ici. Par défaut, un champ de texte standard est utilisé pour afficher les données d’une cellule d’une colonne.

Sélectionnez une vue de cellule de tableau (NSTableFieldCell) dans la hiérarchie d’interface et les propriétés suivantes sont disponibles dans l’inspecteur d’attribut :

Capture d’écran montrant les propriétés disponibles pour la cellule d’affichage de tableau sélectionnée.

Les paramètres les plus importants ici sont les suivants :

  • Disposition : sélectionnez la façon dont les cellules de cette colonne sont disposées.
  • Utilise le mode ligne unique : si true, la cellule est limitée à une seule ligne.
  • Première largeur de disposition du runtime - Si true, la cellule préfère la largeur définie pour elle (manuellement ou automatiquement) lorsqu’elle est affichée la première fois que l’application est exécutée.
  • Action : contrôle le moment où l’action d’édition est envoyée pour la cellule.
  • Comportement : définit si une cellule est sélectionnable ou modifiable.
  • Texte enrichi - Si true, la cellule peut afficher du texte mis en forme et mis en forme.
  • Annuler - Si true, la cellule assume la responsabilité de son comportement d’annulation.

Sélectionnez l’affichage de cellule de tableau (NSTableFieldCell) en bas d’une colonne de tableau dans la hiérarchie d’interface :

Sélection de la vue de cellule de tableau

Cela vous permet de modifier l’affichage de cellule de tableau utilisé comme modèle de base pour toutes les cellules créées pour la colonne donnée.

Ajout d’actions et de points de sortie

Tout comme n’importe quel autre contrôle d’interface utilisateur Cocoa, nous devons exposer notre mode Plan et il s’agit de colonnes et de cellules dans le code C# à l’aide d’actions et de sorties (en fonction des fonctionnalités requises).

Le processus est le même pour n’importe quel élément Vue hiérarchique que nous voulons exposer :

  1. Basculez vers l’Éditeur Assistant et vérifiez que le ViewController.h fichier est sélectionné :

    Sélection du fichier .h correct

  2. Sélectionnez le mode Plan dans la hiérarchie d’interface, cliquez sur le contrôle et faites glisser vers le ViewController.h fichier.

  3. Créez un point de sortie pour l’affichage hiérarchique appelé ProductOutline:

    Capture d’écran montrant une sortie appelée ProductOutline dans l’inspecteur d’attribut.

  4. Créez des points de sortie pour les colonnes de tables également appelées ProductColumn et DetailsColumn:

    Capture d’écran montrant un point de sortie nommé DetailsColumn dans l’inspecteur d’attribut.

  5. Enregistrez les modifications et revenez à Visual Studio pour Mac à synchroniser avec Xcode.

Ensuite, nous allons écrire le code pour afficher des données pour le plan lors de l’exécution de l’application.

Remplissage de l’affichage hiérarchique

Avec notre mode Plan conçu dans le Générateur d’interface et exposé via une sortie, nous devons ensuite créer le code C# pour le remplir.

Tout d’abord, nous allons créer une Product classe pour contenir les informations des lignes et groupes de sous-produits individuels. Dans le Explorateur de solutions, cliquez avec le bouton droit sur le projet, puis sélectionnez Ajouter>un nouveau fichier... Sélectionnez Classe vide générale>, entrez Product le nom, puis cliquez sur le bouton Nouveau :

Création d’une classe vide

Faites en sorte que le Product.cs fichier ressemble à ce qui suit :

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

namespace MacOutlines
{
    public class Product : NSObject
    {
        #region Public Variables
        public List<Product> Products = new List<Product>();
        #endregion

        #region Computed Properties
        public string Title { get; set;} = "";
        public string Description { get; set;} = "";
        public bool IsProductGroup {
            get { return (Products.Count > 0); }
        }
        #endregion

        #region Constructors
        public Product ()
        {
        }

        public Product (string title, string description)
        {
            this.Title = title;
            this.Description = description;
        }
        #endregion
    }
}

Ensuite, nous devons créer une sous-classe permettant de NSOutlineDataSource fournir les données de notre plan tel qu’il est demandé. Dans le Explorateur de solutions, cliquez avec le bouton droit sur le projet, puis sélectionnez Ajouter>un nouveau fichier... Sélectionnez Classe vide générale>, entrez ProductOutlineDataSource le nom, puis cliquez sur le bouton Nouveau.

Modifiez le ProductTableDataSource.cs fichier et faites-le ressembler à ce qui suit :

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

namespace MacOutlines
{
    public class ProductOutlineDataSource : NSOutlineViewDataSource
    {
        #region Public Variables
        public List<Product> Products = new List<Product>();
        #endregion

        #region Constructors
        public ProductOutlineDataSource ()
        {
        }
        #endregion

        #region Override Methods
        public override nint GetChildrenCount (NSOutlineView outlineView, NSObject item)
        {
            if (item == null) {
                return Products.Count;
            } else {
                return ((Product)item).Products.Count;
            }

        }

        public override NSObject GetChild (NSOutlineView outlineView, nint childIndex, NSObject item)
        {
            if (item == null) {
                return Products [childIndex];
            } else {
                return ((Product)item).Products [childIndex];
            }

        }

        public override bool ItemExpandable (NSOutlineView outlineView, NSObject item)
        {
            if (item == null) {
                return Products [0].IsProductGroup;
            } else {
                return ((Product)item).IsProductGroup;
            }

        }
        #endregion
    }
}

Cette classe dispose d’un stockage pour les éléments de notre mode Plan et remplace le GetChildrenCount nombre de lignes dans le tableau. Renvoie GetChild un élément parent ou enfant spécifique (tel que demandé par l’affichage hiérarchique) et définit ItemExpandable l’élément spécifié en tant que parent ou enfant.

Enfin, nous devons créer une sous-classe permettant de NSOutlineDelegate fournir le comportement de notre plan. Dans le Explorateur de solutions, cliquez avec le bouton droit sur le projet, puis sélectionnez Ajouter>un nouveau fichier... Sélectionnez Classe vide générale>, entrez ProductOutlineDelegate le nom, puis cliquez sur le bouton Nouveau.

Modifiez le ProductOutlineDelegate.cs fichier et faites-le ressembler à ce qui suit :

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

namespace MacOutlines
{
    public class ProductOutlineDelegate : NSOutlineViewDelegate
    {
        #region Constants
        private const string CellIdentifier = "ProdCell";
        #endregion

        #region Private Variables
        private ProductOutlineDataSource DataSource;
        #endregion

        #region Constructors
        public ProductOutlineDelegate (ProductOutlineDataSource datasource)
        {
            this.DataSource = datasource;
        }
        #endregion

        #region Override Methods

        public override NSView GetView (NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item) {
            // This pattern allows you reuse existing views when they are no-longer in use.
            // If the returned view is null, you instance up a new view
            // If a non-null view is returned, you modify it enough to reflect the new data
            NSTextField view = (NSTextField)outlineView.MakeView (CellIdentifier, this);
            if (view == null) {
                view = new NSTextField ();
                view.Identifier = CellIdentifier;
                view.BackgroundColor = NSColor.Clear;
                view.Bordered = false;
                view.Selectable = false;
                view.Editable = false;
            }

            // Cast item
            var product = item as Product;

            // Setup view based on the column selected
            switch (tableColumn.Title) {
            case "Product":
                view.StringValue = product.Title;
                break;
            case "Details":
                view.StringValue = product.Description;
                break;
            }

            return view;
        }
        #endregion
    }
}

Lorsque nous créons une instance du ProductOutlineDelegate, nous transmettons également une instance du ProductOutlineDataSource plan qui fournit les données du plan. La GetView méthode est responsable du renvoi d’une vue (données) pour afficher la cellule d’une colonne et d’une ligne donner. Si possible, une vue existante sera réutilisée pour afficher la cellule, sinon une nouvelle vue doit être créée.

Pour remplir le plan, nous allons modifier le MainWindow.cs fichier et faire en sorte que la AwakeFromNib méthode ressemble à ce qui suit :

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

    // Create data source and populate
    var DataSource = new ProductOutlineDataSource ();

    var Vegetables = new Product ("Vegetables", "Greens and Other Produce");
    Vegetables.Products.Add (new Product ("Cabbage", "Brassica oleracea - Leaves, axillary buds, stems, flowerheads"));
    Vegetables.Products.Add (new Product ("Turnip", "Brassica rapa - Tubers, leaves"));
    Vegetables.Products.Add (new Product ("Radish", "Raphanus sativus - Roots, leaves, seed pods, seed oil, sprouting"));
    Vegetables.Products.Add (new Product ("Carrot", "Daucus carota - Root tubers"));
    DataSource.Products.Add (Vegetables);

    var Fruits = new Product ("Fruits", "Fruit is a part of a flowering plant that derives from specific tissues of the flower");
    Fruits.Products.Add (new Product ("Grape", "True Berry"));
    Fruits.Products.Add (new Product ("Cucumber", "Pepo"));
    Fruits.Products.Add (new Product ("Orange", "Hesperidium"));
    Fruits.Products.Add (new Product ("Blackberry", "Aggregate fruit"));
    DataSource.Products.Add (Fruits);

    var Meats = new Product ("Meats", "Lean Cuts");
    Meats.Products.Add (new Product ("Beef", "Cow"));
    Meats.Products.Add (new Product ("Pork", "Pig"));
    Meats.Products.Add (new Product ("Veal", "Young Cow"));
    DataSource.Products.Add (Meats);

    // Populate the outline
    ProductOutline.DataSource = DataSource;
    ProductOutline.Delegate = new ProductOutlineDelegate (DataSource);

}

Si nous exécutons l’application, les éléments suivants s’affichent :

Vue réduite

Si nous développons un nœud en mode Plan, il se présente comme suit :

Vue développée

Tri par colonne

Permettez à l’utilisateur de trier les données dans le plan en cliquant sur un en-tête de colonne. Tout d’abord, double-cliquez sur le Main.storyboard fichier pour l’ouvrir pour modification dans le Générateur d’interface. Sélectionnez la Product colonne, entrez Title la clé de tri, compare: pour le sélecteur et sélectionnez Ascending l’ordre :

Définition de l’ordre des touches de tri

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

Nous allons maintenant modifier le ProductOutlineDataSource.cs fichier et ajouter les méthodes suivantes :

public void Sort(string key, bool ascending) {

    // Take action based on key
    switch (key) {
    case "Title":
        if (ascending) {
            Products.Sort ((x, y) => x.Title.CompareTo (y.Title));
        } else {
            Products.Sort ((x, y) => -1 * x.Title.CompareTo (y.Title));
        }
        break;
    }
}

public override void SortDescriptorsChanged (NSOutlineView outlineView, NSSortDescriptor[] oldDescriptors)
{
    // Sort the data
    Sort (oldDescriptors [0].Key, oldDescriptors [0].Ascending);
    outlineView.ReloadData ();
}

La Sort méthode nous permet de trier les données dans la source de données en fonction d’un champ de classe donné Product dans l’ordre croissant ou décroissant. La méthode substituée SortDescriptorsChanged est appelée chaque fois que l’utilisation clique sur un en-tête de colonne. Il est passé la valeur clé que nous définissons dans le Générateur d’interface et l’ordre de tri de cette colonne.

Si nous exécutons l’application et cliquez dans les en-têtes de colonne, les lignes seront triées par cette colonne :

Exemple de sortie triée

Sélection de lignes

Si vous souhaitez autoriser l’utilisateur à sélectionner une seule ligne, double-cliquez sur le Main.storyboard fichier pour l’ouvrir pour modification dans Interface Builder. Sélectionnez l’affichage hiérarchique dans la hiérarchie d’interface et annulez case activée la boîte de réception multiple case activée dans l’inspecteur d’attributs :

Capture d’écran montrant l’inspecteur d’attribut dans lequel vous pouvez modifier le paramètre Multiple.

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

Ensuite, modifiez le ProductOutlineDelegate.cs fichier et ajoutez la méthode suivante :

public override bool ShouldSelectItem (NSOutlineView outlineView, NSObject item)
{
    // Don't select product groups
    return !((Product)item).IsProductGroup;
}

Cela permet à l’utilisateur de sélectionner n’importe quelle ligne unique en mode Plan. Revenez false pour tous ShouldSelectItem les éléments que vous ne souhaitez pas que l’utilisateur puisse sélectionner ou false pour chaque élément si vous ne souhaitez pas que l’utilisateur puisse sélectionner des éléments.

Sélection de plusieurs lignes

Si vous souhaitez autoriser l’utilisateur à sélectionner plusieurs lignes, double-cliquez sur le Main.storyboard fichier pour l’ouvrir pour modification dans Interface Builder. Sélectionnez l’affichage Hiérarchique dans la hiérarchie d’interface et case activée la boîte de réception Multiple case activée dans l’inspecteur d’attribut :

Capture d’écran montrant l’inspecteur d’attribut dans lequel vous pouvez sélectionner Multiple.

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

Ensuite, modifiez le ProductOutlineDelegate.cs fichier et ajoutez la méthode suivante :

public override bool ShouldSelectItem (NSOutlineView outlineView, NSObject item)
{
    // Don't select product groups
    return !((Product)item).IsProductGroup;
}

Cela permet à l’utilisateur de sélectionner n’importe quelle ligne unique en mode Plan. Revenez false pour tous ShouldSelectRow les éléments que vous ne souhaitez pas que l’utilisateur puisse sélectionner ou false pour chaque élément si vous ne souhaitez pas que l’utilisateur puisse sélectionner des éléments.

Tapez pour sélectionner une ligne

Si vous souhaitez permettre à l’utilisateur de taper un caractère avec l’affichage hiérarchique sélectionné et de sélectionner la première ligne contenant ce caractère, double-cliquez sur le Main.storyboard fichier pour l’ouvrir pour modification dans le Générateur d’interface. Sélectionnez l’affichage hiérarchique dans la hiérarchie d’interface et case activée la zone Sélectionner case activée dans l’inspecteur d’attributs :

Modification du type de ligne

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

Nous allons maintenant modifier le ProductOutlineDelegate.cs fichier et ajouter la méthode suivante :

public override NSObject GetNextTypeSelectMatch (NSOutlineView outlineView, NSObject startItem, NSObject endItem, string searchString)
{
    foreach(Product product in DataSource.Products) {
        if (product.Title.Contains (searchString)) {
            return product;
        }
    }

    // Not found
    return null;
}

La GetNextTypeSelectMatch méthode prend l’élément donné searchString et retourne l’élément du premier Product qui a cette chaîne dans elle est Title.

Réorganiser les colonnes

Si vous souhaitez permettre à l’utilisateur de faire glisser des colonnes réorganisées en mode Plan, double-cliquez sur le Main.storyboard fichier pour l’ouvrir pour modification dans le Générateur d’interface. Sélectionnez l’affichage hiérarchique dans la hiérarchie d’interface et case activée la zone de réorganisation case activée dans l’inspecteur d’attributs :

Capture d’écran montrant l’inspecteur d’attribut dans lequel vous pouvez sélectionner Réorganiser.

Si nous accordons une valeur à la propriété Enregistrement automatique et case activée le champ Informations sur la colonne, toutes les modifications apportées à la disposition de la table seront automatiquement enregistrées pour nous et restaurées la prochaine fois que l’application est exécutée.

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

Nous allons maintenant modifier le ProductOutlineDelegate.cs fichier et ajouter la méthode suivante :

public override bool ShouldReorder (NSOutlineView outlineView, nint columnIndex, nint newColumnIndex)
{
    return true;
}

La ShouldReorder méthode doit retourner true pour n’importe quelle colonne qu’elle souhaite autoriser à faire glisser à nouveau dans le newColumnIndexretour , sinon ;false

Si nous exécutons l’application, nous pouvons faire glisser les en-têtes de colonne autour pour réorganiser nos colonnes :

Exemple de réorganisation des colonnes

Modification des cellules

Si vous souhaitez autoriser l’utilisateur à modifier les valeurs d’une cellule donnée, modifiez le ProductOutlineDelegate.cs fichier et modifiez la GetViewForItem méthode comme suit :

public override NSView GetView (NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item) {
    // Cast item
    var product = item as Product;

    // This pattern allows you reuse existing views when they are no-longer in use.
    // If the returned view is null, you instance up a new view
    // If a non-null view is returned, you modify it enough to reflect the new data
    NSTextField view = (NSTextField)outlineView.MakeView (tableColumn.Title, this);
    if (view == null) {
        view = new NSTextField ();
        view.Identifier = tableColumn.Title;
        view.BackgroundColor = NSColor.Clear;
        view.Bordered = false;
        view.Selectable = false;
        view.Editable = !product.IsProductGroup;
    }

    // Tag view
    view.Tag = outlineView.RowForItem (item);

    // Allow for edit
    view.EditingEnded += (sender, e) => {

        // Grab product
        var prod = outlineView.ItemAtRow(view.Tag) as Product;

        // Take action based on type
        switch(view.Identifier) {
        case "Product":
            prod.Title = view.StringValue;
            break;
        case "Details":
            prod.Description = view.StringValue;
            break;
        }
    };

    // Setup view based on the column selected
    switch (tableColumn.Title) {
    case "Product":
        view.StringValue = product.Title;
        break;
    case "Details":
        view.StringValue = product.Description;
        break;
    }

    return view;
}

Maintenant, si nous exécutons l’application, l’utilisateur peut modifier les cellules dans l’affichage Tableau :

Exemple de modification de cellules

Utilisation d’images dans des vues hiérarchiques

Pour inclure une image dans le cadre de la cellule d’un NSOutlineView, vous devez modifier la façon dont les données sont retournées par la méthode du modeGetViewNSTableViewDelegate'sPlan pour utiliser une NSTableCellView valeur plutôt que la méthode classiqueNSTextField. Par exemple :

public override NSView GetView (NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item) {
    // Cast item
    var product = item as Product;

    // This pattern allows you reuse existing views when they are no-longer in use.
    // If the returned view is null, you instance up a new view
    // If a non-null view is returned, you modify it enough to reflect the new data
    NSTableCellView view = (NSTableCellView)outlineView.MakeView (tableColumn.Title, this);
    if (view == null) {
        view = new NSTableCellView ();
        if (tableColumn.Title == "Product") {
            view.ImageView = new NSImageView (new CGRect (0, 0, 16, 16));
            view.AddSubview (view.ImageView);
            view.TextField = new NSTextField (new CGRect (20, 0, 400, 16));
        } else {
            view.TextField = new NSTextField (new CGRect (0, 0, 400, 16));
        }
        view.TextField.AutoresizingMask = NSViewResizingMask.WidthSizable;
        view.AddSubview (view.TextField);
        view.Identifier = tableColumn.Title;
        view.TextField.BackgroundColor = NSColor.Clear;
        view.TextField.Bordered = false;
        view.TextField.Selectable = false;
        view.TextField.Editable = !product.IsProductGroup;
    }

    // Tag view
    view.TextField.Tag = outlineView.RowForItem (item);

    // Allow for edit
    view.TextField.EditingEnded += (sender, e) => {

        // Grab product
        var prod = outlineView.ItemAtRow(view.Tag) as Product;

        // Take action based on type
        switch(view.Identifier) {
        case "Product":
            prod.Title = view.TextField.StringValue;
            break;
        case "Details":
            prod.Description = view.TextField.StringValue;
            break;
        }
    };

    // Setup view based on the column selected
    switch (tableColumn.Title) {
    case "Product":
        view.ImageView.Image = NSImage.ImageNamed (product.IsProductGroup ? "tags.png" : "tag.png");
        view.TextField.StringValue = product.Title;
        break;
    case "Details":
        view.TextField.StringValue = product.Description;
        break;
    }

    return view;
}

Pour plus d’informations, consultez la section Utilisation d’images avec vues hiérarchiques de notre documentation Working with Image .

Vues hiérarchiques de liaison de données

En utilisant des techniques de codage clé-valeur et de liaison de données dans votre application Xamarin.Mac, vous pouvez réduire considérablement la quantité de code que vous devez écrire et gérer pour remplir et utiliser des éléments d’interface utilisateur. Vous bénéficiez également d’un découplage supplémentaire de vos données de stockage (modèle de données) de votre interface utilisateur frontale (modèle-vue-contrôleur), ce qui facilite la maintenance et la conception d’applications plus flexibles.

Le codage clé-valeur (KVC) est un mécanisme permettant d’accéder indirectement aux propriétés d’un objet, à l’aide de clés (chaînes spécialement mises en forme) pour identifier les propriétés au lieu de les accéder via des variables d’instance ou des méthodes d’accesseur (get/set). En implémentant des accesseurs conformes au codage clé-valeur dans votre application Xamarin.Mac, vous accédez à d’autres fonctionnalités macOS telles que l’observation de valeur clé (KVO), la liaison de données, les données principales, les liaisons Cocoa et la scriptabilité.

Pour plus d’informations, consultez la section Structure de la liaison de données de notre documentation sur la liaison de données et le codage clé-valeur.

Résumé

Cet article a examiné en détail l’utilisation des vues hiérarchiques dans une application Xamarin.Mac. Nous avons vu les différents types et utilisations des vues hiérarchiques, comment créer et gérer des vues hiérarchiques dans le Générateur d’interface de Xcode et comment utiliser les vues hiérarchiques dans le code C#.