Compartilhar via


Modos de exibição de estrutura de tópicos no Xamarin.Mac

Este artigo aborda o trabalho com modos de exibição de estrutura de tópicos em um aplicativo Xamarin.Mac. Ele descreve a criação e manutenção de exibições de estrutura de tópicos no Xcode e no Interface Builder e o trabalho com elas programaticamente.

Ao trabalhar com C# e .NET em um aplicativo Xamarin.Mac, você tem acesso às mesmas Exibições de Estrutura de Tópicos que um desenvolvedor que trabalha e Objective-Co Xcode tem. 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 ao usuário expandir ou recolher 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 representando itens individuais e colunas representando 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.

Uma execução de aplicativo de exemplo

Neste artigo, abordaremos os conceitos básicos de como trabalhar com Modos de Exibição 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 ao Construtor de Interface e Saídas e Ações, pois ele aborda os principais conceitos e técnicas que usaremos neste artigo.

Você pode querer dar uma olhada na seção Expondo classes C# / métodos para Objective-C do documento Xamarin.Mac Internals também, ele explica os Register comandos e Export usados para conectar suas classes C# a Objective-C objetos e elementos da 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 ao usuário expandir ou recolher 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 representando itens individuais e colunas representando 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 abertura, que aponta para a direita quando o item é recolhido e aponta para baixo quando o item é expandido. Clicar no triângulo de abertura faz com que o item se expanda ou entre em colapso.

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 suportadas por uma Exibição de Tabela, como selecionar linhas ou colunas, reposicionar colunas arrastando Cabeçalhos de Coluna, etc., também são suportadas por uma Exibição de Estrutura de Tópicos. Um aplicativo Xamarin.Mac tem controle desses recursos e pode configurar os parâmetros da 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, 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 do Modo de Exibição de Estrutura de Tópicos (NSOutlineViewDelegate) para oferecer suporte ao gerenciamento de colunas de Estrutura de Tópicos, tipo para selecionar funcionalidade, seleção e edição de linhas, controle personalizado e modos de exibição personalizados 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, convém examinar nossa documentação de Modos de Exibição 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 principal

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 do Modo 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 para onde ele diminui 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.
  • Coluna de Estrutura de Tópicos de Salvamento Automático - Se true, a Coluna de Estrutura de Tópicos será salva e restaurada automaticamente entre as execuções do aplicativo.
  • Recuo - A quantidade de colunas de recuo sob um item expandido.
  • Recuo segue células - Se true, a marca de recuo será recuada junto com as células.
  • Itens expandidos de salvamento automático - 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 Modos de Exibição (NSView) ou Células (NSCell) para exibir os dados nas linhas e colunas. A partir do macOS 10.7, você deve usar Visualizações.
  • Flutua Agrupar Linhas - 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 reordenar as colunas na tabela.
  • Redimensionamento - Se true, o usuário poderá arrastar cabeçalhos de coluna para redimensionar colunas.
  • Dimensionamento de Colunas - 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, alguma outra linha terá uma cor 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 as células verticalmente.
  • Cor da grade - Define a cor da borda da célula.
  • Plano de fundo - Define a cor do plano de fundo da célula.
  • Seleção - Permite controlar como o usuário pode selecionar células na tabela como:
    • Múltiplos - Se true, o usuário pode selecionar várias linhas e colunas.
    • Coluna - Se true,o usuário pode selecionar colunas.
    • Tipo Selecionar - Se true, o usuário pode digitar um caractere para selecionar uma linha.
    • Vazio - Se true, o usuário não for obrigado a selecionar uma linha ou coluna, a tabela não permitirá nenhuma seleção.
  • Salvamento automático - O nome no qual o formato das 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 de seus 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 sobre as Exibições de Tabela baseadas em NSCell Tabela. NSCell é considerado legado e pode não ser suportado 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 da 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 do 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 essa coluna.
  • Seletor - É a Ação usada para executar a classificação. Deixe em branco se o usuário não puder classificar essa coluna.
  • Ordem - É a ordem de classificação dos 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 está oculta.

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

Vamos selecionar cada coluna em nossa Exibição de tabela e dar à primeira coluna um título de Product e a segunda Details.

Selecione uma 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 para esta coluna aqui.

Selecione uma Célula de Exibição de Tabela (por padrão, isso é um 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 uma 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 o modo de linha única - Se true, a célula está limitada a uma única linha.
  • First Runtime Layout Width - 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 seu comportamento de desfazer.

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

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

Isso permite que você edite o Modo de Exibição de Célula da Tabela usado como o Padrão base para todas as células criadas para a coluna especificada.

Adicionando ações e saídas

Assim como qualquer outro controle de interface do usuário do 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 a Exibição de Estrutura de Tópicos na Hierarquia de Interface, clique com a tecla Control pressionada e arraste para o ViewController.h arquivo.

  3. Crie uma saída para o Modo de Exibição de Estrutura de Tópicos chamada 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 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 nossa Exibição de Estrutura de Tópicos projetada no Construtor de Interfaces e exposta por meio de um Outlet, 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. No Gerenciador de Soluções, clique com o botão direito do mouse no Projeto e selecione Adicionar>Novo Arquivo... Selecione General>Empty Class, digite Product para o Nome e clique no botão Novo:

Criando uma classe vazia

Faça com que o Product.cs arquivo tenha a seguinte aparência:

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 para fornecer os dados para nossa estrutura de NSOutlineDataSource tópicos conforme solicitado. No Gerenciador de Soluções, clique com o botão direito do mouse no Projeto e selecione Adicionar>Novo Arquivo... Selecione General>Empty Class, digite ProductOutlineDataSource para o Nome e clique no botão Novo.

Edite o ProductTableDataSource.cs arquivo e faça com que ele tenha a seguinte aparência:

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 define ItemExpandable o item especificado como pai ou filho.

Finalmente, precisamos criar uma subclasse de NSOutlineDelegate para fornecer o comportamento para o nosso esboço. No Gerenciador de Soluções, clique com o botão direito do mouse no Projeto e selecione Adicionar>Novo Arquivo... Selecione General>Empty Class, digite ProductOutlineDelegate para o Nome e clique no botão Novo.

Edite o ProductOutlineDelegate.cs arquivo e faça com que ele tenha a seguinte aparência:

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 , também passamos uma instância do ProductOutlineDataSource que fornece os dados para a estrutura de ProductOutlineDelegatetópicos. O GetView método é responsável por retornar uma exibição (dados) para exibir a célula para uma determinada coluna e linha. Se possível, um modo de exibição existente será reutilizado para exibir a célula, se não um novo modo de exibição deve ser criado.

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:

O modo de exibição recolhido

Se expandirmos um nó no Modo de Exibição de Estrutura de Tópicos, ele terá a seguinte aparência:

A visão expandida

Classificação 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 Construtor de Interfaces. Selecione a Product coluna, digite 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 toda vez que o uso clicar em um título de coluna. Será passado o valor de chave que definimos no Construtor de Interface 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 Construtor de Interfaces. Marque o Modo de Exibição de Estrutura de Tópicos na Hierarquia de Interface e desmarque a caixa de seleção Vários no Inspetor de Atributos:

A captura de tela mostra o Inspetor de Atributos, onde 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 nenhum item.

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 Construtor de Interfaces. Marque a Exibição de Estrutura de Tópicos na Hierarquia de Interface e marque a caixa de seleção Vários no Inspetor de Atributos:

A captura de tela mostra o Inspetor de Atributos, onde você pode selecionar 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 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 nenhum item.

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 Construtor de Interfaces. Marque a Exibição de Estrutura de Tópicos na Hierarquia de Interface e marque a caixa de seleção Seleção de Tipo 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 pega o dado searchString e retorna o item do primeiro Product que tem essa cadeia de caracteres em seu Title.

Reordenando colunas

Se você quiser permitir que o usuário arraste colunas de reordenação no Modo de Exibição de Estrutura de Tópicos, clique duas vezes no Main.storyboard arquivo para abri-lo para edição no Construtor de Interfaces. Marque a Exibição de Estrutura de Tópicos na Hierarquia de Interface e marque a caixa de seleção Reordenar no Inspetor de Atributos:

A captura de tela mostra o Inspetor de Atributos, onde você pode selecionar Reordenar.

Se dermos um valor para a propriedade Autosave e verificarmos o campo Informações da Coluna, quaisquer alterações que fizermos 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 ele deseja permitir que seja arrastada reordenada para o newColumnIndex, caso contrário, retorne false;

Se executarmos o aplicativo, podemos 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 modos de exibição 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 doGetViewNSTableViewDelegate'sModo de Exibição de 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 da nossa documentação Trabalhando com imagens .

Exibições de estrutura de tópicos de vinculação de dados

Usando técnicas de codificação de chave-valor e vinculaçã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 suporte (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 mais flexível.

KVC (Key-Value Coding - Codificação de Chave-Valor) é um mecanismo para acessar as propriedades de um objeto indiretamente, 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 acesso (get/set). Ao implementar acessadores compatíveis com Key-Value Coding em seu aplicativo Xamarin.Mac, você obtém acesso a outros recursos do macOS, como KVO (Key-Value Observando), Vinculação de Dados, Dados Principais, Ligações de Cacau e scriptabilidade.

Para obter mais informações, consulte a seção Vinculação de dados de exibição de estrutura de tópicos de nossa documentação de vinculação de dados e codificação de chave-valor.

Resumo

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