Dialogy v Xamarin.Mac
Při práci s jazykem C# a .NET v aplikaci Xamarin.Mac máte přístup ke stejným dialogům a modálnímu Windows, ve kterých vývojář pracuje Objective-C a Xcode . Vzhledem k tomu, že se Xamarin.Mac integruje přímo s Xcode, můžete pomocí Tvůrce rozhraní Xcode vytvořit a udržovat modální windows (nebo je volitelně vytvořit přímo v kódu jazyka C#).
Dialogové okno se zobrazí v reakci na akci uživatele a obvykle poskytuje způsoby, jak můžou uživatelé akci dokončit. Dialogové okno vyžaduje odpověď od uživatele, než ho lze zavřít.
Systém Windows lze použít v bezmodálním stavu (například textový editor, který může mít najednou otevřený více dokumentů) nebo modální (například dialogové okno exportu, které musí být zamítnuto před pokračováním aplikace).
V tomto článku se budeme zabývat základy práce s dialogy a modálními Windows v aplikaci Xamarin.Mac. Důrazně doporučujeme, abyste si nejprve prošli článek Hello, Mac , konkrétně úvod do Xcode a Tvůrce rozhraní a výstupy a akce , protože se zabývá klíčovými koncepty a technikami, které budeme používat v tomto článku.
Možná se také budete chtít podívat na oddíly v dokumentu Interní dokumenty Xamarin.Mac pro zveřejnění tříd a metod Objective-Cjazyka C#. Vysvětluje také, které Register
příkazy a Export
které se používají k připojení tříd jazyka C# k Objective-C objektům a prvkům uživatelského rozhraní.
Úvod do dialogových oken
Dialogové okno se zobrazí v reakci na akci uživatele (například uložení souboru) a poskytuje uživatelům způsob, jak tuto akci dokončit. Dialogové okno vyžaduje odpověď od uživatele, než ho lze zavřít.
Podle Společnosti Apple existují tři způsoby prezentace dialogového okna:
- Modální dokument – Modální dialogové okno dokumentu brání uživateli v provádění čehokoli jiného v daném dokumentu, dokud ho nespustíte.
- Modální aplikace – Dialogové okno Modální aplikace brání uživateli v interakci s aplikací, dokud se nespustí.
- Modeless A Modeless Dialog umožňuje uživatelům měnit nastavení v dialogovém okně a přitom pracovat s oknem dokumentu.
Modální okno
Libovolný standard NSWindow
lze použít jako přizpůsobený dialog tak, že ho zobrazíte modálně:
Modální listy dokumentu
List je modální dialogové okno připojené k danému okně dokumentu, které uživatelům brání v interakci s oknem, dokud dialogové okno nezavřou. List je připojen k oknem, ze kterého se objeví, a současně lze otevřít pouze jeden list pro okno.
Předvolby windows
Okno Předvolby je bezmodální dialogové okno, které obsahuje nastavení aplikace, které uživatel mění zřídka. Okna předvoleb často obsahují panel nástrojů, který uživateli umožňuje přepínat mezi různými skupinami nastavení:
Otevřít dialogové okno
Dialogové okno Otevřít poskytuje uživatelům konzistentní způsob, jak najít a otevřít položku v aplikaci:
Dialogové okno Tisk a vzhled stránky
macOS poskytuje standardní dialogová okna Pro tisk a vzhled stránky, která může aplikace zobrazit, aby uživatelé mohli mít konzistentní možnosti tisku v každé aplikaci, kterou používají.
Dialogové okno Tisk se dá zobrazit jako volné plovoucí dialogové okno:
Nebo ho můžete zobrazit jako list:
Dialogové okno Vzhled stránky se dá zobrazit jako volné plovoucí dialogové okno:
Nebo ho můžete zobrazit jako list:
Uložit dialogy
Dialogové okno Uložit umožňuje uživatelům konzistentní způsob, jak uložit položku v aplikaci. Dialogové okno Uložit má dva stavy: Minimum (označované také jako Sbalené):
A rozbalený stav:
Dialogové okno Minimální uložení lze také zobrazit jako list:
Jak je možné v dialogovém okně Rozbalené uložení:
Další informace najdete v části Dialogy v Pokynech pro lidské rozhraní OS X společnosti Apple .
Přidání modálního okna do projektu
Kromě hlavního okna dokumentu může aplikace Xamarin.Mac potřebovat uživateli zobrazit jiné typy oken, jako jsou předvolby nebo panely inspektoru.
Pokud chcete přidat nové okno, postupujte takto:
V Průzkumník řešení otevřete
Main.storyboard
soubor pro úpravy v Tvůrci rozhraní Xcode.Přetáhněte nový kontroler zobrazení na návrhovou plochu:
V nástroji Identity Inspector zadejte
CustomDialogController
název třídy:Přepněte zpátky na Visual Studio pro Mac, povolte synchronizaci s Xcode a vytvořte
CustomDialogController.h
soubor.Vraťte se do Xcode a navrhněte své rozhraní:
Vytvořte modální segue z hlavního okna aplikace do nového kontroleru zobrazení přetažením z prvku uživatelského rozhraní, který otevře dialogové okno do okna dialogového okna. Přiřaďte identifikátor
ModalSegue
:Připojení všech akcí a výstupů:
Uložte změny a vraťte se do Visual Studio pro Mac pro synchronizaci s Xcode.
Udělejte soubor CustomDialogController.cs
takto:
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
}
}
Tento kód zveřejňuje několik vlastností pro nastavení názvu a popisu dialogového okna a několika událostí, které reagují na zrušené nebo přijaté dialogové okno.
Dále upravte ViewController.cs
soubor, přepište metodu PrepareForSegue
a udělejte ji takto:
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;
}
}
Tento kód inicializujegue, který jsme definovali v Tvůrci rozhraní Xcode, do našeho dialogového okna a nastaví název a popis. Zpracovává také volbu, která uživatel provede v dialogovém okně.
Aplikaci můžeme spustit a zobrazit vlastní dialogové okno:
Další informace o používání oken v aplikaci Xamarin.Mac najdete v naší dokumentaci k práci s Windows .
Vytvoření vlastního listu
List je modální dialogové okno připojené k danému okně dokumentu, které uživatelům brání v interakci s oknem, dokud dialogové okno nezavřou. List je připojen k oknem, ze kterého se objeví, a současně lze otevřít pouze jeden list pro okno.
Pokud chcete vytvořit vlastní list v Xamarin.Mac, udělejme toto:
V Průzkumník řešení otevřete
Main.storyboard
soubor pro úpravy v Tvůrci rozhraní Xcode.Přetáhněte nový kontroler zobrazení na návrhovou plochu:
Navrhněte uživatelské rozhraní:
Vytvořte list segue z hlavního okna na nový kontroler zobrazení:
V nástroji Identity Inspector pojmenujte třídu
SheetViewController
kontroleru zobrazení:Definujte všechny potřebné výstupy a akce:
Uložte změny a vraťte se do Visual Studio pro Mac k synchronizaci.
Potom upravte SheetViewController.cs
soubor a udělejte ho takto:
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
}
}
Dále upravte ViewController.cs
soubor, upravte metodu PrepareForSegue
a udělejte ji takto:
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;
}
}
Pokud spustíme naši aplikaci a otevřeme list, připojí se k oknem:
Dialogové okno Vytvoření předvoleb
Před rozložením zobrazení předvoleb v Tvůrci rozhraní budeme muset přidat vlastní typgue pro zpracování přepínání předvoleb. Přidejte do projektu novou třídu a zavolejte ji ReplaceViewSeque
. Upravte třídu a udělejte ji takto:
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
}
}
S vlastní gue vytvořený, můžeme přidat nové okno v Xcode Interface Builder pro zpracování našich předvoleb.
Pokud chcete přidat nové okno, postupujte takto:
V Průzkumník řešení otevřete
Main.storyboard
soubor pro úpravy v Tvůrci rozhraní Xcode.Přetáhněte nový ovladač okna na návrhovou plochu:
Uspořádejte okno poblíž návrháře řádku nabídek:
Vytvořte kopie připojeného kontroleru zobrazení, protože v zobrazení předvoleb budou karty:
Přetáhněte nový kontroler panelu nástrojů z knihovny:
A umístěte ho na okno na návrhové ploše:
Rozložení návrhu panelu nástrojů:
Control-Click and drag from each Toolbar Button to the Views you created above. Vyberte vlastní typgue:
Vyberte nový Segue a nastavte třídu na
ReplaceViewSegue
:V Návrháři řádku nabídek na návrhové ploše v nabídce aplikace vyberte Předvolby..., control-click and drag to the Preferences Window to create a Show segue:
Uložte změny a vraťte se do Visual Studio pro Mac k synchronizaci.
Pokud kód spustíme a v nabídce Aplikace vybereme předvolby... zobrazí se okno:
Další informace o práci s Windows a panely nástrojů najdete v naší dokumentaci k windows a panelům nástrojů.
Ukládání a načítání předvoleb
Když uživatel v typické aplikaci pro macOS provede změny v některé z uživatelských předvoleb aplikace, uloží se tyto změny automaticky. Nejjednodušší způsob, jak to vyřešit v aplikaci Xamarin.Mac, je vytvořit jednu třídu pro správu všech předvoleb uživatele a sdílet ji v celém systému.
Nejprve přidejte do projektu novou AppPreferences
třídu a dědí z NSObject
. Předvolby budou navrženy tak, aby používaly datové vazby a kódování klíč-hodnota, díky čemuž bude proces vytváření a údržby upřednostňovaných formulářů mnohem jednodušší. Vzhledem k tomu, že předvolby se skládají z malého množství jednoduchých datových typů, použijte předdefinované NSUserDefaults
k ukládání a načítání hodnot.
AppPreferences.cs
Upravte soubor a udělejte ho takto:
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
}
}
Tato třída obsahuje několik pomocných rutin, jako SaveInt
je , , LoadInt
SaveColor
, LoadColor
, atd. pro usnadnění práceNSUserDefaults
. Vzhledem k tomu, že NSUserDefaults
nemá integrovaný způsob NSColors
zpracování , NSColorToHexString
a NSColorFromHexString
metody se používají k převodu barev na webové šestnáctkové řetězce (#RRGGBBAA
kde AA
je alfa průhlednost), které lze snadno uložit a načíst.
AppDelegate.cs
V souboru vytvořte instanci objektu AppPreferences, který bude použit pro celou aplikaci:
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
...
Předvolby zapojení do zobrazení předvoleb
Dále připojte třídu Preference k prvkům uživatelského rozhraní v okně předvoleb a zobrazeních vytvořených výše. V Tvůrci rozhraní vyberte kontroler zobrazení předvoleb a přepněte na Kontrolu identit a vytvořte pro kontroler vlastní třídu:
Přepněte zpět na Visual Studio pro Mac, aby se změny synchronizovaly, a otevřete nově vytvořenou třídu pro úpravy. Udělejte třídu takto:
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
}
}
Všimněte si, že tato třída udělala dvě věci: Nejprve existuje pomocná App
vlastnost, která usnadňuje přístup k AppDelegate . Za druhé vlastnost Preferences
zveřejňuje globální třídu AppPreferences pro datovou vazbu s libovolnými ovládacími prvky uživatelského rozhraní umístěnými v tomto zobrazení.
Potom poklikejte na soubor Storyboard a znovu ho otevřete v Tvůrci rozhraní (a podívejte se na změny, které jste právě provedli výše). Přetáhněte všechny ovládací prvky uživatelského rozhraní potřebné k sestavení rozhraní předvoleb do zobrazení. U každého ovládacího prvku přepněte na kontrolu vazeb a vytvořte vazbu na jednotlivé vlastnosti třídy AppPreference :
Opakujte výše uvedené kroky pro všechny požadované panely (kontrolery zobrazení) a vlastnosti předvoleb.
Použití změn předvoleb u všech otevřených oken
Jak je uvedeno výše, v typické aplikaci pro macOS platí, že když uživatel provede změny v některé z uživatelských předvoleb aplikace, uloží se tyto změny automaticky a použijí se na všechna okna, která uživatel mohl otevřít v aplikaci.
Pečlivé plánování a návrh předvoleb a oken vaší aplikace umožní, aby se tento proces pro koncového uživatele hladce a transparentně s minimálním množstvím práce na kódování.
Pro každé okno, které bude využívat Předvolby aplikace, přidejte následující pomocnou vlastnost do kontroleru zobrazení obsahu, aby byl přístup k naší appDelegate jednodušší:
#region Application Access
public static AppDelegate App {
get { return (AppDelegate)NSApplication.SharedApplication.Delegate; }
}
#endregion
Dále přidejte třídu pro konfiguraci obsahu nebo chování na základě předvoleb uživatele:
public void ConfigureEditor() {
// General Preferences
TextEditor.AutomaticLinkDetectionEnabled = App.Preferences.SmartLinks;
TextEditor.AutomaticQuoteSubstitutionEnabled = App.Preferences.SmartQuotes;
...
}
Při prvním otevření okna je potřeba volat metodu konfigurace, abyste měli jistotu, že odpovídá předvolbám uživatele:
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Configure editor from user preferences
ConfigureEditor ();
...
}
Dále upravte AppDelegate.cs
soubor a přidejte následující metodu, aby se všechny změny předvoleb použily ve všech otevřených oknech:
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 ();
}
}
}
V dalším kroku přidejte PreferenceWindowDelegate
do projektu třídu a udělejte ji takto:
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
}
}
To způsobí, že se všechny změny předvoleb odešlou do všech otevřených oken, když se okno předvoleb zavře.
Nakonec upravte řadič okna předvoleb a přidejte delegáta vytvořeného výše:
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
}
}
Pokud uživatel upraví předvolby aplikace a zavře okno předvoleb, změny se použijí pro všechny otevřené Windows:
Dialogové okno Otevřít
Dialogové okno Otevřít poskytuje uživatelům konzistentní způsob, jak najít a otevřít položku v aplikaci. Chcete-li zobrazit dialogové okno Otevřít v aplikaci Xamarin.Mac, použijte následující kód:
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;
}
}
Ve výše uvedeném kódu otevíráme nové okno dokumentu pro zobrazení obsahu souboru. Tento kód budete muset nahradit funkcemi, které vyžaduje vaše aplikace.
Při práci s NSOpenPanel
aplikací jsou k dispozici následující vlastnosti:
- CanChooseFiles – Pokud
true
uživatel může vybrat soubory. - CanChooseDirectories – pokud
true
uživatel může vybrat adresáře. - AllowsMultipleSelection – Pokud
true
uživatel může vybrat více souborů najednou. - ResolveAliases – Pokud
true
vyberete a alias, přeloží ho na cestu k původnímu souboru. - AllowedFileTypes – je pole řetězců typů souborů, které uživatel může vybrat jako příponu nebo UTI. Výchozí hodnota je
null
, která umožňuje otevření libovolného souboru.
Metoda RunModal ()
zobrazí dialogové okno Otevřít a umožní uživateli vybrat soubory nebo adresáře (jak jsou zadány vlastnostmi) a vrátí 1
se, pokud uživatel klikne na tlačítko Otevřít .
Dialogové okno Otevřít vrátí vybrané soubory nebo adresáře uživatele jako pole adres URL ve URL
vlastnosti.
Pokud program spustíme a v nabídce Soubor vybereme položku Otevřít... zobrazí se následující položky:
Dialogy Nastavení tisku a stránky
macOS poskytuje standardní dialogová okna Pro tisk a vzhled stránky, která může aplikace zobrazit, aby uživatelé mohli mít konzistentní možnosti tisku v každé aplikaci, kterou používají.
Následující kód zobrazí standardní dialogové okno tisku:
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 ();
}
}
}
Pokud vlastnost nastavíme ShowPrintAsSheet
na false
, spusťte aplikaci a zobrazte dialogové okno tisku, zobrazí se následující:
Pokud vlastnost nastavíte ShowPrintAsSheet
na true
, spusťte aplikaci a zobrazte dialogové okno tisku, zobrazí se následující:
Následující kód zobrazí dialogové okno Rozložení stránky:
[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 ();
}
}
}
Pokud vlastnost nastavíme ShowPrintAsSheet
na false
, spusťte aplikaci a zobrazíme dialogové okno rozložení při tisku, zobrazí se následující:
Pokud vlastnost nastavíte ShowPrintAsSheet
na true
, spusťte aplikaci a zobrazte dialogové okno rozložení při tisku, zobrazí se následující:
Další informace o práci s dialogovými okny Tisk a Vzhled stránky najdete v dokumentaci k NSPrintPanel a NSPageLayout společnosti Apple.
Dialogové okno Uložit
Dialogové okno Uložit umožňuje uživatelům konzistentní způsob, jak uložit položku v aplikaci.
Následující kód zobrazí standardní dialogové okno uložit:
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 ();
}
}
}
Vlastnost AllowedFileTypes
je pole řetězců typů souborů, které uživatel může vybrat k uložení souboru jako. Typ souboru může být zadán jako přípona nebo UTI. Výchozí hodnota je null
, která umožňuje použití libovolného typu souboru.
Pokud vlastnost nastavíme ShowSaveAsSheet
na false
, spusťte aplikaci a v nabídce Soubor vyberte Uložit jako... následující:
Uživatel může dialogové okno rozbalit:
Pokud vlastnost nastavíme ShowSaveAsSheet
na true
, spusťte aplikaci a v nabídce Soubor vyberte Uložit jako... následující:
Uživatel může dialogové okno rozbalit:
Další informace o práci s dialogovým oknem Uložit najdete v dokumentaci k NSSavePanel společnosti Apple.
Shrnutí
Tento článek se podrobně podíval na práci s Modálními Windows, Listy a standardními systémovými dialogovými okny v aplikaci Xamarin.Mac. Viděli jsme různé typy a použití modálních oken, listů a dialogů, jak vytvářet a udržovat modální okna a listy v Tvůrci rozhraní Xcode a jak pracovat s modálními okny, listy a dialogy v kódu jazyka C#.