Exibições de estrutura de tópicos no Xamarin.Mac

Este artigo aborda o trabalho com exibições de estrutura de tópicos em um aplicativo Xamarin.Mac. Ele descreve como criar e manter exibições de estrutura de tópicos no Xcode e no Construtor de Interfaces e trabalhar com eles programaticamente.

Ao trabalhar com C# e .NET em um aplicativo Xamarin.Mac, você tem acesso às mesmas Exibições de Estrutura de Tópicos em Objective-C que um desenvolvedor trabalha e o Xcode . Como o Xamarin.Mac se integra diretamente ao Xcode, você pode usar o Construtor de Interfaces do Xcode para criar e manter suas Exibições de Estrutura de Tópicos (ou, opcionalmente, criá-las diretamente no código C#).

Um Modo de Exibição de Estrutura de Tópicos é um tipo de Tabela que permite que o usuário expanda ou recolha linhas de dados hierárquicos. Como um Modo de Exibição de Tabela, um Modo de Exibição de Estrutura de Tópicos exibe dados para um conjunto de itens relacionados, com linhas que representam itens individuais e colunas que representam os atributos desses itens. Ao contrário de um Modo de Exibição de Tabela, os itens em um Modo de Exibição de Estrutura de Tópicos não estão em uma lista simples, eles são organizados em uma hierarquia, como arquivos e pastas em um disco rígido.

Um exemplo de execução de aplicativo

Neste artigo, abordaremos as noções básicas de como trabalhar com exibições de estrutura de tópicos em um aplicativo Xamarin.Mac. É altamente recomendável que você trabalhe primeiro no artigo Olá, Mac , especificamente nas seções Introdução ao Xcode e Construtor de Interfaces e Saídas e Ações , pois aborda os principais conceitos e técnicas que usaremos neste artigo.

Talvez você queira dar uma olhada na seção Expondo classes/métodos em C# do Objective-C documento Interno do Xamarin.Mac também, ele explica os Register comandos e Export usados para conectar suas classes C# a Objective-C objetos e elementos de interface do usuário.

Introdução aos modos de exibição de estrutura de tópicos

Um Modo de Exibição de Estrutura de Tópicos é um tipo de Tabela que permite que o usuário expanda ou recolha linhas de dados hierárquicos. Como um Modo de Exibição de Tabela, um Modo de Exibição de Estrutura de Tópicos exibe dados para um conjunto de itens relacionados, com linhas que representam itens individuais e colunas que representam os atributos desses itens. Ao contrário de um Modo de Exibição de Tabela, os itens em um Modo de Exibição de Estrutura de Tópicos não estão em uma lista simples, eles são organizados em uma hierarquia, como arquivos e pastas em um disco rígido.

Se um item em um Modo de Exibição de Estrutura de Tópicos contiver outros itens, ele poderá ser expandido ou recolhido pelo usuário. Um item expansível exibe um triângulo de divulgação, que aponta para a direita quando o item é recolhido e aponta para baixo quando o item é expandido. Clicar no triângulo de divulgação faz com que o item expanda ou recolha.

O Modo de Exibição de Estrutura de Tópicos (NSOutlineView) é uma subclasse do Modo de Exibição de Tabela (NSTableView) e, como tal, herda grande parte de seu comportamento de sua classe pai. Como resultado, muitas operações compatíveis com um Modo de Exibição de Tabela, como selecionar linhas ou colunas, reposicionar colunas arrastando Cabeçalhos de Coluna, etc., também são compatíveis com um Modo de Exibição de Estrutura de Tópicos. Um aplicativo Xamarin.Mac tem controle desses recursos e pode configurar os parâmetros do Modo de Exibição de Estrutura de Tópicos (no código ou no Construtor de Interfaces) para permitir ou não determinadas operações.

Um Modo de Exibição de Estrutura de Tópicos não armazena seus próprios dados, em vez disso, ele depende de uma Fonte de Dados (NSOutlineViewDataSource) para fornecer as linhas e colunas necessárias, conforme necessário.

O comportamento de um Modo de Exibição de Estrutura de Tópicos pode ser personalizado fornecendo uma subclasse do Delegado de Exibição de Estrutura de Tópicos (NSOutlineViewDelegate) para dar suporte ao gerenciamento de colunas de estrutura de tópicos, tipo para selecionar funcionalidade, seleção e edição de linhas, acompanhamento personalizado e exibições personalizadas para colunas e linhas individuais.

Como um Modo de Exibição de Estrutura de Tópicos compartilha grande parte de seu comportamento e funcionalidade com um Modo de Exibição de Tabela, talvez você queira percorrer nossa documentação de Exibições de Tabela antes de continuar com este artigo.

Criando e mantendo exibições de estrutura de tópicos no Xcode

Ao criar um novo aplicativo Xamarin.Mac Cocoa, você obtém uma janela padrão em branco, por padrão. Essa janela é definida em um .storyboard arquivo incluído automaticamente no projeto. Para editar o design do windows, no Gerenciador de Soluções, clique duas vezes no Main.storyboard arquivo:

Selecionando o storyboard main

Isso abrirá o design da janela no Construtor de Interfaces do Xcode:

Editando a interface do usuário no Xcode

Digite outline na Caixa de Pesquisa do Inspetor de Biblioteca para facilitar a localização dos controles de Exibição de Estrutura de Tópicos:

Selecionando um Modo de Exibição de Estrutura de Tópicos na Biblioteca

Arraste um Modo de Exibição de Estrutura de Tópicos para o Controlador de Exibição no Editor de Interface, faça com que ele preencha a área de conteúdo do Controlador de Exibição e defina-o como onde ele é reduzido e cresce com a janela no Editor de Restrições:

Editando as restrições

Selecione o Modo de Exibição de Estrutura de Tópicos na Hierarquia de Interface e as seguintes propriedades estão disponíveis no Inspetor de Atributos:

A captura de tela mostra as propriedades disponíveis no Inspetor de Atributos.

  • Coluna de Estrutura de Tópicos - A Coluna da Tabela na qual os dados hierárquicos são exibidos.
  • Salvar Automaticamente Coluna de Estrutura de Tópicos – Se true, a Coluna de Estrutura de Tópicos será salva e restaurada automaticamente entre as execuções do aplicativo.
  • Recuo – o valor para recuar colunas em um item expandido.
  • Recuo Segue Células - Se true, a Marca de Recuo será recuada junto com as células.
  • Salvamento automático de itens expandidos – se true, o estado expandido/recolhido dos itens será salvo e restaurado automaticamente entre as execuções do aplicativo.
  • Modo de Conteúdo – permite que você use Exibições (NSView) ou Células (NSCell) para exibir os dados nas linhas e colunas. A partir do macOS 10.7, você deve usar Exibições.
  • Floats Group Rows - Se true, o Modo de Exibição de Tabela desenhará células agrupadas como se estivessem flutuando.
  • Colunas – define o número de colunas exibidas.
  • Cabeçalhos – se true, as colunas terão Cabeçalhos.
  • Reordenação – se true, o usuário poderá arrastar novamente as colunas na tabela.
  • Redimensionamento – se true, o usuário poderá arrastar cabeçalhos de coluna para redimensionar colunas.
  • Dimensionamento de coluna – controla como a tabela dimensionará automaticamente as colunas.
  • Realce – controla o tipo de realce que a tabela usa quando uma célula é selecionada.
  • Linhas alternativas – se true, qualquer outra linha terá uma cor de plano de fundo diferente.
  • Grade Horizontal – seleciona o tipo de borda desenhada entre as células horizontalmente.
  • Grade Vertical – seleciona o tipo de borda desenhada entre células verticalmente.
  • Cor da Grade – define a cor da borda da célula.
  • Plano de fundo – define a cor da tela de fundo da célula.
  • Seleção – Permite controlar como o usuário pode selecionar células na tabela como:
    • Múltiplo – se true, o usuário pode selecionar várias linhas e colunas.
    • Coluna – Se true, o usuário poderá selecionar colunas.
    • Digite Select – Se true, o usuário poderá digitar um caractere para selecionar uma linha.
    • Vazio – se true, o usuário não precisa selecionar uma linha ou coluna, a tabela não permite nenhuma seleção.
  • Salvamento automático – o nome no qual o formato de tabelas é salvo automaticamente.
  • Informações da coluna – se true, a ordem e a largura das colunas serão salvas automaticamente.
  • Quebras de linha – selecione como a célula lida com quebras de linha.
  • Trunca a Última Linha Visível – se true, a célula será truncada nos dados não pode caber dentro dos limites.

Importante

A menos que você esteja mantendo um aplicativo Xamarin.Mac herdado, NSView as Exibições de Estrutura de Tópicos baseadas devem ser usadas em modos NSCell de exibição de tabela baseados. NSCell é considerado herdado e pode não ter suporte daqui para frente.

Selecione uma Coluna de Tabela na Hierarquia de Interface e as seguintes propriedades estão disponíveis no Inspetor de Atributos:

A captura de tela mostra as propriedades disponíveis para a coluna de tabela selecionada no Inspetor de Atributos.

  • Título – define o título da coluna.
  • Alinhamento – defina o alinhamento do texto dentro das células.
  • Fonte do Título – seleciona a fonte do texto cabeçalho da célula.
  • Chave de Classificação – é a chave usada para classificar dados na coluna. Deixe em branco se o usuário não puder classificar esta coluna.
  • Seletor – é a Ação usada para executar a classificação. Deixe em branco se o usuário não puder classificar esta coluna.
  • Ordem – é a ordem de classificação para os dados das colunas.
  • Redimensionamento – seleciona o tipo de redimensionamento para a coluna.
  • Editável – se true, o usuário pode editar células em uma tabela baseada em célula.
  • Oculto – se true, a coluna fica oculta.

Você também pode redimensionar a coluna arrastando sua alça (centralizada verticalmente no lado direito da coluna) para a esquerda ou para a direita.

Vamos selecionar cada Coluna em nosso Modo de Exibição de Tabela e dar à primeira coluna um Título de Product e o segundo Details.

Selecione um Modo de Exibição de Célula de Tabela (NSTableViewCell) na Hierarquia de Interface e as seguintes propriedades estão disponíveis no Inspetor de Atributos:

A captura de tela mostra as propriedades disponíveis para a célula da tabela selecionada no Inspetor de Atributos.

Essas são todas as propriedades de um Modo de Exibição padrão. Você também tem a opção de redimensionar as linhas desta coluna aqui.

Selecione uma Célula de Exibição de Tabela (por padrão, esta é uma NSTextField) na Hierarquia de Interface e as seguintes propriedades estão disponíveis no Inspetor de Atributos:

A captura de tela mostra as propriedades disponíveis para a célula de exibição de tabela selecionada no Inspetor de Atributos.

Você terá todas as propriedades de um Campo de Texto padrão para definir aqui. Por padrão, um Campo de Texto padrão é usado para exibir dados de uma célula em uma coluna.

Selecione um Modo de Exibição de Célula de Tabela (NSTableFieldCell) na Hierarquia de Interface e as seguintes propriedades estão disponíveis no Inspetor de Atributos:

A captura de tela mostra as propriedades disponíveis para a célula de exibição de tabela selecionada.

As configurações mais importantes aqui são:

  • Layout – selecione como as células nesta coluna são dispostas.
  • Usa Modo de Linha Única – Se true, a célula é limitada a uma única linha.
  • Largura do Layout do Primeiro Runtime – se true, a célula preferirá a largura definida para ela (manual ou automaticamente) quando for exibida na primeira vez que o aplicativo for executado.
  • Ação – controla quando a Ação de Edição é enviada para a célula.
  • Comportamento – define se uma célula é selecionável ou editável.
  • Rich Text - Se true, a célula pode exibir texto formatado e estilizado.
  • Desfazer – se true, a célula assume a responsabilidade pelo comportamento de desfazer.

Selecione o Modo de Exibição de Célula da Tabela (NSTableFieldCell) na parte inferior de uma Coluna de Tabela na Hierarquia de Interface:

Selecionando o modo de exibição de célula da tabela

Isso permite editar o Modo de Exibição de Célula de Tabela usado como o Padrão base para todas as células criadas para a coluna fornecida.

Adicionando ações e saídas

Assim como qualquer outro controle de interface do usuário cocoa, precisamos expor nossa Exibição de Estrutura de Tópicos e suas colunas e células ao código C# usando Ações e Saídas (com base na funcionalidade necessária).

O processo é o mesmo para qualquer elemento de Exibição de Estrutura de Tópicos que desejamos expor:

  1. Alterne para o Editor Assistente e verifique se o ViewController.h arquivo está selecionado:

    Selecionando o arquivo .h correto

  2. Selecione o Modo de Exibição de Estrutura de Tópicos na Hierarquia de Interface, clique com o controle e arraste para o ViewController.h arquivo.

  3. Crie uma saída para o Modo de Exibição de Estrutura de Tópicos chamado ProductOutline:

    A captura de tela mostra uma Saída chamada ProductOutline no Inspetor de Atributos.

  4. Crie saídas para as colunas de tabelas, bem como chamadas ProductColumn e DetailsColumn:

    A captura de tela mostra uma saída chamada DetailsColumn no Inspetor de Atributos.

  5. Salve as alterações e retorne ao Visual Studio para Mac para sincronizar com o Xcode.

Em seguida, escreveremos o código para exibir alguns dados para a estrutura de tópicos quando o aplicativo for executado.

Preenchendo o modo de exibição de estrutura de tópicos

Com nosso Modo de Exibição de Estrutura de Tópicos projetado no Construtor de Interfaces e exposto por meio de uma Tomada, em seguida, precisamos criar o código C# para preenchê-lo.

Primeiro, vamos criar uma nova Product classe para armazenar as informações para as linhas individuais e grupos de subprodutos. Na Gerenciador de Soluções, clique com o botão direito do mouse no Projeto e selecione Adicionar>Novo Arquivo... SelecioneClasse VaziaGeral>, insira Product para o Nome e clique no botão Novo:

Criando uma classe vazia

Faça com que o Product.cs arquivo se pareça com o seguinte:

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

Em seguida, precisamos criar uma subclasse de NSOutlineDataSource para fornecer os dados para nossa estrutura de tópicos conforme eles são solicitados. Na Gerenciador de Soluções, clique com o botão direito do mouse no Projeto e selecione Adicionar>Novo Arquivo... SelecioneClasse VaziaGeral>, insira ProductOutlineDataSource para o Nome e clique no botão Novo.

Edite o ProductTableDataSource.cs arquivo e faça com que ele se pareça com o seguinte:

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

Essa classe tem armazenamento para os itens do modo de exibição de estrutura de tópicos e substitui o GetChildrenCount para retornar o número de linhas na tabela. O GetChild retorna um item pai ou filho específico (conforme solicitado pelo Modo de Exibição de Estrutura de Tópicos) e ItemExpandable define o item especificado como pai ou filho.

Por fim, precisamos criar uma subclasse de NSOutlineDelegate para fornecer o comportamento para nossa estrutura de tópicos. Na Gerenciador de Soluções, clique com o botão direito do mouse no Projeto e selecione Adicionar>Novo Arquivo... SelecioneClasse VaziaGeral>, insira ProductOutlineDelegate para o Nome e clique no botão Novo.

Edite o ProductOutlineDelegate.cs arquivo e faça com que ele se pareça com o seguinte:

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

Quando criamos uma instância do ProductOutlineDelegate, também passamos uma instância do ProductOutlineDataSource que fornece os dados para a estrutura de tópicos. O GetView método é responsável por retornar uma exibição (dados) para exibir a célula de uma coluna de atribuição e uma linha. Se possível, um modo de exibição existente será reutilizado para exibir a célula, se não for necessário criar uma nova exibição.

Para preencher a estrutura de tópicos, vamos editar o MainWindow.cs arquivo e fazer com que o AwakeFromNib método tenha a seguinte aparência:

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

}

Se executarmos o aplicativo, o seguinte será exibido:

A exibição recolhida

Se expandirmos um nó no Modo de Exibição de Estrutura de Tópicos, ele será semelhante ao seguinte:

O modo de exibição expandido

Classificando por coluna

Vamos permitir que o usuário classifique os dados na estrutura de tópicos clicando em um Cabeçalho de Coluna. Primeiro, clique duas vezes no Main.storyboard arquivo para abri-lo para edição no Interface Builder. Selecione a Product coluna, insira Title para a Chave de Classificação, compare: para o Seletor e selecione Ascending para a Ordem:

Definindo a ordem da chave de classificação

Salve suas alterações e retorne ao Visual Studio para Mac para sincronizar com o Xcode.

Agora, vamos editar o ProductOutlineDataSource.cs arquivo e adicionar os seguintes métodos:

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

O Sort método nos permite classificar os dados na Fonte de Dados com base em um determinado Product campo de classe em ordem crescente ou decrescente. O método substituído SortDescriptorsChanged será chamado sempre que o uso clicar em um Título de Coluna. Ele será passado o valor de Chave que definimos no Construtor de Interfaces e a ordem de classificação para essa coluna.

Se executarmos o aplicativo e clicarmos nos Cabeçalhos de Coluna, as linhas serão classificadas por essa coluna:

Exemplo de saída classificada

Seleção de Linha

Se você quiser permitir que o usuário selecione uma única linha, clique duas vezes no Main.storyboard arquivo para abri-lo para edição no Interface Builder. Selecione o Modo de Exibição de Estrutura de Tópicos na Hierarquia de Interface e desmarque a caixa de seleção Múltiplos no Inspetor de Atributos:

A captura de tela mostra o Inspetor de Atributos em que você pode alterar a configuração Múltiplos.

Salve suas alterações e retorne ao Visual Studio para Mac para sincronizar com o Xcode.

Em seguida, edite o ProductOutlineDelegate.cs arquivo e adicione o seguinte método:

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

Isso permitirá que o usuário selecione qualquer linha única no Modo de Exibição de Estrutura de Tópicos. Retorne false para o ShouldSelectItem para qualquer item que você não deseja que o usuário possa selecionar ou false para cada item se você não quiser que o usuário possa selecionar itens.

Seleção de várias linhas

Se você quiser permitir que o usuário selecione várias linhas, clique duas vezes no Main.storyboard arquivo para abri-lo para edição no Interface Builder. Selecione o Modo de Exibição de Estrutura de Tópicos na Hierarquia de Interface e marcar a caixa de seleção Múltiplos no Inspetor de Atributos:

A captura de tela mostra o Inspetor de Atributos em que você pode selecionar Múltiplo.

Salve suas alterações e retorne ao Visual Studio para Mac para sincronizar com o Xcode.

Em seguida, edite o ProductOutlineDelegate.cs arquivo e adicione o seguinte método:

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

Isso permitirá que o usuário selecione qualquer linha única no Modo de Exibição de Estrutura de Tópicos. Retorne false para o ShouldSelectRow para qualquer item que você não deseja que o usuário possa selecionar ou false para cada item se você não quiser que o usuário possa selecionar itens.

Digite para Selecionar Linha

Se você quiser permitir que o usuário digite um caractere com o Modo de Exibição de Estrutura de Tópicos selecionado e selecione a primeira linha que tem esse caractere, clique duas vezes no Main.storyboard arquivo para abri-lo para edição no Interface Builder. Selecione o Modo de Exibição de Estrutura de Tópicos na Hierarquia da Interface e marcar caixa de seleção Tipo Selecionar no Inspetor de Atributos:

Editando o tipo de linha

Salve suas alterações e retorne ao Visual Studio para Mac para sincronizar com o Xcode.

Agora, vamos editar o ProductOutlineDelegate.cs arquivo e adicionar o seguinte método:

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

O GetNextTypeSelectMatch método usa o determinado searchString e retorna o item do primeiro Product que tem essa cadeia de caracteres em que é Title.

Reordenando colunas

Se você quiser permitir que o usuário arraste reordenar colunas no Modo de Exibição de Estrutura de Tópicos, clique duas vezes no Main.storyboard arquivo para abri-lo para edição no Interface Builder. Selecione o Modo de Exibição de Estrutura de Tópicos na Hierarquia de Interface e marcar caixa de seleção Reordenação no Inspetor de Atributos:

A captura de tela mostra o Inspetor de Atributos em que você pode selecionar Reordenação.

Se fornecermos um valor para a propriedade Salvamento Automático e marcar o campo Informações da Coluna, todas as alterações feitas no layout da tabela serão salvas automaticamente para nós e restauradas na próxima vez que o aplicativo for executado.

Salve suas alterações e retorne ao Visual Studio para Mac para sincronizar com o Xcode.

Agora, vamos editar o ProductOutlineDelegate.cs arquivo e adicionar o seguinte método:

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

O ShouldReorder método deve retornar true para qualquer coluna que deseje permitir que seja arrastada novamente para o newColumnIndex, caso contrário, retorne false;

Se executarmos o aplicativo, poderemos arrastar cabeçalhos de coluna para reordenar nossas colunas:

Exemplo de reordenação de colunas

Editando células

Se você quiser permitir que o usuário edite os valores de uma determinada célula, edite o ProductOutlineDelegate.cs arquivo e altere o GetViewForItem método da seguinte maneira:

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

Agora, se executarmos o aplicativo, o usuário poderá editar as células no Modo de Exibição de Tabela:

Um exemplo de edição de células

Usando imagens em exibições de estrutura de tópicos

Para incluir uma imagem como parte da célula em um NSOutlineView, você precisará alterar como os dados são retornados pelo método da Exibição de NSTableViewDelegate'sGetView Estrutura de Tópicos para usar um NSTableCellView em vez do típico NSTextField. Por exemplo:

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

Para obter mais informações, consulte a seção Usando imagens com exibições de estrutura de tópicos de nossa documentação Trabalhando com imagem .

Exibições da Estrutura de Tópicos de Associação de Dados

Usando Key-Value técnicas de Codificação e Associação de Dados em seu aplicativo Xamarin.Mac, você pode diminuir consideravelmente a quantidade de código que precisa escrever e manter para preencher e trabalhar com elementos da interface do usuário. Você também tem o benefício de desacoplar ainda mais seus dados de backup (Modelo de Dados) da interface do usuário front-end (Model-View-Controller), levando a um design de aplicativo mais fácil de manter e flexível.

Key-Value Coding (KVC) é um mecanismo para acessar indiretamente as propriedades de um objeto, usando chaves (cadeias de caracteres especialmente formatadas) para identificar propriedades em vez de acessá-las por meio de variáveis de instância ou métodos de acessador (get/set). Ao implementar Key-Value acessadores compatíveis com codificação em seu aplicativo Xamarin.Mac, você obtém acesso a outros recursos do macOS, como Key-Value Observing (KVO), Associação de Dados, Dados Principais, Associações cocoa e capacidade de script.

Para obter mais informações, consulte a seção Associação de dados de exibição de estrutura de tópicos da documentação associação de dados e codificação de Key-Value .

Resumo

Este artigo analisou detalhadamente como trabalhar com exibições de estrutura de tópicos em um aplicativo Xamarin.Mac. Vimos os diferentes tipos e usos de Exibições de Estrutura de Tópicos, como criar e manter exibições de estrutura de tópicos no Construtor de Interfaces do Xcode e como trabalhar com exibições de estrutura de tópicos no código C#.