Vytváření vlastních ovládacích prvků v Xamarin.Macu
Při práci s C# a .NET v aplikaci Xamarin.Mac máte přístup ke stejným uživatelským ovládacím prvkům jako vývojář pracující v Objective-C nástroji Objective-C a Xcode. Vzhledem k tomu, že Xamarin.Mac se integruje přímo s Xcode, můžete použít Interface Builder Xcode k vytvoření a údržbě uživatelských ovládacích prvků (nebo je volitelně vytvořit přímo v kódu jazyka C#).
I když macOS poskytuje velké množství integrovaných uživatelských ovládacích prvků, možná budete muset vytvořit vlastní ovládací prvek, který bude poskytovat funkce, které nejsou k dispozici hned, nebo aby odpovídaly vlastnímu motivu uživatelského rozhraní (například hernímu rozhraní).
V tomto článku projdeme základy vytváření znovu použitelného ovládacího prvku custom Uživatelské rozhraní v aplikaci Xamarin.Mac. Důrazně doporučujeme, abyste si nejprve prošli článek Hello, Mac, konkrétně oddíly Úvod do Xcode a Interface Builder a Výstupy a Akce, protože se zabývá klíčovými koncepty a technikami, které budeme v tomto článku používat.
Možná se budete chtít podívat i na část dokumentu Exposing C# classes / methods to Objective-CExposing C# classes / methods to Objective-C která vysvětluje příkazy a používané k připojení tříd jazyka C# k objektům a prvkům uživatelského RegisterExportObjective-C rozhraní.
Úvod do vlastních ovládacích prvků
Jak je uvedeno výše, může se zobrazit čas, kdy potřebujete vytvořit vlastní ovládací prvek Uživatelské rozhraní pro opětovné použití, který bude poskytovat jedinečné funkce pro uživatelské rozhraní aplikace Xamarin.Mac nebo vytvořit vlastní motiv uživatelského rozhraní (například herní rozhraní).
V těchto situacích můžete snadno dědit z nástroje a vytvořit vlastní nástroj, který lze přidat do uživatelského rozhraní aplikace prostřednictvím kódu jazyka C# nebo prostřednictvím Interface Builder NSControl Xcode. Děděním z vlastního ovládacího prvku se automaticky zobrazí všechny standardní funkce, které má integrovaný NSControl Uživatelské rozhraní Control (například NSButton ).
Pokud vlastní ovládací Uživatelské rozhraní zobrazuje jenom informace (například vlastní nástroj pro grafy a grafický nástroj), můžete chtít místo dědit z NSViewNSControl .
Bez ohledu na to, která základní třída se používá, jsou základní kroky pro vytvoření vlastního ovládacího prvku stejné.
V tomto článku vytvoříte vlastní komponentu překlopení přepínače, která poskytuje jedinečný Uživatelské rozhraní motiv a příklad vytvoření plně funkčního ovládacího prvku Custom Uživatelské rozhraní Control.
Sestavení vlastního ovládacího prvku
Vzhledem k tomu, že vlastní ovládací prvek, který vytváříme, bude reagovat na uživatelský vstup (kliknutí levým tlačítkem myši), dědíme z NSControl . Tímto způsobem bude mít náš vlastní ovládací prvek automaticky všechny standardní funkce, které má integrovaný ovládací prvek Uživatelské rozhraní Control a reaguje jako standardní ovládací prvek macOS.
V Visual Studio pro Mac otevřete projekt Xamarin.Mac, pro který chcete vytvořit vlastní ovládací Uživatelské rozhraní pro (nebo vytvořit nový). Přidejte novou třídu a volejte ji NSFlipSwitch :
Dále upravte třídu NSFlipSwitch.cs a udělejte, aby vypadala takto:
using Foundation;
using System;
using System.CodeDom.Compiler;
using AppKit;
using CoreGraphics;
namespace MacCustomControl
{
[Register("NSFlipSwitch")]
public class NSFlipSwitch : NSControl
{
#region Private Variables
private bool _value = false;
#endregion
#region Computed Properties
public bool Value {
get { return _value; }
set {
// Save value and force a redraw
_value = value;
NeedsDisplay = true;
}
}
#endregion
#region Constructors
public NSFlipSwitch ()
{
// Init
Initialize();
}
public NSFlipSwitch (IntPtr handle) : base (handle)
{
// Init
Initialize();
}
[Export ("initWithFrame:")]
public NSFlipSwitch (CGRect frameRect) : base(frameRect) {
// Init
Initialize();
}
private void Initialize() {
this.WantsLayer = true;
this.LayerContentsRedrawPolicy = NSViewLayerContentsRedrawPolicy.OnSetNeedsDisplay;
}
#endregion
#region Draw Methods
public override void DrawRect (CGRect dirtyRect)
{
base.DrawRect (dirtyRect);
// Use Core Graphic routines to draw our UI
...
}
#endregion
#region Private Methods
private void FlipSwitchState() {
// Update state
Value = !Value;
}
#endregion
}
}
První věc, kterou si musíme všimnout o naší vlastní třídě v tom, že dědíme z a pomocí příkazu Register tuto třídu zpřístupňujeme do třídy NSControl a NSControlObjective-C Interface Builder:
[Register("NSFlipSwitch")]
public class NSFlipSwitch : NSControl
V následujících částech se podrobněji podíváme na zbytek výše uvedeného kódu.
Sledování stavu ovládacího prvku
Vzhledem k tomu, že náš vlastní ovládací prvek je přepínač, potřebujeme způsob, jak sledovat stav zapnutí/vypnutí přepínače. Tento postup zřídíme pomocí následujícího kódu v NSFlipSwitch souboru :
private bool _value = false;
...
public bool Value {
get { return _value; }
set {
// Save value and force a redraw
_value = value;
NeedsDisplay = true;
}
}
Když se stav přepínače změní, potřebujeme způsob, jak aktualizovat uživatelské rozhraní. To uděláme tak, že ovládací prvek vynutíme překreslením uživatelského rozhraní pomocí NeedsDisplay = true .
Pokud náš ovládací prvek vyžadoval více než jeden stav On/Off (například více stavový přepínač se 3 pozicemi), mohli bychom ke sledování stavu použít výčet. V našem příkladu to bude jednoduché.
Přidali jsme také pomocnou metodu pro prohození stavu přepínače mezi přepínačem On (Zapnout) a Off (Vypnuto):
private void FlipSwitchState() {
// Update state
Value = !Value;
}
Později tuto pomocná třídu rozbalíme, aby informovala volajícího o změně stavu přepínačů.
Kreslení rozhraní ovládacího prvku
Rutiny kreslení základní grafiky použijeme k vykreslování vlastního ovládacího prvku Uživatelské rozhraní za běhu. Než to uděláme, musíme pro ovládací prvek zapnout vrstvy. Používáme k tomu následující privátní metodu:
private void Initialize() {
this.WantsLayer = true;
this.LayerContentsRedrawPolicy = NSViewLayerContentsRedrawPolicy.OnSetNeedsDisplay;
}
Tato metoda se volá z každého konstruktoru ovládacího prvku, aby se zajistilo, že je ovládací prvek správně nakonfigurovaný. Například:
public NSFlipSwitch (IntPtr handle) : base (handle)
{
// Init
Initialize();
}
Dále musíme přepsat metodu a přidat DrawRect rutiny základního obrázku, které nakreslí ovládací prvek:
public override void DrawRect (CGRect dirtyRect)
{
base.DrawRect (dirtyRect);
// Use Core Graphic routines to draw our UI
...
}
Vizuální reprezentaci ovládacího prvku upravíme, když se změní jeho stav (například změníme nastavení z On (Vypnuto) na On (Vypnuto). Kdykoli se stav změní, můžeme pomocí příkazu vynutit překreslení ovládacího prvku NeedsDisplay = true pro nový stav.
Reakce na vstup uživatele
Existují dva základní způsoby, jak do vlastního ovládacího prvku přidat uživatelský vstup: Override Mouse Handling Routines (Přepsat rutiny zpracování myši) nebo Gesture Recognizers (Rozpoznávání gest). Metoda, kterou použijeme, bude založená na funkcích, které vyžaduje náš ovládací prvek.
Důležité
U každého vlastního ovládacího prvku, který vytvoříte, byste měli použít buď metody přepsání, nebo rozpoznávání gest,ale ne obojí současně, protože mohou být vzájemně v konfliktu.
Zpracování uživatelského vstupu pomocí metod přepsání
Objekty, které dědí z nebo , mají několik metod přepsání pro NSControl zpracování vstupu myši nebo NSView klávesnice. U našeho příkladu ovládacího prvku chceme překlopit stav přepínače mezi zapnutím a vypnutím, když uživatel klikne na ovládací prvek levým tlačítkem myši. Ke zpracování můžeme do třídy přidat následující metody NSFlipSwitch přepsání:
#region Mouse Handling Methods
// --------------------------------------------------------------------------------
// Handle mouse with Override Methods.
// NOTE: Use either this method or Gesture Recognizers, NOT both!
// --------------------------------------------------------------------------------
public override void MouseDown (NSEvent theEvent)
{
base.MouseDown (theEvent);
FlipSwitchState ();
}
public override void MouseDragged (NSEvent theEvent)
{
base.MouseDragged (theEvent);
}
public override void MouseUp (NSEvent theEvent)
{
base.MouseUp (theEvent);
}
public override void MouseMoved (NSEvent theEvent)
{
base.MouseMoved (theEvent);
}
## endregion
Ve výše uvedeném kódu voláme metodu (definovanou výše), která převrátí stav přepínače v FlipSwitchStateMouseDown metodě . Tím se také vynutí překreslit ovládací prvek tak, aby odrážel aktuální stav.
Zpracování uživatelského vstupu pomocí rozpoznávání gest
Volitelně můžete použít rozpoznávání gest ke zpracování interakcí uživatele s ovládacím prvku. Odeberte přepsání přidaná výše, upravte metodu a Initialize zajistěte, aby vypadala takto:
private void Initialize() {
this.WantsLayer = true;
this.LayerContentsRedrawPolicy = NSViewLayerContentsRedrawPolicy.OnSetNeedsDisplay;
// --------------------------------------------------------------------------------
// Handle mouse with Gesture Recognizers.
// NOTE: Use either this method or the Override Methods, NOT both!
// --------------------------------------------------------------------------------
var click = new NSClickGestureRecognizer (() => {
FlipSwitchState();
});
AddGestureRecognizer (click);
}
Tady vytváříme novou metodu a voláme metodu , která změní stav přepínače, když na něj uživatel klikne NSClickGestureRecognizerFlipSwitchState levým tlačítkem myši. Metoda AddGestureRecognizer (click) přidá do ovládacího prvku Rozpoznávání gest.
To, kterou metodu používáme, opět závisí na tom, čeho se snažíme pomocí vlastního ovládacího prvku dosáhnout. Pokud potřebujeme přístup nízké úrovně k interakci s uživatelem, použijte metody přepsání. Pokud potřebujeme předdefinované funkce, jako jsou kliknutí myší, použijte Rozpoznávání gest.
Reakce na události změny stavu
Když uživatel změní stav vlastního ovládacího prvku, potřebujeme způsob, jak reagovat na změnu stavu v kódu (například udělat něco po kliknutí na vlastní tlačítko).
Pokud chcete tuto funkci poskytnout, upravte NSFlipSwitch třídu a přidejte následující kód:
#region Events
public event EventHandler ValueChanged;
internal void RaiseValueChanged() {
if (this.ValueChanged != null)
this.ValueChanged (this, EventArgs.Empty);
// Perform any action bound to the control from Interface Builder
// via an Action.
if (this.Action !=null)
NSApplication.SharedApplication.SendAction (this.Action, this.Target, this);
}
## endregion
Dále upravte FlipSwitchState metodu a vytvořte, aby vypadala takto:
private void FlipSwitchState() {
// Update state
Value = !Value;
RaiseValueChanged ();
}
Nejprve poskytneme událost, do které můžeme přidat obslužnou rutinu v kódu C#, abychom mohli provést akci, když uživatel změní ValueChanged stav přepínače.
Za druhé, protože náš vlastní ovládací prvek dědí z , má automaticky akci, kterou je možné přiřadit v souboru NSControl Interface Builder. NSControl K volání této akce při změně stavu použijeme následující kód:
if (this.Action !=null)
NSApplication.SharedApplication.SendAction (this.Action, this.Target, this);
Nejprve zkontrolujeme, jestli byla k ovládacímu prvku přiřazena akce. Dále zavoláme akci , pokud byla definována.
Použití vlastního ovládacího prvku
Když máme vlastní ovládací prvek plně definovaný, můžeme ho buď přidat do uživatelského rozhraní aplikace Xamarin.Mac pomocí kódu jazyka C#, nebo v uživatelském rozhraní Interface Builder.
Pokud chcete ovládací prvek přidat pomocí Interface Builder, nejprve proveďte čisté sestavení projektu Xamarin.Mac a pak poklikejte na soubor a otevřete ho v Interface Builder Main.storyboard pro úpravy:
V dalším kroku Custom View přetáhněte do Uživatelské rozhraní návrhu:
Když je vlastní zobrazení stále vybrané, přepněte do inspektoru identit a změňte třídu zobrazení na :
Přepněte do Editoru asistenta a vytvořte výstup pro vlastní ovládací prvek (nezapomeňte ho svázat v souboru, a ne v souboru):
Uložte změny, vraťte se Visual Studio pro Mac a povolte synchronizaci změn. Upravte ViewController.cs soubor a ViewDidLoad zajistěte, aby metoda vypadala takto:
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Do any additional setup after loading the view.
OptionTwo.ValueChanged += (sender, e) => {
// Display the state of the option switch
Console.WriteLine("Option Two: {0}", OptionTwo.Value);
};
}
Tady odpovíme na událost, která jsme ve třídě definovali výše, a když uživatel klikne na ovládací prvek, zapíšeme aktuální ValueChangedNSFlipSwitch hodnotu. ValueChanged
Volitelně se můžeme vrátit k Interface Builder a definovat akci u ovládacího prvku:
Znovu upravte soubor ViewController.cs a přidejte následující metodu:
partial void OptionTwoFlipped (Foundation.NSObject sender) {
// Display the state of the option switch
Console.WriteLine("Option Two: {0}", OptionTwo.Value);
}
Důležité
Měli byste použít buď událost , nebo definovat akci v Interface Builder, ale neměli byste používat obě metody současně, jinak mohou být vzájemně v konfliktu.
Souhrn
Tento článek podrobně popisuje vytvoření znovu použitelného ovládacího prvku custom Uživatelské rozhraní v aplikaci Xamarin.Mac. Viděli jsme, jak nakreslit uživatelské rozhraní vlastních ovládacích prvků, dva hlavní způsoby reakce na vstup myši a uživatele a jak zveřejnit nový ovládací prvek pro akce v uživatelském rozhraní Interface Builder.






