Návrh uživatelského rozhraní .storyboard/.xib-less v Xamarin.Mac
Tento článek popisuje vytvoření uživatelského rozhraní aplikace Xamarin.Mac přímo z kódu jazyka C#, bez souborů .storyboard, souborů .xib nebo Tvůrce rozhraní.
Přehled
Při práci s jazykem C# a .NET v aplikaci Xamarin.Mac máte přístup ke stejným prvkům uživatelského rozhraní a nástrojům, které vývojář pracuje v Objective-C Xcode. Při vytváření aplikace Xamarin.Mac obvykle použijete Tvůrce rozhraní Xcode se soubory .storyboard nebo .xib k vytvoření a údržbě uživatelského rozhraní aplikace.
Máte také možnost vytvořit některé nebo všechny uživatelské rozhraní aplikace Xamarin.Mac přímo v kódu jazyka C#. V tomto článku se budeme zabývat základy vytváření uživatelských rozhraní a prvků uživatelského rozhraní v kódu jazyka C#.
Přepnutí okna pro použití kódu
Když vytvoříte novou aplikaci Xamarin.Mac Cocoa, ve výchozím nastavení se zobrazí standardní prázdné okno. Tato okna jsou definována v souboru Main.storyboard (nebo tradičně MainWindow.xib) automaticky zahrnutý v projektu. To také zahrnuje ViewController.cs soubor, který spravuje hlavní zobrazení aplikace (nebo znovu tradičně MainWindow.cs a soubor MainWindowController.cs ).
Pokud chcete přepnout do okna Xibless pro aplikaci, postupujte takto:
Otevřete aplikaci, kterou chcete přestat používat
.storyboard
, nebo soubory .xib a definujte uživatelské rozhraní v Visual Studio pro Mac.V oblasti řešení klikněte pravým tlačítkem myši na soubor Main.storyboard nebo MainWindow.xib a vyberte Odebrat:
V dialogovém okně Odebrat kliknutím na tlačítko Odstranit z projektu úplně odeberte .storyboard nebo .xib:
Teď budeme muset upravit soubor MainWindow.cs tak, aby definoval rozložení okna a upravili ViewController.cs nebo MainWindowController.cs soubor, abychom vytvořili instanci naší MainWindow
třídy, protože už nepoužíváme soubor .storyboard nebo .xib.
Moderní aplikace Xamarin.Mac, které používají scénáře pro své uživatelské rozhraní, nemusí automaticky zahrnovat MainWindow.cs, ViewController.cs nebo MainWindowController.cs soubory. Podle potřeby stačí do projektu přidat novou prázdnou třídu C# (Přidat>nový soubor...>Obecná>prázdná třída) a pojmenujte ji stejně jako chybějící soubor.
Definování okna v kódu
Potom upravte soubor MainWindow.cs a nastavte ho takto:
using System;
using Foundation;
using AppKit;
using CoreGraphics;
namespace MacXibless
{
public partial class MainWindow : NSWindow
{
#region Private Variables
private int NumberOfTimesClicked = 0;
#endregion
#region Computed Properties
public NSButton ClickMeButton { get; set;}
public NSTextField ClickMeLabel { get ; set;}
#endregion
#region Constructors
public MainWindow (IntPtr handle) : base (handle)
{
}
[Export ("initWithCoder:")]
public MainWindow (NSCoder coder) : base (coder)
{
}
public MainWindow(CGRect contentRect, NSWindowStyle aStyle, NSBackingStore bufferingType, bool deferCreation): base (contentRect, aStyle,bufferingType,deferCreation) {
// Define the user interface of the window here
Title = "Window From Code";
// Create the content view for the window and make it fill the window
ContentView = new NSView (Frame);
// Add UI elements to window
ClickMeButton = new NSButton (new CGRect (10, Frame.Height-70, 100, 30)){
AutoresizingMask = NSViewResizingMask.MinYMargin
};
ContentView.AddSubview (ClickMeButton);
ClickMeLabel = new NSTextField (new CGRect (120, Frame.Height - 65, Frame.Width - 130, 20)) {
BackgroundColor = NSColor.Clear,
TextColor = NSColor.Black,
Editable = false,
Bezeled = false,
AutoresizingMask = NSViewResizingMask.WidthSizable | NSViewResizingMask.MinYMargin,
StringValue = "Button has not been clicked yet."
};
ContentView.AddSubview (ClickMeLabel);
}
#endregion
#region Override Methods
public override void AwakeFromNib ()
{
base.AwakeFromNib ();
// Wireup events
ClickMeButton.Activated += (sender, e) => {
// Update count
ClickMeLabel.StringValue = (++NumberOfTimesClicked == 1) ? "Button clicked one time." : string.Format("Button clicked {0} times.",NumberOfTimesClicked);
};
}
#endregion
}
}
Pojďme si probrat několik klíčových prvků.
Nejprve jsme přidali několik vypočítaných vlastností , které budou fungovat jako výstupy (jako by se okno vytvořilo v souboru .storyboard nebo .xib):
public NSButton ClickMeButton { get; set;}
public NSTextField ClickMeLabel { get ; set;}
Ty nám poskytnou přístup k prvkům uživatelského rozhraní, které budeme zobrazovat v okně. Vzhledem k tomu, že se okno nefoukne ze souboru .storyboard nebo .xib, potřebujeme způsob, jak ho vytvořit instanci (jak uvidíme později ve MainWindowController
třídě). To dělá tato nová metoda konstruktoru:
public MainWindow(CGRect contentRect, NSWindowStyle aStyle, NSBackingStore bufferingType, bool deferCreation): base (contentRect, aStyle,bufferingType,deferCreation) {
...
}
Tady navrhneme rozložení okna a umístíme všechny prvky uživatelského rozhraní potřebné k vytvoření požadovaného uživatelského rozhraní. Než do okna přidáme jakékoli prvky uživatelského rozhraní, potřebuje zobrazení obsahu, aby obsahovalo tyto prvky:
ContentView = new NSView (Frame);
Tím se vytvoří zobrazení obsahu, které vyplní okno. Teď do okna přidáme první prvek uživatelského rozhraní, a to :NSButton
ClickMeButton = new NSButton (new CGRect (10, Frame.Height-70, 100, 30)){
AutoresizingMask = NSViewResizingMask.MinYMargin
};
ContentView.AddSubview (ClickMeButton);
První věc, kterou zde je třeba poznamenat, je, že na rozdíl od iOS macOS používá matematické zápisy k definování jeho souřadnicového systému okna. Počáteční bod je tedy v levém dolním rohu okna, přičemž hodnoty se zvětšující vpravo a směrem k pravému hornímu rohu okna. Když vytvoříme nový NSButton
, vezmeme to v úvahu při definování jeho umístění a velikosti na obrazovce.
Vlastnost AutoresizingMask = NSViewResizingMask.MinYMargin
říká tlačítku, že má zůstat ve stejném umístění v horní části okna, když je okno změněno svisle. Opět je to nutné, protože (0,0) je v levém dolním rohu okna.
ContentView.AddSubview (ClickMeButton)
Nakonec metoda přidá NSButton
do zobrazení obsahu zobrazení obsahu, aby se zobrazila na obrazovce při spuštění aplikace a zobrazené okno.
Dále se přidá popisek do okna, ve kterém se zobrazí počet kliknutí NSButton
:
ClickMeLabel = new NSTextField (new CGRect (120, Frame.Height - 65, Frame.Width - 130, 20)) {
BackgroundColor = NSColor.Clear,
TextColor = NSColor.Black,
Editable = false,
Bezeled = false,
AutoresizingMask = NSViewResizingMask.WidthSizable | NSViewResizingMask.MinYMargin,
StringValue = "Button has not been clicked yet."
};
ContentView.AddSubview (ClickMeLabel);
Vzhledem k tomu, že macOS nemá konkrétní prvek uživatelského rozhraní Popisek , přidali jsme speciálně stylovaný, neupravitelný NSTextField
tak, aby fungoval jako popisek. Stejně jako u tlačítka před, velikost a umístění bere v úvahu, že (0,0) je v levém dolním rohu okna. Vlastnost AutoresizingMask = NSViewResizingMask.WidthSizable | NSViewResizingMask.MinYMargin
používá operátor nebo ke kombinování dvou NSViewResizingMask
funkcí. Díky tomu zůstane popisek ve stejném umístění v horní části okna, když se velikost okna změní svisle a zmenší a zvětší se, protože se velikost okna změní vodorovně.
ContentView.AddSubview (ClickMeLabel)
Metoda opět přidá NSTextField
do zobrazení obsahu zobrazení obsahu, aby se zobrazila na obrazovce při spuštění aplikace a otevření okna.
Úprava kontroleru oken
Vzhledem k tomu, že návrh MainWindow
souboru .storyboard nebo .xib se už nenačítá, budeme muset upravit kontroler okna. Upravte soubor MainWindowController.cs a nastavte ho takto:
using System;
using Foundation;
using AppKit;
using CoreGraphics;
namespace MacXibless
{
public partial class MainWindowController : NSWindowController
{
public MainWindowController (IntPtr handle) : base (handle)
{
}
[Export ("initWithCoder:")]
public MainWindowController (NSCoder coder) : base (coder)
{
}
public MainWindowController () : base ("MainWindow")
{
// Construct the window from code here
CGRect contentRect = new CGRect (0, 0, 1000, 500);
base.Window = new MainWindow(contentRect, (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable), NSBackingStore.Buffered, false);
// Simulate Awaking from Nib
Window.AwakeFromNib ();
}
public override void AwakeFromNib ()
{
base.AwakeFromNib ();
}
public new MainWindow Window {
get { return (MainWindow)base.Window; }
}
}
}
Pojďme probrat klíčové prvky této úpravy.
Nejprve definujeme novou instanci MainWindow
třídy a přiřadíme ji k vlastnosti kontroleru základního Window
okna:
CGRect contentRect = new CGRect (0, 0, 1000, 500);
base.Window = new MainWindow(contentRect, (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable), NSBackingStore.Buffered, false);
Definujeme umístění okna obrazovky pomocí .CGRect
Stejně jako souřadnicový systém okna definuje obrazovka (0,0) jako levý dolní roh. V dalším kroku definujeme styl okna pomocí operátoru Or ke kombinování dvou nebo více NSWindowStyle
funkcí:
... (NSWindowStyle.Titled | NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Resizable) ...
K dispozici jsou následující NSWindowStyle
funkce:
- Bez ohraničení – okno nebude mít žádné ohraničení.
- Název : Okno bude mít záhlaví.
- Closable - Okno má tlačítko Zavřít a lze ho zavřít.
- Miniaturizovatelné – Okno má tlačítko Miniaturizace a dá se minimalizovat.
- Změna velikosti – Okno bude mít tlačítko Změnit velikost a bude možné ho změnit.
- Utility - Okno je okno užitkového stylu (panel).
- DocModal – Pokud je okno panelem, bude se jednat o modální režim dokumentu místo system Modal.
- NonactivatingPanel – Pokud je okno panelem, nebude se jednat o hlavní okno.
- TexturedBackground – okno bude mít texturované pozadí.
- Neškálování – okno se nebude škálovat.
- UnifiedTitleAndToolbar – název okna a oblasti panelu nástrojů budou spojené.
- Hud - Okno se zobrazí jako panel pro zobrazení hlavy.
- FullScreenWindow – okno může vstoupit do režimu celé obrazovky.
- FullSizeContentView – zobrazení obsahu okna je za nadpisem a oblastí panelu nástrojů.
Poslední dvě vlastnosti definují typ ukládání do vyrovnávací paměti pro okno a pokud bude výkres okna odložen. Další informace najdete NSWindows
v dokumentaci společnosti Apple k Systému Windows .
A konečně, protože okno se nefoukne ze souboru .storyboard nebo .xib, musíme ho simulovat v našem MainWindowController.cs voláním metody Windows AwakeFromNib
:
Window.AwakeFromNib ();
To vám umožní kódovat proti oknem stejně jako standardní okno načtené ze souboru .storyboard nebo .xib.
Zobrazení okna
Když soubor .storyboard nebo .xib odeberete a upravíte soubory MainWindow.cs a MainWindowController.cs , použijete okno stejně jako jakékoli normální okno vytvořené v Tvůrci rozhraní Xcode se souborem .xib.
Následující příkaz vytvoří novou instanci okna a jeho kontroleru a zobrazí okno na obrazovce:
private MainWindowController mainWindowController;
...
mainWindowController = new MainWindowController ();
mainWindowController.Window.MakeKeyAndOrderFront (this);
V tomto okamžiku se při spuštění aplikace a kliknutí na tlačítko několikrát zobrazí následující:
Přidání okna pouze s kódem
Pokud chceme přidat pouze kód, xibless okno do existující aplikace Xamarin.Mac, klikněte pravým tlačítkem myši na projekt v Oblasti řešení a vyberte Přidat>nový soubor... V dialogovém okně Nový soubor zvolte okno Xamarin.Mac>Cocoa s kontrolerem, jak je znázorněno níže:
Stejně jako předtím odstraníme výchozí soubor .storyboard nebo .xib z projektu (v tomto případě SecondWindow.xib) a podle kroků v okně Přepneme okno výše, abychom prokryli definici okna na kód.
Přidání prvku uživatelského rozhraní do okna v kódu
Bez ohledu na to, jestli bylo okno vytvořeno v kódu nebo načteno ze souboru .storyboard nebo .xib, může do okna přidat prvek uživatelského rozhraní z kódu. Příklad:
var ClickMeButton = new NSButton (new CGRect (10, 10, 100, 30)){
AutoresizingMask = NSViewResizingMask.MinYMargin
};
MyWindow.ContentView.AddSubview (ClickMeButton);
Výše uvedený kód vytvoří nový NSButton
a přidá ho MyWindow
do instance okna pro zobrazení. V podstatě jakýkoli prvek uživatelského rozhraní, který lze definovat v Tvůrci rozhraní Xcode v souboru .storyboard nebo .xib lze vytvořit v kódu a zobrazit v okně.
Definování řádku nabídek v kódu
Vzhledem k aktuálním omezením v Xamarin.Mac se nedoporučuje, abyste vytvořili řádek nabídek aplikace Xamarin.Mac –NSMenuBar
v kódu, ale nadále používáte soubor Main.storyboard nebo MainMenu.xib k jeho definování. To znamená, že v kódu jazyka C# můžete přidávat a odebírat nabídky a položky nabídek.
Upravte například soubor AppDelegate.cs a nastavte metodu DidFinishLaunching
takto:
public override void DidFinishLaunching (NSNotification notification)
{
mainWindowController = new MainWindowController ();
mainWindowController.Window.MakeKeyAndOrderFront (this);
// Create a Status Bar Menu
NSStatusBar statusBar = NSStatusBar.SystemStatusBar;
var item = statusBar.CreateStatusItem (NSStatusItemLength.Variable);
item.Title = "Phrases";
item.HighlightMode = true;
item.Menu = new NSMenu ("Phrases");
var address = new NSMenuItem ("Address");
address.Activated += (sender, e) => {
Console.WriteLine("Address Selected");
};
item.Menu.AddItem (address);
var date = new NSMenuItem ("Date");
date.Activated += (sender, e) => {
Console.WriteLine("Date Selected");
};
item.Menu.AddItem (date);
var greeting = new NSMenuItem ("Greeting");
greeting.Activated += (sender, e) => {
Console.WriteLine("Greetings Selected");
};
item.Menu.AddItem (greeting);
var signature = new NSMenuItem ("Signature");
signature.Activated += (sender, e) => {
Console.WriteLine("Signature Selected");
};
item.Menu.AddItem (signature);
}
Výše uvedená položka vytvoří nabídku stavového řádku z kódu a zobrazí ji při spuštění aplikace. Další informace o práci s nabídkami najdete v naší dokumentaci k nabídkám .
Shrnutí
Tento článek se podrobně podíval na vytvoření uživatelského rozhraní aplikace Xamarin.Mac v kódu jazyka C# na rozdíl od použití Tvůrce rozhraní Xcode se soubory .storyboard nebo .xib.