Nabídky v Xamarin.Mac
Tento článek popisuje práci s nabídkami v aplikaci Xamarin.Mac. Popisuje vytváření a údržbu nabídek a položek nabídek v Xcode a Interface Builderu a práci s nimi programově.
Při práci s C# a .NET v aplikaci Xamarin.Mac máte přístup ke stejným nabídkám Cocoa, ve Objective-C kterých vývojář pracuje a Xcode. Vzhledem k tomu, že se Xamarin.Mac integruje přímo s Xcode, můžete pomocí Tvůrce rozhraní Xcode vytvářet a udržovat položky nabídek, nabídek a položek nabídek (nebo je volitelně vytvářet přímo v kódu jazyka C#).
Nabídky jsou nedílnou součástí uživatelského prostředí aplikace pro Mac a běžně se zobrazují v různých částech uživatelského rozhraní:
- Řádek nabídek aplikace – Toto je hlavní nabídka, která se zobrazí v horní části obrazovky pro každou aplikaci pro Mac.
- Místní nabídky – Zobrazí se, když uživatel klikne pravým tlačítkem myši nebo stisknutou stisknutou položku v okně.
- Stavový řádek – Jedná se o oblast na pravé straně řádku nabídek aplikace, která se zobrazí v horní části obrazovky (vlevo od hodin řádku nabídek) a při přidávání položek doleva.
- Nabídka Dok – nabídka pro každou aplikaci v doku, která se zobrazí, když uživatel klikne pravým tlačítkem nebo stisknutou klávesou CONTROL klikne na ikonu aplikace nebo když uživatel klikne na ikonu levým tlačítkem a podrží tlačítko myši.
- Automaticky otevírané tlačítko a rozevírací seznamy – automaticky otevírané tlačítko zobrazí vybranou položku a zobrazí seznam možností, ze které můžete vybrat po kliknutí uživatelem. Rozevírací seznam je typ automaticky otevíraného tlačítka, které se obvykle používá pro výběr příkazů specifických pro kontext aktuálního úkolu. Obě můžou být zobrazeny kdekoli v okně.
V tomto článku se podíváme na základy práce s panely nabídek Cocoa, nabídkami a položkami nabídek 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.
Můžete se také podívat na třídy a metody v jazyce C#, které jsou uvedeny v Objective-C oddílu dokumentu Internals Xamarin.Mac, vysvětluje Register
Export
a atributy používané k připojení tříd jazyka C# k Objective-C objektům a prvkům uživatelského rozhraní.
Řádek nabídek aplikace
Na rozdíl od aplikací běžících v operačním systému Windows, kde každé okno může mít připojený vlastní řádek nabídek, má každá aplikace spuštěná v systému macOS jeden řádek nabídek, který běží v horní části obrazovky, který se používá pro každé okno v dané aplikaci:
Položky na tomto řádku nabídek se aktivují nebo deaktivují na základě aktuálního kontextu nebo stavu aplikace a jeho uživatelského rozhraní v libovolném okamžiku. Například: Pokud uživatel vybere textové pole, budou položky v nabídce Úpravy povolené, například Kopírovat a Vyjmout.
Podle Apple a ve výchozím nastavení mají všechny aplikace macOS standardní sadu nabídek a položek nabídek, které se zobrazují na řádku nabídek aplikace:
- Nabídka Apple – Tato nabídka poskytuje přístup k systémovým položkám, které jsou uživatelům k dispozici vždy bez ohledu na to, jaká aplikace je spuštěná. Vývojář tyto položky nemůže změnit.
- Nabídka aplikace – Tato nabídka zobrazuje název aplikace tučně a pomáhá uživateli identifikovat, která aplikace je aktuálně spuštěná. Obsahuje položky, které se vztahují na aplikaci jako celek, a ne na daný dokument nebo proces, jako je ukončení aplikace.
- Nabídka Soubor – Položky používané k vytvoření, otevření nebo uložení dokumentů, se kterými vaše aplikace pracuje. Pokud vaše aplikace není založená na dokumentech, můžete tuto nabídku přejmenovat nebo odebrat.
- Nabídka Upravit – Obsahuje příkazy, jako je Vyjmout, Kopírovat a Vložit , které slouží k úpravám nebo úpravám prvků v uživatelském rozhraní aplikace.
- Nabídka Formát – Pokud aplikace pracuje s textem, obsahuje tato nabídka příkazy pro úpravu formátování tohoto textu.
- Nabídka Zobrazení – Obsahuje příkazy, které ovlivňují zobrazení obsahu (zobrazení) v uživatelském rozhraní aplikace.
- Nabídky specifické pro aplikaci – Jedná se o nabídky specifické pro vaši aplikaci (například nabídku záložek pro webový prohlížeč). Měly by se zobrazit mezi nabídkami Zobrazení a Okna na panelu.
- Nabídka Okna – Obsahuje příkazy pro práci s okny v aplikaci a také seznam otevřených oken.
- Nabídka Nápověda – Pokud vaše aplikace poskytuje nápovědu na obrazovce, měla by být nabídka Nápověda na panelu vpravo.
Další informace o řádku nabídek aplikace a standardních nabídkách a položkách nabídek najdete v pokynech pro lidské rozhraní společnosti Apple.
Výchozí řádek nabídek aplikace
Pokaždé, když vytvoříte nový projekt Xamarin.Mac, automaticky získáte standardní výchozí řádek nabídek aplikace s typickými položkami, které by aplikace pro macOS normálně měla (jak je popsáno v předchozí části). Výchozí řádek nabídek vaší aplikace se definuje v souboru Main.storyboard (spolu se zbytkem uživatelského rozhraní vaší aplikace) v oblasti řešení v oblasti řešení:
Poklikáním otevřete soubor Main.storyboard pro úpravy v Tvůrci rozhraní Xcode a zobrazí se rozhraní editoru nabídek:
Zde můžeme kliknout na položky, jako je například otevřít položku nabídky v nabídce Soubor , upravit nebo upravit její vlastnosti v Inspektoru atributů:
Dále v tomto článku se seznámíme s přidáváním, úpravami a odstraňováním nabídek a položek. Prozatím chceme jenom zjistit, jaké nabídky a položky nabídek jsou ve výchozím nastavení dostupné a jak byly automaticky zpřístupněny kódu prostřednictvím sady předdefinovaných výstupů a akcí (další informace najdete v dokumentaci k výstupům a akcím ).
Pokud například klikneme na inspektor Připojení ion pro položku nabídky Otevřít, uvidíme, že je automaticky připojena k openDocument:
akci:
Pokud vyberete první respondér v hierarchii rozhraní a v Připojení ion Inspectoru se posunete dolů a zobrazí se definice openDocument:
akce, ke které je položka nabídky Otevřít připojena (spolu s několika dalšími výchozími akcemi pro aplikaci, která jsou a nejsou automaticky připojena k ovládacím prvkům):
Proč je to důležité? V další části se dozvíte, jak tyto automaticky definované akce fungují s dalšími prvky uživatelského rozhraní Cocoa, které automaticky povolí a zakáže položky nabídek, a také poskytují integrované funkce pro položky.
Později tyto předdefinované akce použijeme k povolení a zakázání položek z kódu a poskytnutí vlastních funkcí při jejich výběru.
Předdefinované funkce nabídky
Pokud jste před přidáním jakýchkoli položek uživatelského rozhraní nebo kódu spustili nově vytvořenou aplikaci Xamarin.Mac, všimnete si, že některé položky jsou automaticky připojené a povolené (s plnou funkčností automaticky předdefinovanou), jako je například položka Ukončit v nabídce aplikace :
I když jiné položky nabídky, jako jsou vyjmutí, kopírování a vložení , nejsou:
Zastavme aplikaci a poklikáním na soubor Main.storyboard v oblasti řešení ji otevřete pro úpravy v Tvůrci rozhraní Xcode. Potom přetáhněte textové zobrazení z knihovny do kontroleru zobrazení okna v editoru rozhraní:
V Editoru omezení připneme textové zobrazení na hrany okna a nastavíme ho tam, kde se zvětší a zmenší s oknem kliknutím na všechny čtyři červené paprsky v horní části editoru a kliknutím na tlačítko Přidat 4 omezení:
Uložte změny návrhu uživatelského rozhraní a přepněte zpět Visual Studio pro Mac, aby se změny synchronizovaly s projektem Xamarin.Mac. Teď spusťte aplikaci, zadejte do textového zobrazení nějaký text, vyberte ho a otevřete nabídku Upravit :
Všimněte si, jak jsou položky Vyjmout, Kopírovat a Vložit automaticky povoleny a plně funkční, a to vše bez psaní jednoho řádku kódu.
Co se tu děje? Nezapomeňte, že předdefinované předdefinované akce, které se připojují k výchozím položkám nabídky (jak je uvedeno výše), většina prvků uživatelského rozhraní Cocoa, které jsou součástí macOS, mají integrované hooky ke konkrétním akcím (například copy:
). Takže když jsou přidány do okna, aktivní a vybrané, odpovídající položka nabídky nebo položky připojené k této akci jsou automaticky povoleny. Pokud uživatel vybere tuto položku nabídky, funkce integrované do prvku uživatelského rozhraní se zavolá a spustí, a to vše bez zásahu vývojáře.
Povolení a zakázání nabídek a položek
Ve výchozím nastavení se pokaždé, když dojde k události uživatele, NSMenu
automaticky povolí a zakáže každou viditelnou nabídku a položku nabídky na základě kontextu aplikace. Položku můžete povolit nebo zakázat třemi způsoby:
- Automatické povolení nabídky – Položka nabídky je povolena, pokud
NSMenu
může najít odpovídající objekt, který reaguje na akci, na kterou je položka připojena kabelem. Například výše uvedené textové zobrazení, které mělo předdefinované připojení kcopy:
akci. - Vlastní akce a validateMenuItem: – Pro libovolnou položku nabídky, která je svázaná s oknem nebo vlastní akcí kontroleru zobrazení, můžete
validateMenuItem:
přidat akci a ručně povolit nebo zakázat položky nabídky. - Ruční povolení nabídky – Vlastnost každého z nich
NSMenuItem
můžete ručně nastavitEnabled
tak, aby se jednotlivé položky v nabídce povolily nebo zakázaly jednotlivě.
Chcete-li zvolit systém, nastavte AutoEnablesItems
vlastnost NSMenu
. true
je automatické (výchozí chování) a false
je ruční.
Důležité
Pokud se rozhodnete použít ruční povolení nabídky, žádná z položek nabídky, dokonce i ty, které řídí třídy AppKit jako NSTextView
, se aktualizují automaticky. Budete zodpovědní za povolení a zakázání všech položek ručně v kódu.
Použití validateMenuItem
Jak je uvedeno výše, pro libovolnou položku nabídky, která je vázána na vlastní akci okna nebo zobrazení kontroleru, můžete přidat validateMenuItem:
akci a ručně povolit nebo zakázat položky nabídky.
V následujícím příkladu Tag
bude vlastnost použita k rozhodnutí o typu položky nabídky, která bude povolena nebo zakázána validateMenuItem:
akcí na základě stavu vybraného textu v objektu NSTextView
. Vlastnost Tag
byla nastavena v Tvůrci rozhraní pro každou položku nabídky:
A do kontroleru zobrazení se přidal následující kód:
[Action("validateMenuItem:")]
public bool ValidateMenuItem (NSMenuItem item) {
// Take action based on the menu item type
// (As specified in its Tag)
switch (item.Tag) {
case 1:
// Wrap menu items should only be available if
// a range of text is selected
return (TextEditor.SelectedRange.Length > 0);
case 2:
// Quote menu items should only be available if
// a range is NOT selected.
return (TextEditor.SelectedRange.Length == 0);
}
return true;
}
Když se tento kód spustí a v NSTextView
řadiči zobrazení nejsou vybrány žádné texty, jsou zakázány dvě položky nabídky obtékání (i když jsou připojené k akcím v kontroleru zobrazení):
Pokud je vybraný oddíl textu a nabídka se znovu otevře, budou k dispozici dvě položky zalamované nabídky:
Povolení a reakce na položky nabídky v kódu
Jak jsme viděli výše, stačí do návrhu uživatelského rozhraní přidat specifické prvky uživatelského rozhraní Cocoa (například textové pole), několik výchozích položek nabídky se povolí a bude fungovat automaticky, aniž byste museli psát žádný kód. Teď se podíváme na přidání vlastního kódu jazyka C# do projektu Xamarin.Mac, abychom povolili položku nabídky a poskytli funkce, když ji uživatel vybere.
Řekněme například, že chceme, aby uživatel mohl vybrat složku pomocí položky Otevřít v nabídce Soubor . Vzhledem k tomu, že chceme, aby to byla funkce pro celou aplikaci, a ne jen na prvek pro poskytnutí okna nebo uživatelského rozhraní, přidáme kód, který to zpracuje delegátovi aplikace.
V oblasti řešení poklikáním AppDelegate.CS
otevřete soubor pro úpravy:
Pod metodu DidFinishLaunching
přidejte následující kód:
[Export ("openDocument:")]
void OpenDialog (NSObject sender)
{
var dlg = NSOpenPanel.OpenPanel;
dlg.CanChooseFiles = false;
dlg.CanChooseDirectories = true;
if (dlg.RunModal () == 1) {
var alert = new NSAlert () {
AlertStyle = NSAlertStyle.Informational,
InformativeText = "At this point we should do something with the folder that the user just selected in the Open File Dialog box...",
MessageText = "Folder Selected"
};
alert.RunModal ();
}
}
Teď spustíme aplikaci a otevřete nabídku Soubor :
Všimněte si, že položka nabídky Otevřít je teď povolená. Pokud ho vybereme, zobrazí se otevřené dialogové okno:
Pokud klikneme na tlačítko Otevřít , zobrazí se naše zpráva s upozorněním:
Hlavní řádek zde byl [Export ("openDocument:")]
, říká NSMenu
, že naše AppDelegate má metodu void OpenDialog (NSObject sender)
, která reaguje na openDocument:
akci. Pokud si budete pamatovat výše, položka nabídky Otevřít se automaticky připojí k této akci ve výchozím nastavení v Tvůrci rozhraní:
Teď se podíváme na vytvoření vlastní nabídky, položek nabídek a akcí a reagování na ně v kódu.
Práce s otevřenou poslední nabídkou
Ve výchozím nastavení obsahuje nabídka Soubor položku Otevřít poslední, která sleduje posledních několik souborů, které uživatel otevřel ve vaší aplikaci. Pokud vytváříte aplikaci Xamarin.Mac založenou NSDocument
na Xamarin.Mac, bude tato nabídka automaticky zpracována. Pro jakýkoli jiný typ aplikace Xamarin.Mac budete zodpovědní za správu a odpovídání na tuto položku nabídky ručně.
Pokud chcete nabídku Otevřít poslední otevřít ručně zpracovat, musíte nejprve informovat, že byl otevřen nebo uložen nový soubor pomocí následujícího příkazu:
// Add document to the Open Recent menu
NSDocumentController.SharedDocumentController.NoteNewRecentDocumentURL(url);
I když vaše aplikace nepoužívá NSDocuments
, stále používáte NSDocumentController
k údržbě nabídky Otevřít poslední odesláním NSUrl
umístění souboru metodě NoteNewRecentDocumentURL
SharedDocumentController
souboru .
Dále je potřeba přepsat metodu OpenFile
delegáta aplikace, aby se otevřel libovolný soubor, který uživatel vybere z nabídky Otevřít poslední . Příklad:
public override bool OpenFile (NSApplication sender, string filename)
{
// Trap all errors
try {
filename = filename.Replace (" ", "%20");
var url = new NSUrl ("file://"+filename);
return OpenFile(url);
} catch {
return false;
}
}
Vraťte true
se, pokud je možné soubor otevřít, jinak se vrátí false
a uživateli se zobrazí předdefinované upozornění, že soubor nelze otevřít.
Vzhledem k tomu, že název souboru a cesta vrácené z nabídky Otevřít poslední , může obsahovat mezeru, musíme tento znak před vytvořením nebo NSUrl
se zobrazí chyba. Provedeme to pomocí následujícího kódu:
filename = filename.Replace (" ", "%20");
Nakonec vytvoříme odkazující NSUrl
na soubor a použijeme pomocnou metodu v delegátu aplikace k otevření nového okna a načtení souboru do něj:
var url = new NSUrl ("file://"+filename);
return OpenFile(url);
Abychom všechno strhli dohromady, podívejme se na ukázkovou implementaci v souboru AppDelegate.cs :
using AppKit;
using Foundation;
using System.IO;
using System;
namespace MacHyperlink
{
[Register ("AppDelegate")]
public class AppDelegate : NSApplicationDelegate
{
#region Computed Properties
public int NewWindowNumber { get; set;} = -1;
#endregion
#region Constructors
public AppDelegate ()
{
}
#endregion
#region Override Methods
public override void DidFinishLaunching (NSNotification notification)
{
// Insert code here to initialize your application
}
public override void WillTerminate (NSNotification notification)
{
// Insert code here to tear down your application
}
public override bool OpenFile (NSApplication sender, string filename)
{
// Trap all errors
try {
filename = filename.Replace (" ", "%20");
var url = new NSUrl ("file://"+filename);
return OpenFile(url);
} catch {
return false;
}
}
#endregion
#region Private Methods
private bool OpenFile(NSUrl url) {
var good = false;
// Trap all errors
try {
var path = url.Path;
// 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;
}
}
// 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.SetLanguageFromPath(path);
viewController.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
viewController.View.Window.RepresentedUrl = url;
// Add document to the Open Recent menu
NSDocumentController.SharedDocumentController.NoteNewRecentDocumentURL(url);
// Make as successful
good = true;
} catch {
// Mark as bad file on error
good = false;
}
// Return results
return good;
}
#endregion
#region actions
[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) {
// Open the document in a new window
OpenFile (url);
}
}
}
#endregion
}
}
V závislosti na požadavcích aplikace možná nebudete chtít, aby uživatel současně otevřel stejný soubor ve více než jednom okně. Pokud uživatel v naší ukázkové aplikaci zvolí soubor, který je již otevřený (buď z položek nabídky Otevřít poslední , nebo Otevřít), okno obsahující soubor se přenese do popředí.
K tomu jsme v pomocné metodě použili následující kód:
var path = url.Path;
// 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;
}
}
Naši třídu jsme navrhli ViewController
tak, aby držela cestu k souboru ve své Path
vlastnosti. V dalším kroku projdeme všechna aktuálně otevřená okna v aplikaci. Pokud je soubor již otevřený v jednom z oken, přenese se na přední straně všech ostatních oken pomocí:
NSApplication.SharedApplication.Windows[n].MakeKeyAndOrderFront(this);
Pokud se nenajde žádná shoda, otevře se nové okno se načteným souborem a soubor se zaznačí v nabídce Otevřít poslední :
// 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.SetLanguageFromPath(path);
viewController.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
viewController.View.Window.RepresentedUrl = url;
// Add document to the Open Recent menu
NSDocumentController.SharedDocumentController.NoteNewRecentDocumentURL(url);
Práce s vlastními akcemi oken
Stejně jako předdefinované akce prvního respondéru , které jsou předem připojené ke standardním položkám nabídek, můžete vytvořit nové, vlastní akce a připojit je k položkám nabídky v Tvůrci rozhraní.
Nejprve definujte vlastní akci na jednom z kontrolerů oken vaší aplikace. Příklad:
[Action("defineKeyword:")]
public void defineKeyword (NSObject sender) {
// Preform some action when the menu is selected
Console.WriteLine ("Request to define keyword");
}
Potom poklikejte na soubor scénáře aplikace v oblasti řešení a otevřete ho pro úpravy v Tvůrci rozhraní Xcode. Vyberte první respondér ve scéně aplikace a pak přepněte na Inspektor atributů:
Kliknutím na + tlačítko v dolní části inspektoru atributů přidejte novou vlastní akci:
Pojmenujte ho stejně jako vlastní akci, kterou jste vytvořili v kontroleru okna:
Control-click and drag from a menu item to the First Responder under the Application Scene. V automaticky otevírané nabídce vyberte novou akci, kterou jste právě vytvořili (defineKeyword:
v tomto příkladu):
Uložte změny do scénáře a vraťte se do Visual Studio pro Mac, aby se změny synchronizovaly. Pokud spustíte aplikaci, položka nabídky, ke které jste vlastní akci připojili, se automaticky povolí nebo zakáže (na základě okna s otevřenou akcí) a výběrem položky nabídky se aktivuje akce:
Přidávání, úpravy a odstraňování nabídek
Jak jsme viděli v předchozích částech, aplikace Xamarin.Mac obsahuje přednastavený počet výchozích nabídek a položek nabídek, na které se konkrétní ovládací prvky uživatelského rozhraní automaticky aktivují a reagují. Viděli jsme také, jak do aplikace přidat kód, který umožní tyto výchozí položky a odpovídá na ně.
V této části se podíváme na odebrání položek nabídky, které nepotřebujeme, přeuspořádání nabídek a přidávání nových nabídek, položek nabídek a akcí.
Dvakrát klikněte na soubor Main.storyboard v oblasti řešení a otevřete ho pro úpravy:
Pro naši konkrétní aplikaci Xamarin.Mac nebudeme používat výchozí nabídku Zobrazení , takže ji odebereme. V hierarchii rozhraní vyberte položku nabídky Zobrazení, která je součástí hlavního řádku nabídek:
Stisknutím klávesy Delete nebo Backspace nabídku odstraňte. V dalším kroku nebudeme používat všechny položky v nabídce Formát a chceme přesunout položky, které budeme používat mimo podsítě. V hierarchii rozhraní vyberte následující položky nabídky:
Přetáhněte položky pod nadřazenou nabídku z podadresní nabídky , kde jsou aktuálně:
Nabídka by teď měla vypadat takto:
Teď přetáhneme dílčí nabídku Text z nabídky Formát a umístíme ji do hlavního řádku nabídek mezi nabídkami Formát a Okno :
Vraťme se zpátky pod nabídku Formát a odstraňme položku dílčí nabídky Písmo . Dále vyberte nabídku Formát a přejmenujte ho na Písmo:
V dalším kroku vytvoříme vlastní nabídku předdefinovaných frází, které se automaticky přidají k textu v textovém zobrazení, když jsou vybrané. Do vyhledávacího pole v dolní části inspektoru knihovny zadejte "menu". Usnadníte tak hledání a práci se všemi prvky uživatelského rozhraní nabídky:
Teď vytvoříme naši nabídku takto:
Přetáhněte položku nabídky z nástroje Library Inspector do řádku nabídek mezi nabídkami Text a Okno:
Přejmenujte položku "Fráze":
Potom přetáhněte nabídku z inspektoru knihovny:
Přetáhněte nabídku na novou položku nabídky, kterou jsme právě vytvořili, a změňte její název na "Fráze":
Teď přejmenujme tři výchozí položky nabídky Address (Adresa), Date (Datum) a Greeting (Pozdrav):
Pojďme přidat čtvrtou položku nabídky přetažením položky nabídky z inspektoru knihovny a jeho voláním "Podpis":
Uložte změny do řádku nabídek.
Teď vytvoříme sadu vlastních akcí, aby byly naše nové položky nabídky zpřístupněny kódu jazyka C#. V Xcode přepneme do zobrazení Asistent :
Pojďme udělat toto:
Control-drag from the Address menu item to the AppDelegate.h file.
Přepněte typ Připojení ion na akci:
Zadejte název frázeAddress a stisknutím tlačítka Připojení vytvořte novou akci:
Opakujte výše uvedené kroky pro položky nabídky Datum, Pozdrav a Podpis :
Uložte změny do řádku nabídek.
Dále potřebujeme vytvořit výstup pro textové zobrazení, abychom mohli upravit jeho obsah z kódu. V Editoru asistentů vyberte soubor ViewController.h a vytvořte novou zásuvku s názvem documentText
:
Vraťte se do Visual Studio pro Mac, abyste synchronizovali změny z Xcode. Potom upravte soubor ViewController.cs a udělejte ho takto:
using System;
using AppKit;
using Foundation;
namespace MacMenus
{
public partial class ViewController : NSViewController
{
#region Application Access
public static AppDelegate App {
get { return (AppDelegate)NSApplication.SharedApplication.Delegate; }
}
#endregion
#region Computed Properties
public override NSObject RepresentedObject {
get {
return base.RepresentedObject;
}
set {
base.RepresentedObject = value;
// Update the view, if already loaded.
}
}
public string Text {
get { return documentText.Value; }
set { documentText.Value = value; }
}
#endregion
#region Constructors
public ViewController (IntPtr handle) : base (handle)
{
}
#endregion
#region Override Methods
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Do any additional setup after loading the view.
}
public override void ViewWillAppear ()
{
base.ViewWillAppear ();
App.textEditor = this;
}
public override void ViewWillDisappear ()
{
base.ViewDidDisappear ();
App.textEditor = null;
}
#endregion
}
}
Tím se zpřístupní text našeho textového zobrazení mimo ViewController
třídu a informuje delegáta aplikace, když okno získá nebo ztratí fokus. Teď upravte soubor AppDelegate.cs a udělejte ho takto:
using AppKit;
using Foundation;
using System;
namespace MacMenus
{
[Register ("AppDelegate")]
public partial class AppDelegate : NSApplicationDelegate
{
#region Computed Properties
public ViewController textEditor { get; set;} = null;
#endregion
#region Constructors
public AppDelegate ()
{
}
#endregion
#region Override Methods
public override void DidFinishLaunching (NSNotification notification)
{
// Insert code here to initialize your application
}
public override void WillTerminate (NSNotification notification)
{
// Insert code here to tear down your application
}
#endregion
#region Custom actions
[Export ("openDocument:")]
void OpenDialog (NSObject sender)
{
var dlg = NSOpenPanel.OpenPanel;
dlg.CanChooseFiles = false;
dlg.CanChooseDirectories = true;
if (dlg.RunModal () == 1) {
var alert = new NSAlert () {
AlertStyle = NSAlertStyle.Informational,
InformativeText = "At this point we should do something with the folder that the user just selected in the Open File Dialog box...",
MessageText = "Folder Selected"
};
alert.RunModal ();
}
}
partial void phrasesAddress (Foundation.NSObject sender) {
textEditor.Text += "Xamarin HQ\n394 Pacific Ave, 4th Floor\nSan Francisco CA 94111\n\n";
}
partial void phrasesDate (Foundation.NSObject sender) {
textEditor.Text += DateTime.Now.ToString("D");
}
partial void phrasesGreeting (Foundation.NSObject sender) {
textEditor.Text += "Dear Sirs,\n\n";
}
partial void phrasesSignature (Foundation.NSObject sender) {
textEditor.Text += "Sincerely,\n\nKevin Mullins\nXamarin,Inc.\n";
}
#endregion
}
}
Tady jsme vytvořili AppDelegate
částečnou třídu, abychom mohli používat akce a výstupy, které jsme definovali v Tvůrci rozhraní. Zveřejňujeme textEditor
také sledování, na které okno je aktuálně fokus.
K zpracování vlastní nabídky a položek nabídky se používají následující metody:
partial void phrasesAddress (Foundation.NSObject sender) {
if (textEditor == null) return;
textEditor.Text += "Xamarin HQ\n394 Pacific Ave, 4th Floor\nSan Francisco CA 94111\n\n";
}
partial void phrasesDate (Foundation.NSObject sender) {
if (textEditor == null) return;
textEditor.Text += DateTime.Now.ToString("D");
}
partial void phrasesGreeting (Foundation.NSObject sender) {
if (textEditor == null) return;
textEditor.Text += "Dear Sirs,\n\n";
}
partial void phrasesSignature (Foundation.NSObject sender) {
if (textEditor == null) return;
textEditor.Text += "Sincerely,\n\nKevin Mullins\nXamarin,Inc.\n";
}
Když teď spustíme naši aplikaci, všechny položky v nabídce Fráze budou aktivní a při výběru této fráze se do textového zobrazení přidají:
Teď, když máme základy práce s panelem nabídek aplikace dole, se podíváme na vytvoření vlastní kontextové nabídky.
Vytváření nabídek z kódu
Kromě vytváření nabídek a položek nabídek pomocí Tvůrce rozhraní Xcode může docházet k časům, kdy aplikace Xamarin.Mac potřebuje vytvořit, upravit nebo odebrat nabídku, dílčí nabídku nebo položku nabídky z kódu.
V následujícím příkladu se vytvoří třída, která bude obsahovat informace o položkách nabídky a dílčích nabídkách, které budou dynamicky vytvořeny za běhu:
using System;
using System.Collections.Generic;
using Foundation;
using AppKit;
namespace AppKit.TextKit.Formatter
{
public class LanguageFormatCommand : NSObject
{
#region Computed Properties
public string Title { get; set; } = "";
public string Prefix { get; set; } = "";
public string Postfix { get; set; } = "";
public List<LanguageFormatCommand> SubCommands { get; set; } = new List<LanguageFormatCommand>();
#endregion
#region Constructors
public LanguageFormatCommand () {
}
public LanguageFormatCommand (string title)
{
// Initialize
this.Title = title;
}
public LanguageFormatCommand (string title, string prefix)
{
// Initialize
this.Title = title;
this.Prefix = prefix;
}
public LanguageFormatCommand (string title, string prefix, string postfix)
{
// Initialize
this.Title = title;
this.Prefix = prefix;
this.Postfix = postfix;
}
#endregion
}
}
Přidávání nabídek a položek
S touto třídou definovanou následující rutinou parsuje kolekci LanguageFormatCommand
objektů a rekurzivně sestaví nové nabídky a položky nabídek tak, že je připojí do dolní části existující nabídky (vytvořené v Tvůrci rozhraní), která byla předána:
private void AssembleMenu(NSMenu menu, List<LanguageFormatCommand> commands) {
NSMenuItem menuItem;
// Add any formatting commands to the Formatting menu
foreach (LanguageFormatCommand command in commands) {
// Add separator or item?
if (command.Title == "") {
menuItem = NSMenuItem.SeparatorItem;
} else {
menuItem = new NSMenuItem (command.Title);
// Submenu?
if (command.SubCommands.Count > 0) {
// Yes, populate submenu
menuItem.Submenu = new NSMenu (command.Title);
AssembleMenu (menuItem.Submenu, command.SubCommands);
} else {
// No, add normal menu item
menuItem.Activated += (sender, e) => {
// Apply the command on the selected text
TextEditor.PerformFormattingCommand (command);
};
}
}
menu.AddItem (menuItem);
}
}
Pro každý LanguageFormatCommand
objekt, který má prázdnou Title
vlastnost, tato rutina vytvoří položku nabídky Oddělovač (tenká šedá čára) mezi oddíly nabídek:
menuItem = NSMenuItem.SeparatorItem;
Pokud je název zadaný, vytvoří se nová položka nabídky s tímto názvem:
menuItem = new NSMenuItem (command.Title);
LanguageFormatCommand
Pokud objekt obsahuje podřízené LanguageFormatCommand
objekty, vytvoří se podnabídka a AssembleMenu
metoda je rekurzivně volána k sestavení této nabídky:
menuItem.Submenu = new NSMenu (command.Title);
AssembleMenu (menuItem.Submenu, command.SubCommands);
Pro libovolnou novou položku nabídky, která nemá podnabídky, se přidá kód pro zpracování položky nabídky vybrané uživatelem:
menuItem.Activated += (sender, e) => {
// Do something when the menu item is selected
...
};
Testování vytvoření nabídky
Pokud byla vytvořena následující kolekce LanguageFormatCommand
objektů, je-li vytvořen veškerý výše uvedený kód:
// Define formatting commands
FormattingCommands.Add(new LanguageFormatCommand("Strong","**","**"));
FormattingCommands.Add(new LanguageFormatCommand("Emphasize","_","_"));
FormattingCommands.Add(new LanguageFormatCommand("Inline Code","`","`"));
FormattingCommands.Add(new LanguageFormatCommand("Code Block","```\n","\n```"));
FormattingCommands.Add(new LanguageFormatCommand("Comment","<!--","-->"));
FormattingCommands.Add (new LanguageFormatCommand ());
FormattingCommands.Add(new LanguageFormatCommand("Unordered List","* "));
FormattingCommands.Add(new LanguageFormatCommand("Ordered List","1. "));
FormattingCommands.Add(new LanguageFormatCommand("Block Quote","> "));
FormattingCommands.Add (new LanguageFormatCommand ());
var Headings = new LanguageFormatCommand ("Headings");
Headings.SubCommands.Add(new LanguageFormatCommand("Heading 1","# "));
Headings.SubCommands.Add(new LanguageFormatCommand("Heading 2","## "));
Headings.SubCommands.Add(new LanguageFormatCommand("Heading 3","### "));
Headings.SubCommands.Add(new LanguageFormatCommand("Heading 4","#### "));
Headings.SubCommands.Add(new LanguageFormatCommand("Heading 5","##### "));
Headings.SubCommands.Add(new LanguageFormatCommand("Heading 6","###### "));
FormattingCommands.Add (Headings);
FormattingCommands.Add(new LanguageFormatCommand ());
FormattingCommands.Add(new LanguageFormatCommand("Link","[","]()"));
FormattingCommands.Add(new LanguageFormatCommand("Image","![](",")"));
FormattingCommands.Add(new LanguageFormatCommand("Image Link","[![](",")](LinkImageHere)"));
A tato kolekce se předá AssembleMenu
funkci (s nastavením nabídky Format jako základ), vytvoří se následující dynamické nabídky a položky nabídek:
Odebírání nabídek a položek
Pokud potřebujete z uživatelského rozhraní aplikace odebrat libovolnou nabídku nebo položku nabídky, můžete metodu NSMenu
třídy jednoduše použít RemoveItemAt
tak, že jí poskytnete nulový index položky, který chcete odebrat.
Pokud chcete například odebrat nabídky a položky nabídky vytvořené výše uvedenou rutinou, můžete použít následující kód:
public void UnpopulateFormattingMenu(NSMenu menu) {
// Remove any additional items
for (int n = (int)menu.Count - 1; n > 4; --n) {
menu.RemoveItemAt (n);
}
}
V případě výše uvedeného kódu se první čtyři položky nabídky vytvoří v Tvůrci rozhraní Xcode a v aplikaci jsou pryč, takže se neodeberou dynamicky.
Místní nabídky
Místní nabídky se zobrazí, když uživatel klikne pravým tlačítkem myši nebo stisknutou stisknutou položku v okně. Ve výchozím nastavení má několik prvků uživatelského rozhraní integrovaných do systému macOS k nim připojené kontextové nabídky (například textové zobrazení). Někdy ale můžeme chtít vytvořit vlastní kontextové nabídky pro prvek uživatelského rozhraní, který jsme přidali do okna.
Pojďme upravit soubor Main.storyboard v Xcode a přidat okno okna do našeho návrhu, nastavit jeho třídu na NSPanel v Nástroji Identity Inspector, přidat novou položku Pomocníka do nabídky Okno a připojit ho k novému okně pomocí show Segue:
Pojďme udělat toto:
Přetáhněte popisek z inspektoru knihovny do okna Panel a nastavte jeho text na Vlastnost:
Potom přetáhněte nabídku z nástroje Library Inspector do kontroleru zobrazení v hierarchii zobrazení a přejmenujte tři výchozí položky nabídky Dokument, Text a Písmo:
Teď ovládací prvek přetáhněte z popisku vlastnosti do nabídky:
V místním dialogovém okně vyberte Nabídku:
V Kontrole identit nastavte třídu kontroleru zobrazení na PanelViewController:
Přepněte zpět na Visual Studio pro Mac, aby se synchronizoval, a pak se vraťte do Tvůrce rozhraní.
Přepněte do Editoru asistentů a vyberte soubor PanelViewController.h .
Vytvořte akci pro položku nabídky Dokument s názvem
propertyDocument
:Opakujte vytváření akcí pro zbývající položky nabídky:
Nakonec vytvořte výstup pro popisek vlastnosti s názvem
propertyLabel
:Uložte změny a vraťte se do Visual Studio pro Mac pro synchronizaci s Xcode.
Upravte soubor PanelViewController.cs a přidejte následující kód:
partial void propertyDocument (Foundation.NSObject sender) {
propertyLabel.StringValue = "Document";
}
partial void propertyFont (Foundation.NSObject sender) {
propertyLabel.StringValue = "Font";
}
partial void propertyText (Foundation.NSObject sender) {
propertyLabel.StringValue = "Text";
}
Když teď spustíme aplikaci a klikneme pravým tlačítkem myši na popisek vlastnosti na panelu, zobrazí se naše vlastní kontextová nabídka. Pokud vybereme položku a položku z nabídky, hodnota popisku se změní:
Teď se podíváme na vytváření nabídek stavového řádku.
Nabídky stavového řádku
Nabídky stavového řádku zobrazují kolekci položek stavové nabídky, které poskytují interakci s uživatelem nebo jejich zpětnou vazbu, například nabídku nebo obrázek odrážející stav aplikace. Nabídka stavového řádku aplikace je povolená a aktivní, i když je aplikace spuštěná na pozadí. Stavový řádek na úrovni celého systému se nachází na pravé straně řádku nabídek aplikace a je jediným stavovým řádkem, který je aktuálně dostupný v systému macOS.
Pojďme upravit náš soubor AppDelegate.cs a nastavit metodu DidFinishLaunching
takto:
public override void DidFinishLaunching (NSNotification notification)
{
// Create a status bar menu
NSStatusBar statusBar = NSStatusBar.SystemStatusBar;
var item = statusBar.CreateStatusItem (NSStatusItemLength.Variable);
item.Title = "Text";
item.HighlightMode = true;
item.Menu = new NSMenu ("Text");
var address = new NSMenuItem ("Address");
address.Activated += (sender, e) => {
PhraseAddress(address);
};
item.Menu.AddItem (address);
var date = new NSMenuItem ("Date");
date.Activated += (sender, e) => {
PhraseDate(date);
};
item.Menu.AddItem (date);
var greeting = new NSMenuItem ("Greeting");
greeting.Activated += (sender, e) => {
PhraseGreeting(greeting);
};
item.Menu.AddItem (greeting);
var signature = new NSMenuItem ("Signature");
signature.Activated += (sender, e) => {
PhraseSignature(signature);
};
item.Menu.AddItem (signature);
}
NSStatusBar statusBar = NSStatusBar.SystemStatusBar;
poskytuje přístup k stavovém řádku na úrovni celého systému. var item = statusBar.CreateStatusItem (NSStatusItemLength.Variable);
vytvoří novou položku stavového řádku. Odtud vytvoříme nabídku a řadu položek nabídky a připojíme ji k položce stavového řádku, kterou jsme právě vytvořili.
Pokud spustíme aplikaci, zobrazí se nová položka stavového řádku. Výběrem položky z nabídky změníte text v textovém zobrazení:
V dalším kroku se podíváme na vytvoření vlastních položek nabídky doku.
Vlastní nabídky dokování
Když uživatel klikne pravým tlačítkem myši nebo control klikne na ikonu aplikace v docku, zobrazí se nabídka doku pro aplikaci pro Mac:
Pojďme pro naši aplikaci vytvořit vlastní nabídku doku následujícím způsobem:
V Visual Studio pro Mac klikněte pravým tlačítkem na projekt aplikace a vyberte Přidat>nový soubor... V dialogovém okně nový soubor vyberte Xamarin.Mac>Empty Interface Definition, jako název použijte DockMenu a kliknutím na tlačítko Nový vytvořte nový soubor DockMenu.xib:
V oblasti řešení poklikejte na soubor DockMenu.xib a otevřete ho pro úpravy v Xcode. Vytvořte novou nabídku s následujícími položkami: Adresa, Datum, Pozdrav a Podpis
V dalším kroku propojíme nové položky nabídek s existujícími akcemi, které jsme vytvořili pro vlastní nabídku v části Přidávání, úpravy a odstraňování nabídek výše. Přepněte na Připojení ion Inspector a v hierarchii rozhraní vyberte první respondér. Posuňte se dolů a najděte
phraseAddress:
akci. Přetáhněte čáru z kruhu v této akci na položku nabídky Adresa :Opakujte postup pro všechny ostatní položky nabídky, které je připojují k odpovídajícím akcím:
Dále vyberte aplikaci v hierarchii rozhraní. V inspektoru Připojení přetáhněte čáru z kruhu na výstupu
dockMenu
do nabídky, kterou jsme právě vytvořili:Uložte změny a přepněte zpátky na Visual Studio pro Mac, aby se synchronizovaly s Xcode.
Poklikáním otevřete soubor Info.plist pro úpravy:
Klikněte na kartu Zdroj v dolní části obrazovky:
Klikněte na Přidat novou položku, klikněte na zelené tlačítko plus, nastavte název vlastnosti na AppleDockMenu a hodnotu na DockMenu (název našeho nového souboru .xib bez přípony):
Když teď spustíme naši aplikaci a klikneme pravým tlačítkem myši na její ikonu v Docku, zobrazí se nové položky nabídky:
Pokud vybereme jednu z vlastních položek z nabídky, text v našem textovém zobrazení se upraví.
Automaticky otevírané tlačítko a rozevírací seznamy
Automaticky otevírané tlačítko zobrazí vybranou položku a zobrazí seznam možností, ze které můžete vybrat po kliknutí uživatelem. Rozevírací seznam je typ automaticky otevíraného tlačítka, které se obvykle používá pro výběr příkazů specifických pro kontext aktuálního úkolu. Obě můžou být zobrazeny kdekoli v okně.
Pomocí následujícího příkazu vytvořte vlastní automaticky otevírané tlačítko pro naši aplikaci:
Upravte soubor Main.storyboard v Xcode a přetáhněte překryvné tlačítko z Inspektoru knihovny do okna panelu, které jsme vytvořili v části Kontextové nabídky:
Přidání nové položky nabídky a nastavení názvů položek v místní nabídce na: Adresa, Datum, Pozdrav a Podpis
V dalším kroku propojíme nové položky nabídky s existujícími akcemi, které jsme vytvořili pro vlastní nabídku v části Přidávání, úpravy a odstraňování nabídek výše. Přepněte na Připojení ion Inspector a v hierarchii rozhraní vyberte první respondér. Posuňte se dolů a najděte
phraseAddress:
akci. Přetáhněte čáru z kruhu v této akci na položku nabídky Adresa :Opakujte postup pro všechny ostatní položky nabídky, které je připojují k odpovídajícím akcím:
Uložte změny a přepněte zpátky na Visual Studio pro Mac, aby se synchronizovaly s Xcode.
Když teď spustíme naši aplikaci a vybereme položku z místní nabídky, text v našem textovém zobrazení se změní:
Můžete vytvářet a pracovat s rozevíracími seznamy úplně stejným způsobem jako automaticky otevíraná tlačítka. Místo připojení k existující akci byste mohli vytvořit vlastní akce stejně jako v místní nabídce v části Kontextové nabídky.
Shrnutí
Tento článek se podrobně podíval na práci s nabídkami a položkami nabídek v aplikaci Xamarin.Mac. Nejprve jsme prozkoumali řádek nabídek aplikace a pak jsme se podívali na vytváření kontextových nabídek, dále jsme prozkoumali nabídky stavového řádku a vlastní dokovací nabídky. Nakonec jsme probrali místní nabídky a rozevírací seznamy.