Windows в Xamarin.Mac

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

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

В зависимости от своей цели приложение Xamarin.Mac может представить одну или несколько Windows на экране для управления и координации информации, с которыми она отображается и с которыми работает. Основные функции окна:

  1. Чтобы предоставить область, в которой можно разместить и управлять представлениями и элементами управления.
  2. Чтобы принять и реагировать на события в ответ на взаимодействие пользователя с клавиатурой и мышью.

Windows можно использовать в режиме без режима (например, текстовый редактор, который может одновременно открывать несколько документов) или модал (например, диалоговое окно экспорта, которое должно быть отклонено до продолжения приложения).

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

Редактирование окна в Xcode

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

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

Общие сведения о окнах

Как упоминалось выше, окно предоставляет область, в которой можно размещать представления и элементы управления и управлять и реагировать на события, основанные на взаимодействии с пользователем (с помощью клавиатуры или мыши).

Согласно Apple, существует пять основных типов Windows в приложении macOS:

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

Дополнительные сведения см. в разделе "О Windows" в темах дизайна macOS Apple.

Основные, ключи и неактивные окна

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

Основные и ключевые окна (если они разделены) всегда активны, неактивные Окна открыты, которые не находятся на переднем плане. Например, приложение текстового редактора может одновременно открывать несколько документов, только главное окно будет активным, все остальные будут неактивными.

Дополнительные сведения см. в разделе "О Windows" в темах дизайна macOS Apple.

Окна именования

Окно может отображать строку заголовка и при отображении заголовка обычно это имя приложения, имя рабочего документа или функция окна (например, инспектор). Некоторые приложения не отображают заголовок, так как они распознаются по видимости и не работают с документами.

Apple предлагает следующие рекомендации:

  • Используйте имя приложения для заголовка основного окна, отличного от документа.
  • Назовите новое окно untitledдокумента. Для первого нового документа не добавляйте число к заголовку (например untitled 1). Если пользователь создает еще один документ перед сохранением и вводом текста в первую очередь, вызовите это окно untitled 2и untitled 3т. д.

Дополнительные сведения см. в разделе именования Windows в темах дизайна macOS Apple.

Полноэкранные окна

В macOS окно приложения может скрыть все, в том числе панель меню приложения (которая может быть показана путем перемещения курсора в верхнюю часть экрана), чтобы обеспечить отвлекающее свободное взаимодействие с содержимым.

Apple предлагает следующие рекомендации:

  • Определите, подходит ли окно для полноэкранного режима. Приложения, обеспечивающие краткое взаимодействие (например, калькулятор), не должны предоставлять полноэкранный режим.
  • Отображение панели инструментов, если требуется задача полноэкранного экрана. Обычно панель инструментов скрыта в полноэкранном режиме.
  • В полноэкранном окне должны быть все пользователи функций, необходимые для выполнения задачи.
  • Если это возможно, избегайте взаимодействия Finder, пока пользователь находится в полноэкранном окне.
  • Воспользуйтесь преимуществами увеличенного пространства экрана, не переместив фокус в сторону от основной задачи.

Дополнительные сведения см. в разделе "Полноэкранные окна" в темах оформления macOS Apple.

Панели

Панель — это вспомогательное окно, содержащее элементы управления и параметры, влияющие на активный документ или выбор (например, системный средство выбора цветов):

Цветовая панель

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

Apple предлагает следующие рекомендации:

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

Инспекторов

Большинство современных приложений macOS представляют вспомогательные элементы управления и параметры, влияющие на активный документ или выбор в качестве инспекторов , которые входят в основное окно (например , приложение Pages , показанное ниже), вместо использования Панели Windows:

Пример инспектора

Дополнительные сведения см. в разделе "Панели" в темах дизайна macOS Apple.

Создание и обслуживание окон в Xcode

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

Выбор основной раскадровки

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

Редактирование пользовательского интерфейса в Xcode

В инспекторе атрибутов есть несколько свойств, которые можно использовать для определения и управления окном.

  • Заголовок — это текст, который будет отображаться в заголовке окна.
  • Автосохранение — это ключ , который будет использоваться для идентификации окна при автоматическом сохранении позиции и параметров.
  • Строка заголовка — отображает ли окно строку заголовка.
  • Унифицированный заголовок и панель инструментов. Если окно включает панель инструментов , она должна быть частью строки заголовка.
  • Представление содержимого полного размера — позволяет области содержимого окна находиться в строке заголовка.
  • Тень — имеет ли окно тень.
  • Текстурированные - Текстурированные окна могут использовать эффекты (например, vibrancy) и могут перемещаться вокруг, перетаскивая в любое место их тела.
  • Закрыть — имеет ли окно кнопку закрытия .
  • Свернуть окно с кнопкой свернуть.
  • Изменение размера— имеет ли окно элемент управления изменением размера.
  • Кнопка "Панель инструментов" — есть ли в окне кнопка скрытия или отображения панели инструментов.
  • Можно восстановить. Позиция окна и параметры автоматически сохраняются и восстанавливаются.
  • Видимый при запуске — окно автоматически отображается при .xib загрузке файла.
  • Скрыть деактивацию — окно скрыто, когда приложение входит в фон.
  • Выпуск при закрытии — окно очищается из памяти при закрытии.
  • Подсказки всегда отображаются. Подсказки постоянно отображаются.
  • Перерасчитывает цикл представления . Выполняется пересчет порядка представления перед рисованием окна.
  • Spaces, Exposé и Велоспорт — все определяет, как работает окно в этих средах macOS.
  • Полноэкранный режим— определяет, может ли это окно входить в полноэкранный режим.
  • Анимация — управляет типом анимации, доступной для окна.
  • Внешний вид — управляет внешним видом окна. На данный момент есть только один вид, Aqua.

Дополнительные сведения см. в документации Apple по Windows и NSWindow .

Задание размера и расположения по умолчанию

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

Размер и расположение по умолчанию

Здесь можно задать начальный размер окна, присвоить ему минимальный и максимальный размер, задать начальное расположение на экране и контролировать границы вокруг окна.

Настройка пользовательского контроллера главного окна

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

Выполните следующие действия.

  1. Откройте раскадровку приложения в конструкторе интерфейсов Xcode.

  2. NSWindowController Выберите область конструктора.

  3. Перейдите в представление инспектора удостоверений и введите WindowController имя класса:

    Задание имени класса

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

  5. Файл WindowController.cs будет добавлен в проект в Обозреватель решений в Visual Studio для Mac:

    Выбор контроллера Windows

  6. Откройте раскадровку в построителе интерфейсов Xcode.

  7. Файл WindowController.h будет доступен для использования:

    Редактирование файла WindowController.h

Добавление элементов пользовательского интерфейса

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

Например, давайте перетащите панель инструментов из инспектора библиотеки в окно в редакторе интерфейса:

Выбор панели инструментов из библиотеки

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

Добавление текстового представления

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

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

Щелкнув четыре красных I-Beams в верхней части редактора и нажав кнопку "Добавить 4 ограничения", мы говорим текстовому представлению, чтобы придерживаться заданных координат X,Y и увеличивать или уменьшать по горизонтали и по вертикали по мере изменения размера окна.

Наконец, предоставьте текстовое представление коду с помощью выхода (обязательно выберите ViewController.h файл):

Настройка выхода

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

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

Стандартный рабочий процесс окна

Для любого окна, с которым вы создаете и работаете в приложении Xamarin.Mac, процесс в основном совпадает с тем, что мы только что сделали выше:

  1. Для новых окон, которые не добавляются автоматически в проект, добавьте новое определение окна в проект. Это будет подробно описано ниже.
  2. Дважды щелкните Main.storyboard файл, чтобы открыть макет окна для редактирования в конструкторе интерфейсов Xcode.
  3. Перетащите новое окно в дизайн пользовательского интерфейса и подключите окно в главное окно с помощью segues (дополнительные сведения см. в разделе "Segues" документации по работе с раскадровки).
  4. Задайте все необходимые свойства окна в инспекторе атрибутов и инспекторе размера.
  5. Перетащите элементы управления, необходимые для сборки интерфейса, и настройте их в инспекторе атрибутов.
  6. Используйте инспектор размера для обработки изменения размера элементов пользовательского интерфейса.
  7. Предоставление элементов пользовательского интерфейса окна коду C# через точки и действия.
  8. Сохраните изменения и вернитесь в Visual Studio для Mac для синхронизации с Xcode.

Теперь, когда мы создали базовое окно, мы рассмотрим типичные процессы, выполняемые приложением Xamarin.Mac при работе с окнами.

Отображение окна по умолчанию

По умолчанию новое приложение Xamarin.Mac автоматически отобразит окно, определенное MainWindow.xib в файле при запуске:

Пример окна, выполняющегося

Так как мы изменили макет этого окна выше, теперь он включает панель инструментов по умолчанию и элемент управления "Представление текста". Следующий раздел в Info.plist файле отвечает за отображение этого окна:

Редактирование Info.plist

Раскрывающийся список "Основной интерфейс" используется для выбора раскадровки, которая будет использоваться в качестве основного пользовательского интерфейса приложения (в данном случае Main.storyboard).

Контроллер представления автоматически добавляется в проект для управления отображением основного окна (наряду с основным представлением). Он определен в ViewController.cs файле и присоединен к владельцу файла в построителе интерфейсов в инспекторе удостоверений:

Задание владельца файла

Для нашего окна мы хотели бы иметь заголовок untitled при первом открытии, чтобы переопределить ViewWillAppear метод в ViewController.cs следующем виде:

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

    // Set Window Title
    this.View.Window.Title = "untitled";
}

Примечание.

Свойство окна Title задано в ViewWillAppear методе вместо ViewDidLoad метода, так как, хотя представление может быть загружено в память, оно еще не полностью создано. Title Доступ к свойству в ViewDidLoad методе мы получим null исключение, так как окно еще не было создано и подключено к свойству.

Программное закрытие окна

Может возникнуть время, когда вы хотите программно закрыть окно в приложении Xamarin.Mac, кроме нажатия пользователем кнопки "Закрыть" или с помощью элемента меню. macOS предоставляет два разных способа закрытия программноPerformClose: NSWindow и Close.

ВыполнениеClose

PerformClose Вызов метода NSWindow имитирует пользователя, щелкнув кнопку "Закрыть" окна, моментальным выделением кнопки и закрытием окна.

Если приложение реализует NSWindowWillClose событие, оно будет поднято до закрытия окна. Если событие возвращается false, окно не будет закрыто. Если окно не имеет кнопки закрытия или не может быть закрыто по какой-либо причине, ОС будет выдавать звук оповещения.

Например:

MyWindow.PerformClose(this);

Попытается закрыть MyWindow NSWindow экземпляр. Если это было успешно, окно будет закрыто, в противном случае будет создан звук оповещения и останется открытым.

Закрытие

Close Вызов метода NSWindow не имитирует пользователя, щелкнув кнопку закрытия окна, на мгновение выделите кнопку, просто закрывает окно.

Окно не должно быть видимым, и NSWindowWillCloseNotification уведомление будет размещено в Центре уведомлений по умолчанию для закрытия окна.

Метод Close отличается двумя важными способами от PerformClose метода:

  1. Он не пытается вызвать WillClose событие.
  2. Он не имитирует пользователя, нажав кнопку "Закрыть", на мгновение выделите кнопку.

Например:

MyWindow.Close();

Будет закрывать MyWindow NSWindow экземпляр.

Измененное содержимое окон

В macOS Apple предоставила возможность сообщить пользователю о том, что содержимое окна (NSWindow) было изменено пользователем и должно быть сохранено. Если окно содержит измененное содержимое, в мини-приложении Close отобразится небольшая черная точка:

Окно с измененным маркером

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

Лист сохранения отображается при закрытии окна

Маркировка окна как измененного

Чтобы пометить окно как измененное содержимое, используйте следующий код:

// Mark Window content as modified
Window.DocumentEdited = true;

После сохранения изменения снимите измененный флаг с помощью:

// Mark Window content as not modified
Window.DocumentEdited = false;

Сохранение изменений перед закрытием окна

Чтобы отслеживать закрытие окна и разрешение на сохранение измененного содержимого NSWindowDelegate заранее, необходимо создать подкласс и переопределить его WindowShouldClose метод. Например:

using System;
using AppKit;
using System.IO;
using Foundation;

namespace SourceWriter
{
    public class EditorWindowDelegate : NSWindowDelegate
    {
        #region Computed Properties
        public NSWindow Window { get; set;}
        #endregion

        #region constructors
        public EditorWindowDelegate (NSWindow window)
        {
            // Initialize
            this.Window = window;

        }
        #endregion

        #region Override Methods
        public override bool WindowShouldClose (Foundation.NSObject sender)
        {
            // is the window dirty?
            if (Window.DocumentEdited) {
                var alert = new NSAlert () {
                    AlertStyle = NSAlertStyle.Critical,
                    InformativeText = "Save changes to document before closing window?",
                    MessageText = "Save Document",
                };
                alert.AddButton ("Save");
                alert.AddButton ("Lose Changes");
                alert.AddButton ("Cancel");
                var result = alert.RunSheetModal (Window);

                // Take action based on result
                switch (result) {
                case 1000:
                    // Grab controller
                    var viewController = Window.ContentViewController as ViewController;

                    // Already saved?
                    if (Window.RepresentedUrl != null) {
                        var path = Window.RepresentedUrl.Path;

                        // Save changes to file
                        File.WriteAllText (path, viewController.Text);
                        return true;
                    } else {
                        var dlg = new NSSavePanel ();
                        dlg.Title = "Save Document";
                        dlg.BeginSheet (Window, (rslt) => {
                            // File selected?
                            if (rslt == 1) {
                                var path = dlg.Url.Path;
                                File.WriteAllText (path, viewController.Text);
                                Window.DocumentEdited = false;
                                viewController.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
                                viewController.View.Window.RepresentedUrl = dlg.Url;
                                Window.Close();
                            }
                        });
                        return true;
                    }
                    return false;
                case 1001:
                    // Lose Changes
                    return true;
                case 1002:
                    // Cancel
                    return false;
                }
            }

            return true;
        }
        #endregion
    }
}

Используйте следующий код для присоединения экземпляра этого делегата к окну:

// Set delegate
Window.Delegate = new EditorWindowDelegate(Window);

Сохранение изменений перед закрытием приложения

Наконец, приложение Xamarin.Mac должно проверить, содержит ли любой из его Windows измененное содержимое и позволить пользователю сохранять изменения перед выходом. Для этого измените AppDelegate.cs файл, переопределите ApplicationShouldTerminate метод и сделайте его следующим образом:

public override NSApplicationTerminateReply ApplicationShouldTerminate (NSApplication sender)
{
    // See if any window needs to be saved first
    foreach (NSWindow window in NSApplication.SharedApplication.Windows) {
        if (window.Delegate != null && !window.Delegate.WindowShouldClose (this)) {
            // Did the window terminate the close?
            return NSApplicationTerminateReply.Cancel;
        }
    }

    // Allow normal termination
    return NSApplicationTerminateReply.Now;
}

Работа с несколькими окнами

Большинство приложений Mac на основе документов могут одновременно изменять несколько документов. Например, текстовый редактор может одновременно открывать несколько текстовых файлов. По умолчанию в новом приложении Xamarin.Mac есть меню "Файл" с автоматически проводным элементом "newDocument:Действие".

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

Измените файл и добавьте следующее AppDelegate.cs вычисляемое свойство:

public int UntitledWindowCount { get; set;} =1;

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

Затем добавьте следующий метод:

[Export ("newDocument:")]
void NewDocument (NSObject sender) {
    // Get new window
    var storyboard = NSStoryboard.FromName ("Main", null);
    var controller = storyboard.InstantiateControllerWithIdentifier ("MainWindow") as NSWindowController;

    // Display
    controller.ShowWindow(this);

    // Set the title
    controller.Window.Title = (++UntitledWindowCount == 1) ? "untitled" : string.Format ("untitled {0}", UntitledWindowCount);
}

Этот код создает новую версию контроллера окна, загружает новое окно, делает его основным и ключевым окном и задает его заголовок. Теперь, если мы запустите приложение, и выберите "Создать" в меню "Файл ", откроется и отобразится новое окно редактора:

Добавлено новое окно без названия

Если открыть меню Windows , вы увидите, что приложение автоматически отслеживает и обрабатывает наши открытые окна:

Меню окон

Дополнительные сведения о работе с меню в приложении Xamarin.Mac см. в документации по работе с меню .

Получение активного окна

В приложении Xamarin.Mac, которое может открывать несколько окон (документов), возникает время, когда вам потребуется получить текущее, самое верхнее окно (окно ключа). Следующий код возвращает окно ключа:

var window = NSApplication.SharedApplication.KeyWindow;

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

Доступ ко всем окнам приложений

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

Windows Сохраняет NSApplication.SharedApplication свойство, содержащее массив всех открытых окон в приложении. Вы можете выполнить итерацию по этому массиву, чтобы получить доступ ко всем текущим окнам приложения. Например:

// Is the file already open?
for(int n=0; n<NSApplication.SharedApplication.Windows.Length; ++n) {
    var content = NSApplication.SharedApplication.Windows[n].ContentViewController as ViewController;
    if (content != null && path == content.FilePath) {
        // Bring window to front
        NSApplication.SharedApplication.Windows[n].MakeKeyAndOrderFront(this);
        return true;
    }
}

В примере кода мы приведение каждого возвращаемого окна к пользовательскому классу в нашем приложении и тестирование значения настраиваемого ViewController Path свойства по пути к файлу, который пользователь хочет открыть. Если файл уже открыт, мы переносим это окно на передний план.

Настройка размера окна в коде

Существует время, когда приложению необходимо изменить размер окна в коде. Чтобы изменить размер окна и изменить его положение, вы измените его Frame свойство. При настройке размера окна обычно необходимо также настроить его источник, чтобы сохранить окно в том же расположении из-за системы координат macOS.

В отличие от iOS, где верхний левый угол представляет (0,0), macOS использует математическую систему координат, где нижний левый угол экрана представляет (0,0). В iOS координаты увеличиваются при переходе вниз к правому краю. В macOS координаты увеличиваются вверх к правому краю.

В следующем примере кода изменяется размер окна:

nfloat y = 0;

// Calculate new origin
y = Frame.Y - (768 - Frame.Height);

// Resize and position window
CGRect frame = new CGRect (Frame.X, y, 1024, 768);
SetFrame (frame, true);

Внимание

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

Изменение размера окна мониторинга

Иногда требуется отслеживать изменения размера окна в приложении Xamarin.Mac. Например, чтобы изменить содержимое в соответствии с новым размером.

Чтобы отслеживать изменения размера, сначала убедитесь, что вы назначили пользовательский класс для контроллера окна в построителе интерфейсов Xcode. Например, MasterWindowController в следующем:

Инспектор удостоверений

Затем измените пользовательский класс контроллера окна и отслеживайте DidResize событие в окне контроллера, чтобы получать уведомления об изменениях размера в реальном времени. Например:

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

    Window.DidResize += (sender, e) => {
        // Do something as the window is being live resized
    };
}

При необходимости можно использовать DidEndLiveResize событие только после завершения изменения размера окна. Пример:

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

        Window.DidEndLiveResize += (sender, e) => {
        // Do something after the user's finished resizing
        // the window
    };
}

Задание заголовка окна и представленного файла

При работе с окнами, представляющими документы, имеет DocumentEdited свойство, которое если задано true для отображения небольшой точки в кнопке закрытия, NSWindow чтобы предоставить пользователю указание на изменение файла и его сохранение перед закрытием.

Давайте отредактируем наш ViewController.cs файл и внесите следующие изменения:

public bool DocumentEdited {
    get { return View.Window.DocumentEdited; }
    set { View.Window.DocumentEdited = value; }
}
...

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

    // Set Window Title
    this.View.Window.Title = "untitled";

    View.Window.WillClose += (sender, e) => {
        // is the window dirty?
        if (DocumentEdited) {
            var alert = new NSAlert () {
                AlertStyle = NSAlertStyle.Critical,
                InformativeText = "We need to give the user the ability to save the document here...",
                MessageText = "Save Document",
            };
            alert.RunModal ();
        }
    };
}

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

    // Show when the document is edited
    DocumentEditor.TextDidChange += (sender, e) => {
        // Mark the document as dirty
        DocumentEdited = true;
    };

    // Overriding this delegate is required to monitor the TextDidChange event
    DocumentEditor.ShouldChangeTextInRanges += (NSTextView view, NSValue[] values, string[] replacements) => {
        return true;
    };

}

Мы также отслеживаем WillClose событие в окне и проверяем состояние DocumentEdited свойства. true Если нужно предоставить пользователю возможность сохранить изменения в файле. Если мы запускаем приложение и введем текст, будет отображаться точка:

Измененное окно

Если вы попытаетесь закрыть окно, вы получите оповещение:

Отображение диалогового окна сохранения

Если документ загружается из файла, задайте заголовок окна именем файла с помощью window.SetTitleWithRepresentedFilename (Path.GetFileName(path)); метода (учитывая, что path это строка, представляющая открываемый файл). Кроме того, можно задать URL-адрес файла с помощью window.RepresentedUrl = url; метода.

Если URL-адрес указывает на тип файла, известный ОС, его значок будет отображаться в строке заголовка. Если пользователь щелкает значок правой кнопкой мыши, будет показан путь к файлу.

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

[Export ("openDocument:")]
void OpenDialog (NSObject sender)
{
    var dlg = NSOpenPanel.OpenPanel;
    dlg.CanChooseFiles = true;
    dlg.CanChooseDirectories = false;

    if (dlg.RunModal () == 1) {
        // Nab the first file
        var url = dlg.Urls [0];

        if (url != null) {
            var path = url.Path;

            // Get new window
            var storyboard = NSStoryboard.FromName ("Main", null);
            var controller = storyboard.InstantiateControllerWithIdentifier ("MainWindow") as NSWindowController;

            // Display
            controller.ShowWindow(this);

            // Load the text into the window
            var viewController = controller.Window.ContentViewController as ViewController;
            viewController.Text = File.ReadAllText(path);
                    viewController.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
            viewController.View.Window.RepresentedUrl = url;

        }
    }
}

Теперь, если мы запустите наше приложение, в меню "Файл" выберите текстовый файл в диалоговом окне "Открыть" и откройте его:

Открытое диалоговое окно

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

Содержимое загруженного файла

Добавление нового окна в проект

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

Чтобы добавить новое окно, сделайте следующее:

  1. В Обозреватель решений дважды щелкните Main.storyboard файл, чтобы открыть его для редактирования в построителе интерфейсов Xcode.

  2. Перетащите новый контроллер окна из библиотеки и удалите его на поверхность конструктора:

    Выбор нового контроллера окна в библиотеке

  3. В инспекторе удостоверений введите PreferencesWindow идентификатор раскадровки:

    Задание идентификатора раскадровки

  4. Проектирование интерфейса:

    Проектирование пользовательского интерфейса

  5. Откройте меню приложения (MacWindows), выберите параметры..., щелкните элемент управления и перетащите его в новое окно:

    Создание segue

  6. Выберите "Показать " в всплывающем меню.

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

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

Меню примеров параметров

Работа с панелями

Как указано в начале этой статьи, панель плавает над другими окнами и предоставляет средства или элементы управления, с которыми пользователи могут работать при открытии документов.

Как и любой другой тип окна, с которым вы создаете и работаете в приложении Xamarin.Mac, процесс в основном такой же:

  1. Добавьте новое определение окна в проект.
  2. Дважды щелкните .xib файл, чтобы открыть макет окна для редактирования в конструкторе интерфейсов Xcode.
  3. Задайте все необходимые свойства окна в инспекторе атрибутов и инспекторе размера.
  4. Перетащите элементы управления, необходимые для сборки интерфейса, и настройте их в инспекторе атрибутов.
  5. Используйте инспектор размера для обработки изменения размера элементов пользовательского интерфейса.
  6. Предоставление элементов пользовательского интерфейса окна коду C# через точки и действия.
  7. Сохраните изменения и вернитесь в Visual Studio для Mac для синхронизации с Xcode.

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

Инспектор атрибутов

  • Стиль . Позволяет настроить стиль панели с: обычная панель (выглядит как стандартное окно), панель служебной программы (имеет меньшую строку заголовка), huD Panel (является полупрозрачной, а строка заголовка является частью фона).
  • Без активации — определяется на панели становится окном ключа.
  • Модальный документ — если модал документа, панель будет плавать только над окнами приложения, в противном случае она плавает над всеми.

Чтобы добавить новую панель, сделайте следующее:

  1. В Обозреватель решений щелкните проект правой кнопкой мыши и выберите "Добавить>новый файл...".

  2. В диалоговом окне "Создать файл" выберите окно Какао Xamarin.Mac>с контроллером:

    Добавление нового контроллера окна

  3. Введите в поле Имя значение DocumentPanel и нажмите кнопку Новый.

  4. Дважды щелкните DocumentPanel.xib файл, чтобы открыть его для редактирования в Конструкторе интерфейсов:

    Изменение панели

  5. Удалите существующее окно и перетащите панель из инспектора библиотеки в редакторе интерфейса:

    Удаление существующего окна

  6. Подключите панель к окну - владельца - файла:

    Перетаскивание на проводную панель

  7. Переключитесь на инспектор удостоверений и задайте для класса DocumentPanelПанели значение :

    Задание класса панели

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

  9. Измените файл и измените DocumentPanel.cs определение класса следующим образом:

    public partial class DocumentPanel : NSPanel

  10. Сохраните изменения в файле.

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

public override void DidFinishLaunching (NSNotification notification)
{
        // Display panel
    var panel = new DocumentPanelController ();
    panel.Window.MakeKeyAndOrderFront (this);
}

Если мы запускаем наше приложение, откроется панель:

Панель в работающем приложении

Внимание

Панель Windows устарела apple и должна быть заменена интерфейсами инспекторов.

Итоги

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