Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
При работе с C# и .NET в приложении Xamarin.Mac у вас есть доступ к тем же диалогам и модальным Windows, в которых работает Objective-C разработчик и Xcode . Так как Xamarin.Mac интегрируется непосредственно с Xcode, вы можете использовать построитель интерфейсов Xcode для создания и поддержания модального Windows (или при необходимости создания их непосредственно в коде C#).
Диалоговое окно отображается в ответ на действие пользователя и обычно предоставляет способы выполнения действия пользователями. Для закрытия диалогового окна требуется ответ от пользователя.
Windows можно использовать в режиме без режима (например, текстовый редактор, который может одновременно открывать несколько документов) или модал (например, диалоговое окно экспорта, которое должно быть отклонено до продолжения приложения).
В этой статье мы рассмотрим основы работы с диалогами и модальными окнами в приложении Xamarin.Mac. Настоятельно рекомендуется сначала ознакомиться со статьей Hello, Mac , в частности в разделах "Введение в Xcode" и "Конструктор интерфейсов" и "Торговых точек" и "Действия ", поскольку рассматриваются основные понятия и методы, которые мы будем использовать в этой статье.
Вы можете ознакомиться с классами И методами C# в Objective-Cразделе документа Xamarin.Mac Internals, а также объяснить Register Export команды, используемые для подключения классов C# к Objective-C объектам и элементам пользовательского интерфейса.
Общие сведения о диалогах
Диалоговое окно отображается в ответ на действие пользователя (например, сохранение файла) и позволяет пользователям выполнить это действие. Для закрытия диалогового окна требуется ответ от пользователя.
По словам Apple, существует три способа представления диалога:
- Модальное диалоговое окно документа — диалоговое окно "Модальный документ" запрещает пользователю делать что-либо другое в заданном документе до тех пор, пока он не будет закрыт.
- Модальное окно приложения — диалоговое окно модального приложения запрещает пользователю взаимодействовать с приложением до тех пор, пока он не будет закрыт.
- Бессерверное диалоговое окно A позволяет пользователям изменять параметры в диалоговом окне при взаимодействии с окном документа.
Модальное окно
Любой стандарт NSWindow можно использовать в качестве настраиваемого диалогового окна, отображая его модально:
Модальные листы диалоговых окон документа
Лист — это модальное диалоговое окно, которое присоединено к заданному окну документа, предотвращая взаимодействие пользователей с окном, пока они не уволят диалоговое окно. Лист присоединяется к окну, из которого она возникает, и только один лист может быть открыт для окна в любое время.
Параметры Windows
Окно параметров — это бессерверное диалоговое окно, содержащее параметры приложения, которые пользователь редко изменяет. Параметры Windows часто включают панель инструментов, которая позволяет пользователю переключаться между различными группами параметров:
Открыть диалоговое окно
Диалоговое окно "Открыть" предоставляет пользователям согласованный способ поиска и открытия элемента в приложении:
Диалоговые окна настройки печати и страницы
macOS предоставляет стандартные диалоговые окна настройки печати и страницы, которые могут отображаться в приложении, чтобы пользователи могли иметь согласованные возможности печати в каждом приложении, которое они используют.
Диалоговое окно печати может отображаться как свободное плавающее диалоговое окно:
Или его можно отобразить как лист:
Диалоговое окно установки страницы может отображаться как свободное диалоговое окно с плавающей запятой:
Или его можно отобразить как лист:
Сохранение диалогов
Диалоговое окно "Сохранить" предоставляет пользователям согласованный способ сохранения элемента в приложении. Диалоговое окно сохранения имеет два состояния: минимальное (также известное как свернутый):
И развернутое состояние:
Диалоговое окно "Минимальное сохранение" также можно отобразить в виде листа:
Как можно развернуть диалоговое окно сохранения:
Дополнительные сведения см. в разделе "Диалоги " руководства по пользовательскому интерфейсу Apple OS X
Добавление модального окна в проект
Помимо основного окна документа, приложению Xamarin.Mac может потребоваться отобразить другие типы окон для пользователя, например настройки или панели инспекторов.
Чтобы добавить новое окно, сделайте следующее:
В Обозреватель решений откройте
Main.storyboardфайл для редактирования в построителе интерфейсов Xcode.Перетащите новый контроллер представления в область конструктора:
В инспекторе удостоверений введите
CustomDialogControllerимя класса:Вернитесь к Visual Studio для Mac, разрешите ему синхронизироваться с Xcode и создать
CustomDialogController.hфайл.Вернитесь к Xcode и создайте интерфейс:
Создайте модальный segue из главного окна приложения к новому контроллеру представления, перетаскивая элемент управления из элемента пользовательского интерфейса, который откроет диалоговое окно в окно диалогового окна. Назначьте идентификатор
ModalSegue:Проводка любых действий и выходов:
Сохраните изменения и вернитесь к Visual Studio для Mac для синхронизации с Xcode.
Сделайте CustomDialogController.cs файл следующим образом:
using System;
using Foundation;
using AppKit;
namespace MacDialog
{
public partial class CustomDialogController : NSViewController
{
#region Private Variables
private string _dialogTitle = "Title";
private string _dialogDescription = "Description";
private NSViewController _presentor;
#endregion
#region Computed Properties
public string DialogTitle {
get { return _dialogTitle; }
set { _dialogTitle = value; }
}
public string DialogDescription {
get { return _dialogDescription; }
set { _dialogDescription = value; }
}
public NSViewController Presentor {
get { return _presentor; }
set { _presentor = value; }
}
#endregion
#region Constructors
public CustomDialogController (IntPtr handle) : base (handle)
{
}
#endregion
#region Override Methods
public override void ViewWillAppear ()
{
base.ViewWillAppear ();
// Set initial title and description
Title.StringValue = DialogTitle;
Description.StringValue = DialogDescription;
}
#endregion
#region Private Methods
private void CloseDialog() {
Presentor.DismissViewController (this);
}
#endregion
#region Custom Actions
partial void AcceptDialog (Foundation.NSObject sender) {
RaiseDialogAccepted();
CloseDialog();
}
partial void CancelDialog (Foundation.NSObject sender) {
RaiseDialogCanceled();
CloseDialog();
}
#endregion
#region Events
public EventHandler DialogAccepted;
internal void RaiseDialogAccepted() {
if (this.DialogAccepted != null)
this.DialogAccepted (this, EventArgs.Empty);
}
public EventHandler DialogCanceled;
internal void RaiseDialogCanceled() {
if (this.DialogCanceled != null)
this.DialogCanceled (this, EventArgs.Empty);
}
#endregion
}
}
Этот код предоставляет несколько свойств, чтобы задать заголовок и описание диалогового окна, а также несколько событий для реагирования на отмену или принятие диалогового окна.
Затем измените ViewController.cs файл, переопределите PrepareForSegue метод и сделайте его следующим образом:
public override void PrepareForSegue (NSStoryboardSegue segue, NSObject sender)
{
base.PrepareForSegue (segue, sender);
// Take action based on the segue name
switch (segue.Identifier) {
case "ModalSegue":
var dialog = segue.DestinationController as CustomDialogController;
dialog.DialogTitle = "MacDialog";
dialog.DialogDescription = "This is a sample dialog.";
dialog.DialogAccepted += (s, e) => {
Console.WriteLine ("Dialog accepted");
DismissViewController (dialog);
};
dialog.Presentor = this;
break;
}
}
Этот код инициализирует segue, определенный в построителе интерфейсов Xcode в нашем диалоговом окне, и настраивает заголовок и описание. Он также обрабатывает выбор пользователя в диалоговом окне.
Мы можем запустить приложение и отобразить настраиваемое диалоговое окно:
Дополнительные сведения об использовании окон в приложении Xamarin.Mac см. в нашей документации по Работе с Windows .
Создание настраиваемого листа
Лист — это модальное диалоговое окно, которое присоединено к заданному окну документа, предотвращая взаимодействие пользователей с окном, пока они не уволят диалоговое окно. Лист присоединяется к окну, из которого она возникает, и только один лист может быть открыт для окна в любое время.
Чтобы создать пользовательский лист в Xamarin.Mac, давайте сделаем следующее:
В Обозреватель решений откройте
Main.storyboardфайл для редактирования в построителе интерфейсов Xcode.Перетащите новый контроллер представления в область конструктора:
Проектирование пользовательского интерфейса:
Создайте сег листа из главного окна на новый контроллер представления:
В инспекторе удостоверений назовите класс
SheetViewControllerконтроллера представления:Определите все необходимые точки и действия:
Сохраните изменения и вернитесь к Visual Studio для Mac для синхронизации.
Затем измените SheetViewController.cs файл и сделайте его следующим образом:
using System;
using Foundation;
using AppKit;
namespace MacDialog
{
public partial class SheetViewController : NSViewController
{
#region Private Variables
private string _userName = "";
private string _password = "";
private NSViewController _presentor;
#endregion
#region Computed Properties
public string UserName {
get { return _userName; }
set { _userName = value; }
}
public string Password {
get { return _password;}
set { _password = value;}
}
public NSViewController Presentor {
get { return _presentor; }
set { _presentor = value; }
}
#endregion
#region Constructors
public SheetViewController (IntPtr handle) : base (handle)
{
}
#endregion
#region Override Methods
public override void ViewWillAppear ()
{
base.ViewWillAppear ();
// Set initial values
NameField.StringValue = UserName;
PasswordField.StringValue = Password;
// Wireup events
NameField.Changed += (sender, e) => {
UserName = NameField.StringValue;
};
PasswordField.Changed += (sender, e) => {
Password = PasswordField.StringValue;
};
}
#endregion
#region Private Methods
private void CloseSheet() {
Presentor.DismissViewController (this);
}
#endregion
#region Custom Actions
partial void AcceptSheet (Foundation.NSObject sender) {
RaiseSheetAccepted();
CloseSheet();
}
partial void CancelSheet (Foundation.NSObject sender) {
RaiseSheetCanceled();
CloseSheet();
}
#endregion
#region Events
public EventHandler SheetAccepted;
internal void RaiseSheetAccepted() {
if (this.SheetAccepted != null)
this.SheetAccepted (this, EventArgs.Empty);
}
public EventHandler SheetCanceled;
internal void RaiseSheetCanceled() {
if (this.SheetCanceled != null)
this.SheetCanceled (this, EventArgs.Empty);
}
#endregion
}
}
Затем измените ViewController.cs файл, измените PrepareForSegue метод и сделайте его следующим образом:
public override void PrepareForSegue (NSStoryboardSegue segue, NSObject sender)
{
base.PrepareForSegue (segue, sender);
// Take action based on the segue name
switch (segue.Identifier) {
case "ModalSegue":
var dialog = segue.DestinationController as CustomDialogController;
dialog.DialogTitle = "MacDialog";
dialog.DialogDescription = "This is a sample dialog.";
dialog.DialogAccepted += (s, e) => {
Console.WriteLine ("Dialog accepted");
DismissViewController (dialog);
};
dialog.Presentor = this;
break;
case "SheetSegue":
var sheet = segue.DestinationController as SheetViewController;
sheet.SheetAccepted += (s, e) => {
Console.WriteLine ("User Name: {0} Password: {1}", sheet.UserName, sheet.Password);
};
sheet.Presentor = this;
break;
}
}
Если мы запускаем приложение и открываем лист, он будет присоединен к окну:
Создание диалогового окна параметров
Прежде чем выложить представление предпочтений в построителе интерфейсов, необходимо добавить настраиваемый тип segue для обработки переключения параметров. Добавьте новый класс в проект и вызовите его ReplaceViewSeque. Измените класс и сделайте его следующим образом:
using System;
using AppKit;
using Foundation;
namespace MacWindows
{
[Register("ReplaceViewSeque")]
public class ReplaceViewSeque : NSStoryboardSegue
{
#region Constructors
public ReplaceViewSeque() {
}
public ReplaceViewSeque (string identifier, NSObject sourceController, NSObject destinationController) : base(identifier,sourceController,destinationController) {
}
public ReplaceViewSeque (IntPtr handle) : base(handle) {
}
public ReplaceViewSeque (NSObjectFlag x) : base(x) {
}
#endregion
#region Override Methods
public override void Perform ()
{
// Cast the source and destination controllers
var source = SourceController as NSViewController;
var destination = DestinationController as NSViewController;
// Is there a source?
if (source == null) {
// No, get the current key window
var window = NSApplication.SharedApplication.KeyWindow;
// Swap the controllers
window.ContentViewController = destination;
// Release memory
window.ContentViewController?.RemoveFromParentViewController ();
} else {
// Swap the controllers
source.View.Window.ContentViewController = destination;
// Release memory
source.RemoveFromParentViewController ();
}
}
#endregion
}
}
С помощью созданного пользовательского segue можно добавить новое окно в построителе интерфейсов Xcode для обработки наших предпочтений.
Чтобы добавить новое окно, сделайте следующее:
В Обозреватель решений откройте
Main.storyboardфайл для редактирования в построителе интерфейсов Xcode.Перетащите новый контроллер окна в область конструктора:
Упорядочение окна рядом с конструктором строк меню:
Создайте копии подключенного контроллера представления, так как в представлении предпочтений будут вкладки:
Перетащите новый контроллер панели инструментов из библиотеки:
И удалите его в окне в области конструктора:
Макет макета панели инструментов:
Щелкните элемент управления и перетащите с каждой кнопки панели инструментов в созданные выше представления. Выберите тип пользовательского segue:
Выберите новый segue и задайте для класса
ReplaceViewSegueзначение :В конструкторе панели меню в области конструктора в меню "Приложение" выберите "Параметры"..., щелкните элемент управления и перетащите его в окно "Настройки", чтобы создать сеге "Показать":
Сохраните изменения и вернитесь к Visual Studio для Mac для синхронизации.
Если вы запустите код и выберите параметры из меню приложения, откроется окно:
Дополнительные сведения о работе с Windows и панели инструментов см. в нашей документации по Windows и панели инструментов.
Сохранение и загрузка параметров
В обычном приложении macOS, когда пользователь вносит изменения в любой из параметров пользователя приложения, эти изменения сохраняются автоматически. Самый простой способ справиться с этим в приложении Xamarin.Mac — создать один класс для управления всеми предпочтениями пользователя и совместно использовать его на уровне системы.
Сначала добавьте новый AppPreferences класс в проект и наследуйте от NSObjectнего. Параметры будут предназначены для использования привязки данных и кодирования ключа, что сделает процесс создания и поддержания форм предпочтений гораздо проще. Так как параметры будут состоять из небольшого количества простых типов данных, используйте встроенный для NSUserDefaults хранения и извлечения значений.
Измените AppPreferences.cs файл и сделайте его следующим образом:
using System;
using Foundation;
using AppKit;
namespace SourceWriter
{
[Register("AppPreferences")]
public class AppPreferences : NSObject
{
#region Computed Properties
[Export("DefaultLanguage")]
public int DefaultLanguage {
get {
var value = LoadInt ("DefaultLanguage", 0);
return value;
}
set {
WillChangeValue ("DefaultLanguage");
SaveInt ("DefaultLanguage", value, true);
DidChangeValue ("DefaultLanguage");
}
}
[Export("SmartLinks")]
public bool SmartLinks {
get { return LoadBool ("SmartLinks", true); }
set {
WillChangeValue ("SmartLinks");
SaveBool ("SmartLinks", value, true);
DidChangeValue ("SmartLinks");
}
}
// Define any other required user preferences in the same fashion
...
[Export("EditorBackgroundColor")]
public NSColor EditorBackgroundColor {
get { return LoadColor("EditorBackgroundColor", NSColor.White); }
set {
WillChangeValue ("EditorBackgroundColor");
SaveColor ("EditorBackgroundColor", value, true);
DidChangeValue ("EditorBackgroundColor");
}
}
#endregion
#region Constructors
public AppPreferences ()
{
}
#endregion
#region Public Methods
public int LoadInt(string key, int defaultValue) {
// Attempt to read int
var number = NSUserDefaults.StandardUserDefaults.IntForKey(key);
// Take action based on value
if (number == null) {
return defaultValue;
} else {
return (int)number;
}
}
public void SaveInt(string key, int value, bool sync) {
NSUserDefaults.StandardUserDefaults.SetInt(value, key);
if (sync) NSUserDefaults.StandardUserDefaults.Synchronize ();
}
public bool LoadBool(string key, bool defaultValue) {
// Attempt to read int
var value = NSUserDefaults.StandardUserDefaults.BoolForKey(key);
// Take action based on value
if (value == null) {
return defaultValue;
} else {
return value;
}
}
public void SaveBool(string key, bool value, bool sync) {
NSUserDefaults.StandardUserDefaults.SetBool(value, key);
if (sync) NSUserDefaults.StandardUserDefaults.Synchronize ();
}
public string NSColorToHexString(NSColor color, bool withAlpha) {
//Break color into pieces
nfloat red=0, green=0, blue=0, alpha=0;
color.GetRgba (out red, out green, out blue, out alpha);
// Adjust to byte
alpha *= 255;
red *= 255;
green *= 255;
blue *= 255;
//With the alpha value?
if (withAlpha) {
return String.Format ("#{0:X2}{1:X2}{2:X2}{3:X2}", (int)alpha, (int)red, (int)green, (int)blue);
} else {
return String.Format ("#{0:X2}{1:X2}{2:X2}", (int)red, (int)green, (int)blue);
}
}
public NSColor NSColorFromHexString (string hexValue)
{
var colorString = hexValue.Replace ("#", "");
float red, green, blue, alpha;
// Convert color based on length
switch (colorString.Length) {
case 3 : // #RGB
red = Convert.ToInt32(string.Format("{0}{0}", colorString.Substring(0, 1)), 16) / 255f;
green = Convert.ToInt32(string.Format("{0}{0}", colorString.Substring(1, 1)), 16) / 255f;
blue = Convert.ToInt32(string.Format("{0}{0}", colorString.Substring(2, 1)), 16) / 255f;
return NSColor.FromRgba(red, green, blue, 1.0f);
case 6 : // #RRGGBB
red = Convert.ToInt32(colorString.Substring(0, 2), 16) / 255f;
green = Convert.ToInt32(colorString.Substring(2, 2), 16) / 255f;
blue = Convert.ToInt32(colorString.Substring(4, 2), 16) / 255f;
return NSColor.FromRgba(red, green, blue, 1.0f);
case 8 : // #AARRGGBB
alpha = Convert.ToInt32(colorString.Substring(0, 2), 16) / 255f;
red = Convert.ToInt32(colorString.Substring(2, 2), 16) / 255f;
green = Convert.ToInt32(colorString.Substring(4, 2), 16) / 255f;
blue = Convert.ToInt32(colorString.Substring(6, 2), 16) / 255f;
return NSColor.FromRgba(red, green, blue, alpha);
default :
throw new ArgumentOutOfRangeException(string.Format("Invalid color value '{0}'. It should be a hex value of the form #RBG, #RRGGBB or #AARRGGBB", hexValue));
}
}
public NSColor LoadColor(string key, NSColor defaultValue) {
// Attempt to read color
var hex = NSUserDefaults.StandardUserDefaults.StringForKey(key);
// Take action based on value
if (hex == null) {
return defaultValue;
} else {
return NSColorFromHexString (hex);
}
}
public void SaveColor(string key, NSColor color, bool sync) {
// Save to default
NSUserDefaults.StandardUserDefaults.SetString(NSColorToHexString(color,true), key);
if (sync) NSUserDefaults.StandardUserDefaults.Synchronize ();
}
#endregion
}
}
Этот класс содержит несколько вспомогательных подпрограмм, таких как SaveInt, LoadInt, SaveColorи LoadColorт. д. для упрощения работы NSUserDefaults . Кроме того, так как NSUserDefaults не имеет встроенного способа обработки NSColors, NSColorToHexString методы NSColorFromHexString используются для преобразования цветов в шестнадцатеричные строки на основе веб-сайтов (#RRGGBBAA где AA альфа-прозрачность), которые можно легко хранить и извлекать.
AppDelegate.cs В файле создайте экземпляр объекта AppPreferences, который будет использоваться на уровне приложения:
using AppKit;
using Foundation;
using System.IO;
using System;
namespace SourceWriter
{
[Register ("AppDelegate")]
public class AppDelegate : NSApplicationDelegate
{
#region Computed Properties
public int NewWindowNumber { get; set;} = -1;
public AppPreferences Preferences { get; set; } = new AppPreferences();
#endregion
#region Constructors
public AppDelegate ()
{
}
#endregion
...
Параметры подключения к представлениям предпочтений
Затем подключите класс предпочтения к элементам пользовательского интерфейса в окне предпочтения и представлениях, созданных выше. В построителе интерфейсов выберите контроллер представления предпочтений и перейдите в инспектор удостоверений, создайте пользовательский класс для контроллера:
Вернитесь к Visual Studio для Mac для синхронизации изменений и откройте только что созданный класс для редактирования. Сделайте класс следующим образом:
using System;
using Foundation;
using AppKit;
namespace SourceWriter
{
public partial class EditorPrefsController : NSViewController
{
#region Application Access
public static AppDelegate App {
get { return (AppDelegate)NSApplication.SharedApplication.Delegate; }
}
#endregion
#region Computed Properties
[Export("Preferences")]
public AppPreferences Preferences {
get { return App.Preferences; }
}
#endregion
#region Constructors
public EditorPrefsController (IntPtr handle) : base (handle)
{
}
#endregion
}
}
Обратите внимание, что этот класс сделал два действия здесь: во-первых, есть вспомогательное App свойство, чтобы упростить доступ к AppDelegate . Во-вторых, Preferences свойство предоставляет глобальный класс AppPreferences для привязки данных с любыми элементами управления пользовательского интерфейса, размещенными в этом представлении.
Затем дважды щелкните файл раскадровки, чтобы повторно открыть его в построителе интерфейсов (и просмотреть изменения, внесенные выше). Перетащите все элементы управления пользовательского интерфейса, необходимые для создания интерфейса параметров в представлении. Для каждого элемента управления перейдите к инспектору привязки и привязать к отдельным свойствам класса AppPreference :
Повторите описанные выше действия для всех панелей (контроллеров представления) и необходимых свойств предпочтения.
Применение изменений предпочтений ко всем открытым окнам
Как упоминалось выше, в обычном приложении macOS, когда пользователь вносит изменения в любой из параметров пользователя приложения, эти изменения сохраняются автоматически и применяются к любым окнам, которые пользователь может открыть в приложении.
Тщательное планирование и проектирование настроек и окон приложения позволит этому процессу плавно и прозрачно работать с конечным пользователем с минимальным объемом работы по программированию.
Для любого окна, которое будет использовать параметры приложения, добавьте следующее вспомогательное свойство в контроллер представления содержимого, чтобы упростить доступ к нашему AppDelegate :
#region Application Access
public static AppDelegate App {
get { return (AppDelegate)NSApplication.SharedApplication.Delegate; }
}
#endregion
Затем добавьте класс для настройки содержимого или поведения на основе предпочтений пользователя:
public void ConfigureEditor() {
// General Preferences
TextEditor.AutomaticLinkDetectionEnabled = App.Preferences.SmartLinks;
TextEditor.AutomaticQuoteSubstitutionEnabled = App.Preferences.SmartQuotes;
...
}
Необходимо вызвать метод конфигурации при первом открытии окна, чтобы убедиться, что он соответствует предпочтениям пользователя:
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Configure editor from user preferences
ConfigureEditor ();
...
}
Затем измените AppDelegate.cs файл и добавьте следующий метод, чтобы применить любые изменения предпочтений ко всем открытым окнам:
public void UpdateWindowPreferences() {
// Process all open windows
for(int n=0; n<NSApplication.SharedApplication.Windows.Length; ++n) {
var content = NSApplication.SharedApplication.Windows[n].ContentViewController as ViewController;
if (content != null ) {
// Reformat all text
content.ConfigureEditor ();
}
}
}
Затем добавьте PreferenceWindowDelegate класс в проект и сделайте его следующим образом:
using System;
using AppKit;
using System.IO;
using Foundation;
namespace SourceWriter
{
public class PreferenceWindowDelegate : NSWindowDelegate
{
#region Application Access
public static AppDelegate App {
get { return (AppDelegate)NSApplication.SharedApplication.Delegate; }
}
#endregion
#region Computed Properties
public NSWindow Window { get; set;}
#endregion
#region constructors
public PreferenceWindowDelegate (NSWindow window)
{
// Initialize
this.Window = window;
}
#endregion
#region Override Methods
public override bool WindowShouldClose (Foundation.NSObject sender)
{
// Apply any changes to open windows
App.UpdateWindowPreferences();
return true;
}
#endregion
}
}
Это приведет к тому, что все изменения предпочтений будут отправляться во все открытые Окна при закрытии окна предпочтений.
Наконец, измените контроллер окна предпочтения и добавьте делегат, созданный выше:
using System;
using Foundation;
using AppKit;
namespace SourceWriter
{
public partial class PreferenceWindowController : NSWindowController
{
#region Constructors
public PreferenceWindowController (IntPtr handle) : base (handle)
{
}
#endregion
#region Override Methods
public override void WindowDidLoad ()
{
base.WindowDidLoad ();
// Initialize
Window.Delegate = new PreferenceWindowDelegate(Window);
Toolbar.SelectedItemIdentifier = "General";
}
#endregion
}
}
При всех этих изменениях, если пользователь изменяет настройки приложения и закрывает окно предпочтения, изменения будут применены ко всем открытым Окнам Windows:
Диалоговое окно "Открыть"
Диалоговое окно "Открыть" предоставляет пользователям согласованный способ поиска и открытия элемента в приложении. Чтобы открыть диалоговое окно в приложении Xamarin.Mac, используйте следующий код:
var dlg = NSOpenPanel.OpenPanel;
dlg.CanChooseFiles = true;
dlg.CanChooseDirectories = false;
dlg.AllowedFileTypes = new string[] { "txt", "html", "md", "css" };
if (dlg.RunModal () == 1) {
// Nab the first file
var url = dlg.Urls [0];
if (url != null) {
var path = url.Path;
// Create a new window to hold the text
var newWindowController = new MainWindowController ();
newWindowController.Window.MakeKeyAndOrderFront (this);
// Load the text into the window
var window = newWindowController.Window as MainWindow;
window.Text = File.ReadAllText(path);
window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
window.RepresentedUrl = url;
}
}
В приведенном выше коде мы открываем новое окно документа для отображения содержимого файла. Вам потребуется заменить этот код функциональными возможностями приложения.
Следующие свойства доступны при работе с:NSOpenPanel
- CanChooseFiles — если
trueпользователь может выбрать файлы. - CanChooseDirectory — если
trueпользователь может выбрать каталоги. - РазрешитьMultipleSelection — если
trueпользователь может выбрать несколько файлов одновременно. - ResolveAliases — если
trueвыбран и псевдоним, разрешает его путь к исходному файлу. - AllowedFileTypes — это строковый массив типов файлов, которые пользователь может выбрать как расширение или UTI. Значением по умолчанию является
null, что позволяет открывать любой файл.
Метод RunModal () отображает диалоговое окно "Открыть" и позволяет пользователю выбирать файлы или каталоги (как указано в свойствах) и возвращается 1 , если пользователь нажимает кнопку "Открыть ".
Диалоговое окно "Открыть" возвращает выбранные файлы или каталоги пользователя в виде массива URL-адресов в свойстве URL .
Если запустить программу и выбрать элемент Open... в меню "Файл ", отобразится следующее:
Диалоговые окна настройки печати и страницы
macOS предоставляет стандартные диалоговые окна настройки печати и страницы, которые могут отображаться в приложении, чтобы пользователи могли иметь согласованные возможности печати в каждом приложении, которое они используют.
В следующем коде показан стандартный диалог печати:
public bool ShowPrintAsSheet { get; set;} = true;
...
[Export ("showPrinter:")]
void ShowDocument (NSObject sender) {
var dlg = new NSPrintPanel();
// Display the print dialog as dialog box
if (ShowPrintAsSheet) {
dlg.BeginSheet(new NSPrintInfo(),this,this,null,new IntPtr());
} else {
if (dlg.RunModalWithPrintInfo(new NSPrintInfo()) == 1) {
var alert = new NSAlert () {
AlertStyle = NSAlertStyle.Critical,
InformativeText = "We need to print the document here...",
MessageText = "Print Document",
};
alert.RunModal ();
}
}
}
Если для свойства задано ShowPrintAsSheet значение false, запустите приложение и отобразите диалоговое окно печати, отобразится следующее:
Если для свойства задано ShowPrintAsSheet значение true, запустите приложение и отобразите диалоговое окно печати, отобразится следующее:
В следующем коде отобразится диалоговое окно макета страницы:
[Export ("showLayout:")]
void ShowLayout (NSObject sender) {
var dlg = new NSPageLayout();
// Display the print dialog as dialog box
if (ShowPrintAsSheet) {
dlg.BeginSheet (new NSPrintInfo (), this);
} else {
if (dlg.RunModal () == 1) {
var alert = new NSAlert () {
AlertStyle = NSAlertStyle.Critical,
InformativeText = "We need to print the document here...",
MessageText = "Print Document",
};
alert.RunModal ();
}
}
}
Если для свойства задано ShowPrintAsSheet значение false, запустите приложение и отобразите диалоговое окно макета печати, отобразится следующее:
Если для свойства задано ShowPrintAsSheet значение true, запустите приложение и отобразите диалоговое окно макета печати, отобразится следующее:
Дополнительные сведения о работе с диалогами настройки печати и страниц см. в документации apple NSPrintPanel и NSPageLayout .
Диалоговое окно сохранения
Диалоговое окно "Сохранить" предоставляет пользователям согласованный способ сохранения элемента в приложении.
В следующем коде отобразится стандартное диалоговое окно сохранения:
public bool ShowSaveAsSheet { get; set;} = true;
...
[Export("saveDocumentAs:")]
void ShowSaveAs (NSObject sender)
{
var dlg = new NSSavePanel ();
dlg.Title = "Save Text File";
dlg.AllowedFileTypes = new string[] { "txt", "html", "md", "css" };
if (ShowSaveAsSheet) {
dlg.BeginSheet(mainWindowController.Window,(result) => {
var alert = new NSAlert () {
AlertStyle = NSAlertStyle.Critical,
InformativeText = "We need to save the document here...",
MessageText = "Save Document",
};
alert.RunModal ();
});
} else {
if (dlg.RunModal () == 1) {
var alert = new NSAlert () {
AlertStyle = NSAlertStyle.Critical,
InformativeText = "We need to save the document here...",
MessageText = "Save Document",
};
alert.RunModal ();
}
}
}
Это AllowedFileTypes строковый массив типов файлов, которые пользователь может выбрать, чтобы сохранить файл как. Тип файла можно указать как расширение или UTI. Значение по умолчанию — nullэто значение, позволяющее использовать любой тип файла.
Если для свойства задано ShowSaveAsSheet значение false, запустите приложение и выберите "Сохранить как... " в меню "Файл ", отобразится следующее:
Пользователь может развернуть диалоговое окно:
Если для свойства задано ShowSaveAsSheet значение true, запустите приложение и выберите "Сохранить как... " в меню "Файл ", отобразится следующее:
Пользователь может развернуть диалоговое окно:
Дополнительные сведения о работе с диалоговым окном сохранения см. в документации Apple NSSavePanel .
Итоги
В этой статье подробно рассматривается работа с модальными окнами Windows, листами и стандартными системными диалоговых окнами в приложении Xamarin.Mac. Мы видели различные типы и использование модальных окон, листов и диалоговых окон, как создавать модальные окна и листы в построителе интерфейсов Xcode и как работать с модальными окнами, листами и диалогами в коде C#.


































