Представления структуры в Xamarin.Mac

В этой статье рассматривается работа с представлениями структуры в приложении Xamarin.Mac. В нем описывается создание и обслуживание представлений структуры в Xcode и Конструкторе интерфейсов и их программное взаимодействие.

При работе с C# и .NET в приложении Xamarin.Mac у вас есть доступ к тем же представлениям структуры, в которых работает Objective-C разработчик и Xcode . Так как Xamarin.Mac интегрируется непосредственно с Xcode, с помощью построителя интерфейсов Xcode можно создавать и поддерживать представления структуры (или при необходимости создавать их непосредственно в коде C#).

Представление структуры — это тип таблицы, которая позволяет пользователю развертывать или свернуть строки иерархических данных. Как и в представлении таблицы, представление структуры отображает данные для набора связанных элементов с строками, представляющими отдельные элементы и столбцы, представляющие атрибуты этих элементов. В отличие от представления таблицы элементы в представлении структуры не находятся в неструктурированном списке, они упорядочены в иерархии, например в файлах и папках на жестком диске.

An example app run

В этой статье мы рассмотрим основы работы с представлениями структуры в приложении Xamarin.Mac. Настоятельно рекомендуется сначала ознакомиться со статьей Hello, Mac , в частности в разделах "Введение в Xcode" и "Конструктор интерфейсов" и "Торговых точек" и "Действия ", поскольку рассматриваются основные понятия и методы, которые мы будем использовать в этой статье.

Вы можете ознакомиться с классами И методами C# вObjective-Cразделе документа Xamarin.Mac Internals, а также объяснить RegisterExport команды, используемые для подключения классов C# к Objective-C объектам и элементам пользовательского интерфейса.

Общие сведения о представлениях структуры

Представление структуры — это тип таблицы, которая позволяет пользователю развертывать или свернуть строки иерархических данных. Как и в представлении таблицы, представление структуры отображает данные для набора связанных элементов с строками, представляющими отдельные элементы и столбцы, представляющие атрибуты этих элементов. В отличие от представления таблицы элементы в представлении структуры не находятся в неструктурированном списке, они упорядочены в иерархии, например в файлах и папках на жестком диске.

Если элемент в представлении структуры содержит другие элементы, его можно развернуть или свернуть пользователем. Развернутый элемент отображает треугольник раскрытия, указывающий справа, когда элемент свернут и указывает вниз при развертывании элемента. Нажатие треугольника раскрытия приводит к тому, что элемент будет развернут или свернут.

Представление структуры (NSOutlineView) является подклассом представления таблицы (NSTableView) и таким образом наследует большую часть его поведения от родительского класса. В результате многие операции, поддерживаемые представлением таблицы, например выбор строк или столбцов, изменение положения столбцов путем перетаскивания заголовков столбцов и т. д., также поддерживаются представлением структуры. Приложение Xamarin.Mac управляет этими функциями и может настроить параметры представления структуры (в коде или построителе интерфейсов) для разрешения или запрета определенных операций.

Представление структуры не сохраняет собственные данные, а использует источник данных (NSOutlineViewDataSource) для предоставления строк и столбцов, необходимых по мере необходимости.

Поведение представления структуры можно настроить, предоставив подкласс делегата представления структуры (NSOutlineViewDelegate) для поддержки управления столбцами структуры, типа для выбора функций, выбора строк и редактирования, пользовательского отслеживания и пользовательских представлений для отдельных столбцов и строк.

Так как представление структуры использует большую часть его поведения и функциональных возможностей с представлением таблицы, вам может потребоваться перейти к нашей документации по представлениям таблиц, прежде чем продолжить работу с этой статьей.

Создание и обслуживание представлений структуры в Xcode

При создании нового приложения Xamarin.Mac Cocoa вы получаете стандартное пустое окно по умолчанию. Эти окна определяются в файле, который автоматически включается в .storyboard проект. Чтобы изменить дизайн окон, в Обозреватель решений дважды щелкните Main.storyboard файл:

Selecting the main storyboard

Откроется конструктор окон в построителе интерфейсов Xcode:

Editing the UI in Xcode

Введите outline в поле поиска инспектора библиотеки, чтобы упростить поиск элементов управления "Представление структуры":

Selecting an Outline View from the Library

Перетащите представление структуры в контроллер представления в редакторе интерфейса, заполните область содержимого контроллера представления и установите его на место сжатия и роста окна в редакторе ограничений:

Editing the constraints

Выберите представление структуры в иерархии интерфейса и в инспекторе атрибутов доступны следующие свойства:

Screenshot shows the properties available in the Attribute Inspector.

  • Столбец структуры — столбец таблицы, в котором отображаются иерархические данные.
  • Автосохранение столбца структуры . Если trueстолбец структуры будет автоматически сохранен и восстановлен между запуском приложения.
  • Отступ — сумма отступа столбцов под развернутым элементом.
  • Отступ следует за ячейками . Если trueзнак отступа будет отступен вместе с ячейками.
  • Автосохранение развернутых элементов — если trueразвернутое или свернутое состояние элементов будет автоматически сохранено и восстановлено между выполнением приложения.
  • Режим содержимого— позволяет использовать представления (NSView) или ячейки (NSCell) для отображения данных в строках и столбцах. Начиная с macOS 10.7, следует использовать представления.
  • Строки группы с плавающей запятой — если trueпредставление таблицы нарисует сгруппированные ячейки, как если бы они плавали.
  • Столбцы — определяет количество отображаемых столбцов.
  • Заголовки — если trueстолбцы будут иметь заголовки.
  • Переупорядочение — если trueпользователь сможет перетаскивать столбцы в таблице.
  • Изменение размера — если trueпользователь сможет перетащить заголовки столбцов для изменения размера столбцов.
  • Размер столбцов — определяет, как таблица будет автоматически размерить столбцы.
  • Выделение — управляет типом выделения таблицы, используемой при выборе ячейки.
  • Альтернативные строки — если true, когда-либо другая строка будет иметь другой цвет фона.
  • Горизонтальная сетка — выбирает тип границы, рисуемой между ячейками по горизонтали.
  • Вертикальная сетка — выбирает тип границы, рисуемой между ячейками по вертикали.
  • Цвет сетки — задает цвет границы ячейки.
  • Фон — задает цвет фона ячейки.
  • Выбор . Позволяет управлять тем, как пользователь может выбирать ячейки в таблице следующим образом:
    • Несколько — если trueпользователь может выбрать несколько строк и столбцов.
    • Столбец — если trueпользователь может выбрать столбцы.
    • Выбор типа — если trueпользователь может ввести символ, чтобы выбрать строку.
    • Пустое — если trueпользователю не требуется выбрать строку или столбец, таблица не позволяет выбирать ни в коем случае.
  • Автосохранение — имя, в которое формат таблиц автоматически сохраняется.
  • Сведения о столбцах — если trueпорядок и ширина столбцов будут автоматически сохранены.
  • Разрывы строк— выберите способ обработки разрывов строк ячейки.
  • Усечение последней видимой строки . Если trueячейка будет усечена в данных не может помещаться внутри границ.

Внимание

Если вы не поддерживаете устаревшее приложение Xamarin.Mac, NSView основанные представления структуры должны использоваться для NSCell представлений таблиц на основе. NSCell считается устаревшим и может не поддерживаться в будущем.

Выберите столбец таблицы в иерархии интерфейса, а следующие свойства доступны в инспекторе атрибутов:

Screenshot shows the properties available for the selected table column in the Attribute Inspector.

  • Заголовок — задает заголовок столбца.
  • Выравнивание — установка выравнивания текста в ячейках.
  • Заголовок шрифта — выбирает шрифт для текста заголовка ячейки.
  • Ключ сортировки — это ключ , используемый для сортировки данных в столбце. Оставьте пустым, если пользователь не может сортировать этот столбец.
  • Селектор — это действие , используемое для выполнения сортировки. Оставьте пустым, если пользователь не может сортировать этот столбец.
  • Порядок — это порядок сортировки данных столбцов.
  • Изменение размера — выбирает тип изменения размера столбца.
  • Редактируемый — если trueпользователь может изменять ячейки в таблице на основе ячеек.
  • Скрытый — если trueстолбец скрыт.

Вы также можете изменить размер столбца, перетащив его дескриптор (по вертикали на правой стороне столбца) влево или вправо.

Давайте выделите каждый столбец в представлении таблицы и присвойте первому столбцу заголовокProduct и второй Details.

Выберите представление ячейки таблицы (NSTableViewCell) в иерархии интерфейса и в инспекторе атрибутов доступны следующие свойства:

Screenshot shows the properties available for the selected table cell in the Attribute Inspector.

Это все свойства стандартного представления. Вы также можете изменить размер строк для этого столбца.

Выберите ячейку представления таблицы (по умолчанию это NSTextField) в иерархии интерфейса, а следующие свойства доступны в инспекторе атрибутов:

Screenshot shows the properties available for the selected table view cell in the Attribute Inspector.

У вас будут все свойства стандартного текстового поля, заданные здесь. По умолчанию стандартное текстовое поле используется для отображения данных ячейки в столбце.

Выберите представление ячейки таблицы (NSTableFieldCell) в иерархии интерфейса и в инспекторе атрибутов доступны следующие свойства:

Screenshot shows the properties available for the selected table view cell.

Ниже приведены наиболее важные параметры.

  • Макет . Выберите, как выкладываются ячейки в этом столбце.
  • Использует однострочный режим . Если trueячейка ограничена одной строкой.
  • Первая ширина макета среды выполнения — если trueячейка предпочитает набор ширины (вручную или автоматически) при первом запуске приложения.
  • Действие — управляет при отправке действия редактирования для ячейки.
  • Поведение — определяет, можно ли выбрать или изменить ячейку.
  • Форматированный текст — если trueячейка может отображать отформатированный и стильный текст.
  • Отмена — если trueячейка несет ответственность за его поведение отмены.

Выберите представление ячейки таблицы (NSTableFieldCell) в нижней части столбца таблицы в иерархии интерфейса:

Selecting the table cell view

Это позволяет изменять представление ячеек таблицы, используемое в качестве базового шаблона для всех ячеек, созданных для данного столбца.

Добавление действий и точек

Как и любой другой элемент управления пользовательского интерфейса Cocoa, необходимо предоставить представление структуры, а столбцы и ячейки коду C# с помощью действий и точек (на основе необходимых функций).

Процесс совпадает с любым элементом "Представление структуры", который мы хотим предоставить:

  1. Перейдите в редактор помощника и убедитесь, что ViewController.h выбран файл:

    Selecting the correct .h file

  2. Выберите представление структуры из иерархии интерфейса, щелкните элемент управления и перетащите его в ViewController.h файл.

  3. Создайте выход для представления структуры:ProductOutline

    Screenshot shows an Outlet called ProductOutline in the Attribute Inspector.

  4. Создайте точки для столбцов таблиц, которые также называются ProductColumn и DetailsColumn:

    Screenshot shows an Outlet named DetailsColumn in the Attribute Inspector.

  5. Сохраните изменения и вернитесь в Visual Studio для Mac для синхронизации с Xcode.

Затем мы напишем код, отображая некоторые данные для структуры при запуске приложения.

Заполнение представления структуры

С помощью представления структуры, разработанного в построителе интерфейсов и предоставляемых через выход, необходимо создать код C#, чтобы заполнить его.

Сначала создадим новый Product класс для хранения сведений для отдельных строк и групп вложенных продуктов. В Обозреватель решений щелкните проект правой кнопкой мыши и выберите "Добавить>новый файл" ... Выберите общий>пустой класс, введите Productимя и нажмите кнопку "Создать":

Creating an empty class

Сделайте Product.cs файл следующим образом:

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

Затем необходимо создать подкласс NSOutlineDataSource для предоставления данных для структуры по мере его запроса. В Обозреватель решений щелкните проект правой кнопкой мыши и выберите "Добавить>новый файл" ... Выберите общий>пустой класс, введите ProductOutlineDataSourceимя и нажмите кнопку "Создать".

Измените ProductTableDataSource.cs файл и сделайте его следующим образом:

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

Этот класс содержит хранилище для элементов представления структуры и переопределяет GetChildrenCount количество строк в таблице. Возвращает GetChild определенный родительский или дочерний элемент (как запрашивается представлением структуры) и ItemExpandable определяет указанный элемент как родительский или дочерний элемент.

Наконец, необходимо создать подкласс NSOutlineDelegate , чтобы обеспечить поведение для нашей структуры. В Обозреватель решений щелкните проект правой кнопкой мыши и выберите "Добавить>новый файл" ... Выберите общий>пустой класс, введите ProductOutlineDelegateимя и нажмите кнопку "Создать".

Измените ProductOutlineDelegate.cs файл и сделайте его следующим образом:

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

Когда мы создадим экземпляр объекта, мы также передаем экземпляр ProductOutlineDelegateProductOutlineDataSource объекта, предоставляющего данные для структуры. Метод GetView отвечает за возврат представления (данных) для отображения ячейки для заданного столбца и строки. Если это возможно, существующее представление будет повторно использоваться для отображения ячейки, если она не должна быть создана.

Чтобы заполнить структуру, давайте отредактируем MainWindow.cs файл и создадим AwakeFromNib метод следующим образом:

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

}

Если запустить приложение, отобразится следующее:

The collapsed view

Если развернуть узел в представлении структуры, он будет выглядеть следующим образом:

The expanded view

Сортировка по столбцу

Давайте позволим пользователю отсортировать данные в структуре, щелкнув заголовок столбца. Сначала дважды щелкните Main.storyboard файл, чтобы открыть его для редактирования в Конструкторе интерфейсов. Product Выберите столбец, введите Title ключ compare:сортировки для селектораи выберите Ascending для заказа:

Setting the sort key order

Сохраните изменения и вернитесь к Visual Studio для Mac для синхронизации с Xcode.

Теперь давайте отредактируем ProductOutlineDataSource.cs файл и добавьте следующие методы:

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

Метод Sort позволяет отсортировать данные в источнике данных на основе заданного Product поля класса в порядке возрастания или убывания. Переопределенный SortDescriptorsChanged метод будет вызываться каждый раз, когда используется нажатие заголовка столбца. Он будет передан значение ключа, заданное в конструкторе интерфейсов, и порядок сортировки для этого столбца.

Если запустить приложение и щелкнуть заголовки столбцов, строки будут отсортированы по такому столбцу:

Example of sorted output

Выбор строки

Если вы хотите разрешить пользователю выбрать одну строку, дважды щелкните Main.storyboard файл, чтобы открыть его для редактирования в Конструкторе интерфейсов. Выберите представление структуры в иерархии интерфейса и un проверка поле "Несколько проверка" в инспекторе атрибутов:

Screenshot shows the Attribute Inspector where you can change the Multiple setting.

Сохраните изменения и вернитесь к Visual Studio для Mac для синхронизации с Xcode.

Затем измените ProductOutlineDelegate.cs файл и добавьте следующий метод:

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

Это позволит пользователю выбрать любую одну строку в представлении структуры. Вернитесь false к ShouldSelectItem любому элементу, который не хотите, чтобы пользователь мог выбрать или false для каждого элемента, если вы не хотите, чтобы пользователь мог выбирать элементы.

Выбор нескольких строк

Если вы хотите разрешить пользователю выбрать несколько строк, дважды щелкните Main.storyboard файл, чтобы открыть его для редактирования в Конструкторе интерфейсов. Выберите представление структуры в иерархии интерфейса и проверка поле "Несколько проверка" в инспекторе атрибутов:

Screenshot shows the Attribute Inspector where you can select Multiple.

Сохраните изменения и вернитесь к Visual Studio для Mac для синхронизации с Xcode.

Затем измените ProductOutlineDelegate.cs файл и добавьте следующий метод:

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

Это позволит пользователю выбрать любую одну строку в представлении структуры. Вернитесь false к ShouldSelectRow любому элементу, который не хотите, чтобы пользователь мог выбрать или false для каждого элемента, если вы не хотите, чтобы пользователь мог выбирать элементы.

Тип для выбора строки

Если вы хотите разрешить пользователю вводить символ с выбранным представлением структуры и выбрать первую строку с таким символом, дважды щелкните Main.storyboard файл, чтобы открыть его для редактирования в Конструкторе интерфейсов. Выберите представление структуры в иерархии интерфейса и проверка поле "Выбрать проверка" в инспекторе атрибутов:

Editing the row type

Сохраните изменения и вернитесь к Visual Studio для Mac для синхронизации с Xcode.

Теперь давайте отредактируем ProductOutlineDelegate.cs файл и добавьте следующий метод:

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

Метод GetNextTypeSelectMatch принимает заданный searchString и возвращает элемент первой Product строки, которая содержит строку в ней Title.

Изменение порядка столбцов

Если вы хотите разрешить пользователю перетаскивать столбцы переупорядочения в представлении структуры, дважды щелкните Main.storyboard файл, чтобы открыть его для редактирования в Конструкторе интерфейсов. Выберите представление структуры в иерархии интерфейса и проверка поле "Изменить порядок проверка" в инспекторе атрибутов:

Screenshot shows the Attribute Inspector where you can select Reordering.

Если мы предоставим значение для свойства автосохранение и проверка поле "Сведения о столбцах", все изменения, внесенные в макет таблицы, будут автоматически сохранены для нас и восстановлены при следующем запуске приложения.

Сохраните изменения и вернитесь к Visual Studio для Mac для синхронизации с Xcode.

Теперь давайте отредактируем ProductOutlineDelegate.cs файл и добавьте следующий метод:

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

Метод ShouldReorder должен возвращать true любой столбец, который требуется разрешить переупорядочению в другой newColumnIndexвозвращаемый falseстолбец;

Если мы запускаем приложение, мы можем перетащить заголовки столбцов вокруг, чтобы изменить порядок наших столбцов:

Example of reordering columns

Редактирование ячеек

Если вы хотите разрешить пользователю изменять значения для данной ячейки, измените ProductOutlineDelegate.cs файл и измените GetViewForItem метод следующим образом:

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

Теперь, если мы запустите приложение, пользователь может изменить ячейки в представлении таблицы:

An example of editing cells

Использование изображений в представлениях структуры

Чтобы включить изображение в ячейку в NSOutlineViewячейку, необходимо изменить способ возврата данных методом "Представление структуры NSTableViewDelegate'sGetView " вместо NSTableCellView типичного NSTextField. Например:

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

Дополнительные сведения см. в разделе "Использование изображений с представлениями структуры" в документации по работе с изображением .

Представления структуры привязки данных

Используя методы кодирования ключей и привязки данных в приложении Xamarin.Mac, вы можете значительно уменьшить объем кода, который необходимо написать и поддерживать для заполнения и работы с элементами пользовательского интерфейса. Кроме того, вы можете дополнительно отсогласовать резервные данные (модель данных) с интерфейсного пользовательского интерфейса (model-View-Controller), что упрощает обслуживание, более гибкое проектирование приложений.

Кодирование ключей (KVC) — это механизм косвенного доступа к свойствам объекта с помощью ключей (специально отформатированных строк) для идентификации свойств вместо доступа к ним через переменные экземпляра или методы доступа (get/set). Реализуя соответствующие методы доступа к кодированию ключей в приложении Xamarin.Mac, вы получаете доступ к другим функциям macOS, таким как наблюдение за ключевым значением (KVO), привязка данных, основные данные, привязки Какао и скрипты.

Дополнительные сведения см. в разделе "Привязка данных представления данных" в документации по привязке данных и кодированию ключа.

Итоги

В этой статье подробно рассматривается работа с представлениями структуры в приложении Xamarin.Mac. Мы видели различные типы и использование представлений структуры, как создавать и поддерживать представления структуры в построителе интерфейсов Xcode и как работать с представлениями структуры в коде C#.