Partilhar via


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 a criação e a manutenção de exibições de estrutura de tópicos no Xcode e no Construtor de Interfaces 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-C o 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 uma Exibição de Tabela, uma 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 uma Exibição de Tabela, os itens em uma 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 ao Construtor de Interfaces e Saídas e Ações , pois ele aborda os principais conceitos e técnicas que usaremos neste artigo.

Talvez você queira dar uma olhada na seção Expondo classes/métodos C# para Objective-Cdo documento Internos 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 às Exibições 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 uma Exibição de Tabela, uma 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 uma Exibição de Tabela, os itens em uma 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 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 caia.

A Visualização de Estrutura de Tópicos (NSOutlineView) é uma subclasse da Visualizaçã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 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, 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, rastreamento personalizado e exibições personalizadas para colunas e linhas individuais.

Como uma Exibição de Estrutura de Tópicos compartilha muito de seu comportamento e funcionalidade com uma Exibição de Tabela, talvez você queira consultar 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. Esta 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 da Exibição de estrutura de tópicos:

Selecionando uma Visualização de Estrutura de Tópicos na Biblioteca

Arraste uma Exibição de Estrutura de Tópicos para o Controlador de Exibição no Editor de Interface, faça com que ela preencha a área de conteúdo do Controlador de Exibição e defina-a para onde ela encolhe e aumenta com a janela no Editor de Restrição:

Editando as restrições

Selecione a Exibição de Estrutura de Tópicos na Hierarquia de Interface e as seguintes propriedades estarã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 - O valor para recuar colunas em um item expandido.
  • O recuo segue as células - Se true, a marca de recuo será recuada junto com as células.
  • Salvar itens expandidos automaticamente - Se true, o estado expandido/recolhido dos itens será salvo e restaurado automaticamente entre as execuções do aplicativo.
  • Modo de conteúdo - Permite usar Exibições (NSView) ou Células (NSCell) para exibir os dados nas linhas e colunas. A partir do macOS 10.7, você deve usar Visualizações.
  • Linhas de grupo flutuantes - Se true, a 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 e reordenar 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 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 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 pode selecionar colunas.
    • Seleção de tipo - Se true, o usuário poderá digitar um caractere para selecionar uma linha.
    • Vazio - Se trueo , o usuário não precisar selecionar uma linha ou coluna, a tabela não permitirá nenhuma seleção.
  • Salvamento automático - O nome sob o 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 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 em vez de NSCell Exibições de Tabela baseadas. NSCell é considerado legado e pode não ter suporte no futuro.

Selecione uma Coluna da Tabela na Hierarquia da Interface e as seguintes propriedades estarã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 para o texto do cabeçalho da célula.
  • Chave de classificação - É a chave usada para classificar os 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 da coluna.
  • Editável - Se true, o usuário pode editar células em uma tabela baseada em células.
  • Oculto - Se true, a coluna está 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 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 estarã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 uma 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, é 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 estarã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.
  • Largura do layout do primeiro tempo de execução - 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 por seu comportamento de desfazer.

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

Selecionando a visualização da célula da tabela

Isso permite que você edite a Exibição de Célula de Tabela usada como 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 do Cocoa, precisamos expor nosso Modo de 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 queremos 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 a 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 das tabelas , bem chamadas ProductColumn e DetailsColumn:

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

  5. Salve suas 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 a visualizaçã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 Saída, em seguida, precisamos criar o código C# para preenchê-lo.

Primeiro, vamos criar uma nova Product classe para armazenar as informações das 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 Geral>Classe Vazia, 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 NSOutlineDataSource para fornecer os dados para nosso esboço conforme solicitado. No Gerenciador de Soluções, clique com o botão direito do mouse no Projeto e selecione Adicionar>Novo Arquivo... Selecione Geral>Classe Vazia, digite ProductOutlineDataSource para o Nome e clique no botão Novo.

Edite o ProductTableDataSource.cs arquivo e faça com que ele fique parecido 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 nosso Modo de Exibição de Estrutura de Tópicos e substitui o GetChildrenCount para retornar o número de linhas na tabela. O retorna GetChild um item pai ou filho específico (conforme solicitado pela Exibição de Estrutura de Tópicos) e ItemExpandable define o item especificado como pai ou filho.

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

Edite o ProductOutlineDelegate.cs arquivo e faça com que ele fique parecido 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 o esboço. O GetView método é responsável por retornar uma exibição (dados) para exibir a célula de uma determinada coluna e linha. Se possível, uma exibição existente será reutilizada para exibir a célula, caso contrário, uma nova exibição deverá ser criada.

Para preencher a estrutura de tópicos, vamos editar o MainWindow.cs arquivo e fazer com que o AwakeFromNib método se pareça com o seguinte:

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 visualização recolhida

Se expandirmos um nó na Visualização de estrutura de tópicos, ele terá a seguinte aparência:

A visualizaçã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, insira Title para a Chave de classificação, compare: para o Seletor e selecione Ascending para a Ordem:

Definindo a ordem das chaves 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 Cabeçalho de Coluna. Será passado o valor da chave que definimos no Construtor de Interfaces e a ordem de classificação dessa coluna.

Se executarmos o aplicativo e clicarmos nos cabeçalhos das colunas, 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. Selecione a Visualizaçã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, onde você pode alterar a configuração 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 qualquer ShouldSelectItem 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. Selecione a Visualização de Estrutura de Tópicos na Hierarquia de Interface e marque a caixa de seleção Múltiplos 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 qualquer ShouldSelectRow 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 a linha

Se você quiser permitir que o usuário digite um caractere com a Exibição de estrutura de tópicos selecionada 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. Selecione a Visualizaçã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 string em seu Title.

Reordenando colunas

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

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

Se dermos um valor para a propriedade Salvamento automático e marcarmos 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 deseja permitir que seja arrastada reordenada para o newColumnIndex, caso contrário, retorne false;

Se executarmos o aplicativo, podemos arrastar os cabeçalhos das colunas 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 pode editar as células na Visualizaçã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 do GetView NSTableViewDelegate's Modo de Exibição de Estrutura de Tópicos para usar um NSTableCellView em vez do .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 imagens .

Modos de Exibição de Estrutura de Tópicos de Associação de Dados

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

A codificação de valor-chave (KVC) é um mecanismo para acessar as propriedades de um objeto indiretamente, usando chaves (strings 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 Codificação de Chave-Valor em seu aplicativo Xamarin.Mac, você obtém acesso a outros recursos do macOS, como KVO (Observação de Chave-Valor), Associação de Dados, Dados Principais, associações Cocoa e capacidade de script.

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 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#.