Меню в Xamarin.MacMenus in Xamarin.Mac

В этой статье рассматривается работа с меню в приложении Xamarin.Mac. Он описывает создание и поддержание меню и пунктов меню в Xcode и конструкторе Interface Builder и также программным способом работы с ними.This article covers working with menus in a Xamarin.Mac application. It describes creating and maintaining menus and menu items in Xcode and Interface Builder and working with them programmatically.

При работе с C# и .NET в приложении Xamarin.Mac, у вас есть доступ к тем же меню Cocoa, что разработчик, работающий в Objective-C и Xcode.When working with C# and .NET in a Xamarin.Mac application, you have access to the same Cocoa menus that a developer working in Objective-C and Xcode does. Поскольку Xamarin.Mac напрямую интегрируется с Xcode, можно использовать конструктора Interface Builder для создания и поддержки строки меню, меню и пунктов меню (или при необходимости создать их непосредственно в коде C#).Because Xamarin.Mac integrates directly with Xcode, you can use Xcode's Interface Builder to create and maintain your menu bars, menus, and menu items (or optionally create them directly in C# code).

Меню являются неотъемлемой частью приложения Mac взаимодействие с пользователем и обычно отображаются в различных частях пользовательского интерфейса:Menus are an integral part of a Mac application's user experience and commonly appear in various parts of the user interface:

  • Меню приложения -это главного меню, которое отображается в верхней части экрана для каждого приложения Mac.The application's menu bar - This is the main menu that appears at the top of the screen for every Mac application.
  • Контекстные меню -они отображаются, когда пользователь щелкает правой кнопкой мыши или элемент в окне управления щелчков.Contextual menus - These appear when the user right-clicks or control-clicks an item in a window.
  • В строке состояния -это область в крайней правой части панели меню приложения, который отображается в верхней части экрана (слева часов панели меню) и потом увеличилась до слева, так как элементы добавляются к нему.The status bar - This is the area at the far right side of the application menu bar that appears at the top of the screen (to the left of the menu bar clock) and grows to the left as items are added to it.
  • Закрепить меню -меню для каждого приложения на панели dock, появляется когда пользователь щелкает правой кнопкой мыши или элемент управления щелкает значок приложения, а также когда пользователь батарейки значок и удерживает кнопку мыши.Dock menu - The menu for each application in the dock that appears when the user right-clicks or control-clicks the application's icon, or when the user left-clicks the icon and holds the mouse button down.
  • Кнопки, всплывающее и раскрывающихся списков -всплывающее кнопка отображается выбранный элемент и выводит список параметров для использования при нажатии пользователем.Pop-up button and pull-down lists - A pop-up button displays a selected item and presents a list of options to select from when clicked by the user. Выпадающем списке — это разновидность всплывающее кнопки, обычно используется для выбора команды, относящиеся к контексту текущей задачи.A pull-down list is a type of pop-up button usually used for selecting commands specific to the context of the current task. Оба могут находиться в любом месте окна.Both can appear anywhere in a window.

В примере менюAn example menu

В этой статье мы обсудим, что узнаете основы работы с меню Cocoa, меню и пунктов меню в приложении Xamarin.Mac.In this article, we'll cover the basics of working with Cocoa menu bars, menus, and menu items in a Xamarin.Mac application. Настоятельно рекомендуется работать через Привет, Mac статьи, во-первых, в частности введение в Xcode и конструкторе Interface Builder и переменных экземпляров и действий разделы, так как он рассматриваются основные понятия и методы, которые мы будем использовать в этой статье.It is highly suggested that you work through the Hello, Mac article first, specifically the Introduction to Xcode and Interface Builder and Outlets and Actions sections, as it covers key concepts and techniques that we'll be using in this article.

Может потребоваться взгляните на предоставление C# классы / методы Objective-c раздел структуре Xamarin.Mac документа, он объясняет Register и Export атрибуты используется для передачи классов C# в службе Objective-C объекты и элементы пользовательского интерфейса.You may want to take a look at the Exposing C# classes / methods to Objective-C section of the Xamarin.Mac Internals document as well, it explains the Register and Export attributes used to wire-up your C# classes to Objective-C objects and UI elements.

Строка меню приложенияThe application's menu bar

В отличие от приложений, работающих в операционной системе Windows, где каждое окно может иметь свои собственные строки меню, подключенные к ней каждое приложение, работающее в macOS имеется один меню вдоль верхней части экрана, который используется для каждого окна в этом приложении:Unlike applications running on the Windows OS where every window can have its own menu bar attached to it, every application running on macOS has a single menu bar that runs along the top of the screen that's used for every window in that application:

Строка менюA menu bar

Элементы на этой панели меню активируются или деактивируются исходя из текущего контекста или состояние приложения и его пользовательский интерфейс в каждый конкретный момент.Items on this menu bar are activated or deactivated based on the current context or state of the application and its user interface at any given moment. Например: Если пользователь выбирает текстового поля, элементы на изменить меню будут поступать включена, такие как копирования и Вырезать.For example: if the user selects a text field, items on the Edit menu will be come enabled such as Copy and Cut.

В соответствии с Apple и по умолчанию все приложения macOS имеют стандартный набор меню и пунктов меню, которые отображаются в строке меню приложения:According to Apple and by default, all macOS applications have a standard set of menus and menu items that appear in the application's menu bar:

  • Меню Apple -это меню предоставляет доступ к системе расширенные элементы, доступные для пользователя все время, независимо от того, какие приложения.Apple menu - This menu provides access to system wide items that are available to the user at all times, regardless of what application is running. Эти элементы невозможно изменить разработчиком.These items cannot be modified by the developer.
  • Меню приложения -это меню отображает имя приложения полужирным шрифтом и помогает пользователю определить, какое приложение выполняется в данный момент.App menu - This menu displays the application's name in bold and helps the user identify what application is currently running. Он содержит элементы, которые применяются к приложению как единое целое и не данному документу или процесс, например выхода из приложения.It contains items that apply to the application as a whole and not a given document or process such as quitting the application.
  • Меню "файл" — использовать элементы для создания, открыть или сохранить документы, приложение работает с.File menu - Items used to create, open, or save documents that your application works with. Если приложения не основанные на документе, это меню может быть переименован или удален.If your application is not document-based, this menu can be renamed or removed.
  • Меню "Правка" -содержит команды, такие как Вырезать, копирования, и вставить которого используются для редактирования или изменения элементов в пользовательском интерфейсе приложения.Edit menu - Holds commands such as Cut, Copy, and Paste which are used to edit or modify elements in the application's user interface.
  • Меню «Формат» — Если приложение работает с текстом, это меню содержит команды, чтобы изменить форматирование текста.Format menu - If the application works with text, this menu holds commands to adjust the formatting of that text.
  • Меню "Вид" -содержит команды, влияющие на способ отображения содержимого (Просмотр) в пользовательском интерфейсе приложения.View menu - Holds commands that affect how content is displayed (viewed) in the application's user interface.
  • Меню приложения -это любой меню, которые предназначены специально для вашего приложения (например, меню закладок для веб-браузера).Application-specific menus - These are any menus that are specific to your application (such as a bookmarks menu for a web browser). Они должны отображаться между представление и окно меню в строке.They should appear between the View and Window menus on the bar.
  • Меню "окно" -команды для работы с окнами в приложении, а также список текущего открытых окон.Window menu - Contains commands for working with windows in your application, as well as a list of current open windows.
  • Меню "Справка" -приложения, предоставляющего справки на экране, меню "Справка" должен быть меню справа на панели.Help menu - If your application provides onscreen help, the Help menu should be the right-most menu on the bar.

Дополнительные сведения о строке меню приложения и стандартные меню и пункты меню, см. в разделе Apple рекомендациям по интерфейсам.For more information about the application menu bar and standard menus and menu items, please see Apple's Human Interface Guidelines.

Строка меню приложения по умолчаниюThe default application menu bar

Каждый раз при создании нового проекта Xamarin.Mac, вы автоматически получаете и стандартный, строка меню приложения по умолчанию, которая имеет типичных элементов, которые приложение macOS обычно имеет (как уже говорилось в предыдущем разделе).Whenever you create a new Xamarin.Mac project, you automatically get a standard, default application menu bar that has the typical items that a macOS application would normally have (as discussed in the section above). Строка меню приложения по умолчанию определяется в Main.storyboard файл (вместе с остальной части пользовательского интерфейса приложения) в проекте в панели решения:Your application's default menu bar is defined in the Main.storyboard file (along with the rest of your app's UI) under the project in the Solution Pad:

Выберите основной раскадровкиSelect the main storyboard

Дважды щелкните Main.storyboard файл, чтобы открыть его для редактирования в Interface Builder в Xcode и вам представится интерфейса редактора меню:Double-click the Main.storyboard file to open it for editing in Xcode's Interface Builder and you'll be presented with the menu editor interface:

Изменение пользовательского интерфейса в XcodeEditing the UI in Xcode

Здесь можно щелкнуть элементы например откройте пункта меню в файл меню редактировать и изменять его свойства в инспектор атрибутов:From here we can click on items such as the Open menu item in the File menu and edit or adjust its properties in the Attributes Inspector:

Изменив атрибуты менюEditing a menu's attributes

Мы рассмотрим добавление, изменение и удаление меню и элементов, далее в этой статье.We'll get into adding, editing, and deleting menus and items later in this article. Для теперь мы просто хотите узнать, какие меню и пункты меню будут доступны по умолчанию и как они автоматически доступны в код с помощью набора стандартных переменных экземпляров и действий (Дополнительные сведения см. наш переменных экземпляров и действий Документация по).For now we just want to see what menus and menu items are available by default and how they have been automatically exposed to code via a set of predefined outlets and actions (for more information see our Outlets and Actions documentation).

Например, если мы щелкаем инспектор подключения для откройте пункта меню, мы видим, до автоматического связывания openDocument: действия:For example, if we click on the Connection Inspector for the Open menu item we can see it is automatically wired up to the openDocument: action:

Просмотр вложенное действиеViewing the attached action

При выборе первый респондент в иерархия интерфейса и прокрутите вниз содержимое инспектор подключения, и вы увидите определение openDocument: действие, откройте пункта меню подключен к (а также несколько другие действия по умолчанию для приложения и автоматически не отправлены элементы управления):If you select the First Responder in the Interface Hierarchy and scroll down in the Connection Inspector, and you will see the definition of the openDocument: action that the Open menu item is attached to (along with several other default actions for the application that are and are not automatically wired up to controls):

Просмотр всех присоединенных действияViewing all attached actions

Почему это важно?Why is this important? В следующем разделе будут видеть, как работают эти действия автоматически определяется с другими Cocoa элементам управления и автоматически включить и отключить пунктов меню, а также, предоставляя встроенные функциональные возможности для элементов.In the next section will see how these automatically-defined actions work with other Cocoa user interface elements to automatically enable and disable menu items, as well as, provide built-in functionality for the items.

Позже мы будем использовать эти встроенные действия для включения и отключения элементов из кода и предоставить собственные функции при их выборе.Later we'll be using these built-in actions to enable and disable items from code and provide our own functionality when they are selected.

Функциональные возможности встроенного менюBuilt-in menu functionality

Если созданное приложение Xamarin.Mac перед добавлением элементов пользовательского интерфейса и кода запуска, видно, что некоторые элементы автоматически привязав и являются для вас (с полностью автоматически встроенные функции), такие как Quit элемент приложения меню:If you were the run a newly created Xamarin.Mac application before adding any UI items or code, you'll notice that some items are automatically wired-up and enabled for you (with fully functionality automatically built-in), such as the Quit item in the App menu:

Элемент меню включенаAn enabled menu item

Хотя другие пункты меню, например Вырезать, копирования, и вставить не являются:While other menu items, such as Cut, Copy, and Paste are not:

Отключенных элементов менюDisabled menu items

Давайте остановите приложение и дважды щелкните Main.storyboard файл панели решения чтобы открыть его для редактирования в Xcode конструктора Interface Builder.Let's stop the application and double-click the Main.storyboard file in the Solution Pad to open it for editing in Xcode's Interface Builder. Затем перетащите представления текста из библиотеки на контроллер представления окна в редактор интерфейса:Next, drag a Text View from the Library onto the window's view controller in the Interface Editor:

Выбор представления текста из библиотекиSelecting a Text View from the Library

В Редактор ограничений давайте закрепить представления текста для границы окна и задайте для него где растет и сжимается с окном, щелкнув все четыре red I-образных указателей в верхней части редактора и добавить 4 ограничения кнопки:In the Constraint Editor let's pin the text view to the window's edges and set it where it grows and shrinks with the window by clicking all four red I-beams at the top of the editor and clicking the Add 4 Constraints button:

Изменение ограниченийEditing the contraints

Сохраните изменения пользовательского интерфейса и вернуться назад в Visual Studio для Mac для синхронизации изменений с проектом Xamarin.Mac.Save your changes to the user interface design and switch back the Visual Studio for Mac to synchronize the changes with your Xamarin.Mac project. Теперь запустите приложение, введите текст в представление текста, выберите его и откройте изменить меню:Now start the application, type some text into the text view, select it, and open the Edit menu:

Элементы меню автоматически включается или отключаетсяThe menu items are automatically enabled/disabled

Обратите внимание, что как Вырезать, копирования, и вставить элементы автоматически включенной и полностью работоспособной, не написав ни строчки кода.Notice how the Cut, Copy, and Paste items are automatically enabled and fully functional, all without writing a single line of code.

Что здесь происходит?What's going on here? Помните, встроенной заранее определить действия, которые перейдут в проводных до пунктов меню по умолчанию (поскольку представленные выше), большая часть элементов интерфейса пользователя Cocoa, которые являются частью macOS имеют встроенные обработчики на выполнение определенных действий (таких как copy:).Remember the built-in predefine actions that come wired up to the default menu items (as presented above), most of the Cocoa user interface elements that are part of macOS have built in hooks to specific actions (such as copy:). Поэтому при их добавлении в окно активным и выборе соответствующего пункта меню или элементы, присоединенные к действия включаются автоматически.So when they are added to a window, active, and selected, the corresponding menu item or items attached to that action are automatically enabled. Если пользователь выбирает этот элемент меню, функций, встроенных в элемент пользовательского интерфейса вызывается и выполняется, не привлекая разработчиков.If the user selects that menu item, the functionality built into the UI element is called and executed, all without developer intervention.

Включение и отключение меню и элементовEnabling and disabling menus and items

По умолчанию каждый раз при возникновении события пользователя NSMenu автоматически включает и отключает каждого отображается меню и меню элементов на основе контекста приложения.By default, every time a user event occurs, NSMenu automatically enables and disables each visible menu and menu item based on the context of the application. Чтобы включить или отключить элемент тремя способами:There are three ways to enable/disable an item:

  • Включение автоматического меню -пункт меню доступен в том случае, если NSMenu можно найти соответствующий объект, который отвечает на действие, которое элемент является привязав для.Automatic menu enabling - A menu item is enabled if NSMenu can find an appropriate object that responds to the action that the item is wired-up to. Например, представление текста выше оказывали встроенный обработчик, чтобы copy: действие.For example, the text view above that had a built-in hook to the copy: action.
  • Настраиваемые действия и validateMenuItem: — для любого элемента меню, привязанный к окно или представление настраиваемого действия контроллера, вы можете добавить validateMenuItem: действие и вручную включить или отключить пунктов меню.Custom actions and validateMenuItem: - For any menu item that is bound to a window or view controller custom action, you can add the validateMenuItem: action and manually enable or disable menu items.
  • Включение меню вручную -пользователь вручную задаст Enabled свойства каждого NSMenuItem для включения или отключения каждого элемента в меню отдельно.Manual menu enabling - You manually set the Enabled property of each NSMenuItem to enable or disable each item in a menu individually.

Чтобы выбрать систему, установите AutoEnablesItems свойство NSMenu.To choose a system, set the AutoEnablesItems property of a NSMenu. true выполняется автоматически (по умолчанию) и false выполняется вручную.true is automatic (the default behavior) and false is manual.

Важно!

Если вы решили использовать вручную меню включения, ни один из меню элементы, даже те, которые контролируются AppKit классов, таких как NSTextView, обновляются автоматически.If you choose to use manual menu enabling, none of the menu items, even those controlled by AppKit classes like NSTextView, are updated automatically. Вы будет нести ответственность за включение и отключение всех элементов вручную в коде.You will be responsible for enabling and disabling all items by hand in code.

С помощью validateMenuItemUsing validateMenuItem

Как уже говорилось, для любого элемента меню, привязанный к окна или пользовательское действие контроллера представления, вы можете добавить validateMenuItem: действие и вручную включить или отключить пунктов меню.As stated above, for any menu item that is bound to a Window or View Controller Custom Action, you can add the validateMenuItem: action and manually enable or disable menu items.

В следующем примере Tag решить, тип элемента меню, который будет включить или отключить, будет использоваться свойство validateMenuItem: действия на основе состояния выбранного текста в NSTextView.In the following example, the Tag property will be used to decide the type of menu item that will be enabled/disabled by the validateMenuItem: action based on the state of selected text in a NSTextView. Tag Свойства в конструкторе Interface Builder для каждого пункта меню:The Tag property has been set in Interface Builder for each menu item:

Задание свойства тегаSetting the Tag property

И следующий код, добавляемый контроллер представления:And the following code added to the View Controller:

[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;
}

При выполнении этого кода, и текст не выбран в NSTextView, пункты меню два переноса по словам отключены (даже если они привязаны к действиям в контроллере представления):When this code is run, and no text is selected in the NSTextView, the two wrap menu items are disabled (even though they are wired to actions on the view controller):

Отключить отображение элементовShowing disabled items

Если выбран раздел текста и повторном открытии меню, два wrap пункты меню будут доступны:If a section of text is selected and the menu reopened, the two wrap menu items will be available:

Включить отображение элементовShowing enabled items

Включение и отвечать на запросы к пунктам меню в кодеEnabling and responding to menu items in code

Как мы уже видели выше, просто добавив определенные элементы пользовательского интерфейса Cocoa для наших Дизайн пользовательского интерфейса (например, текстовое поле), несколько пунктов меню по умолчанию будут включены и функционируют автоматически без необходимости написания кода.As we have seen above, just by adding specific Cocoa user interface elements to our UI design (such as a text field), several of the default menu items will be enabled and function automatically, without having to write any code. Далее давайте рассмотрим добавление нашим собственным кодом C# для нашего проекта Xamarin.Mac для включения пункта меню и предоставляют функциональные возможности, когда пользователь выбирает его.Next let's look at adding our own C# code to our Xamarin.Mac project to enable a menu item and provide functionality when the user selects it.

Например, допустим мы хотим, чтобы пользователь мог использовать откройте элемент файл меню, чтобы найти нужную папку.For example, let say we want the user to be able to use the Open item in the File menu to select a folder. Так как мы это должно быть функцией уровня приложения, не ограниченной предоставляют окна или элемента пользовательского интерфейса, мы собираемся добавить код для обработки таких делегату наши приложения.Since we want this to be an application-wide function and not limited to a give window or UI element, we're going to add the code to handle this to our application delegate.

В панели решения, дважды щелкните AppDelegate.CS файл, чтобы открыть его для редактирования:In the Solution Pad, double-click the AppDelegate.CS file to open it for editing:

Выбрав делегата приложенияSelecting the app delegate

Добавьте следующий код ниже DidFinishLaunching метод:Add the following code below the DidFinishLaunching method:

[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 ();
    }
}

Давайте запустите приложение и откройте файл меню:Let's run the application now and open the File menu:

Меню "файл"The File menu

Обратите внимание, что откройте пункт меню включен.Notice that the Open menu item is now enabled. Если выбрать его, откройте диалоговое окно будет отображаться:If we select it, the open dialog will be displayed:

Окно открытияAn open dialog

При нажатии кнопки откройте кнопку, отображается наших предупреждающее сообщение:If we click the Open button, our alert message will be displayed:

Пример диалогового окна сообщенияAn example dialog message

Строки ключа был [Export ("openDocument:")], он сообщает NSMenu , наши AppDelegate имеет метод void OpenDialog (NSObject sender) , реагирующий на openDocument: действие.The key line here was [Export ("openDocument:")], it tells NSMenu that our AppDelegate has a method void OpenDialog (NSObject sender) that responds to the openDocument: action. Если вы не забудете выше, откройте пункт меню является автоматически привязав к этому действию по умолчанию в конструкторе Interface Builder:If you'll remember from above, the Open menu item is automatically wired-up to this action by default in Interface Builder:

Просмотр вложенных действийViewing the attached actions

Далее давайте взглянем на создание собственных меню, пункты меню и действия, а также отвечать на запросы к ним в коде.Next let's look at creating our own menu, menu items, and actions and responding to them in code.

Работа с меню открытия последниеWorking with the open recent menu

По умолчанию файл меню содержит открыть последние элемент, который следит за последние несколько файлов, которые пользователь открыл с вашим приложением.By default, the File menu contains an Open Recent item that keeps track of the last several files that the user has opened with your app. Если вы создаете NSDocument на основе приложения Xamarin.Mac, это меню будет обрабатываться для вас автоматически.If you are creating a NSDocument based Xamarin.Mac app, this menu will be handled for you automatically. Для любого другого типа приложения Xamarin.Mac будет отвечать за управление и вручную отвечать на этот пункт меню.For any other type of Xamarin.Mac app, you will be responsible for managing and responding to this menu item manually.

Чтобы вручную обрабатывать открыть последние меню, сначала необходимо будет уведомлять его об, что новый файл было открыто или сохранить, используя следующие:To manually handle the Open Recent menu, you will first need to inform it that a new file has been opened or saved using the following:

// Add document to the Open Recent menu
NSDocumentController.SharedDocumentController.NoteNewRecentDocumentURL(url);

Несмотря на то, что приложение не использует NSDocuments, по-прежнему использовать NSDocumentController для поддержания открыть последние меню, отправляя NSUrl с расположением файла NoteNewRecentDocumentURL метод SharedDocumentController.Even though your app is not using NSDocuments, you still use the NSDocumentController to maintain the Open Recent menu by sending a NSUrl with the location of the file to the NoteNewRecentDocumentURL method of the SharedDocumentController.

Далее необходимо переопределить OpenFile метод делегата приложения, чтобы открыть любой файл, который пользователь выбирает из последние документы меню.Next, you need to override the OpenFile method of the app delegate to open any file that the user selects from the Open Recent menu. Пример:For example:

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;
    }
}

Вернуть true Если файл может быть открыт, в противном случае возвращает false и встроенные предупреждение будет отображаться для пользователя, что файл не удалось открыть.Return true if the file can be opened, else return false and a built-in warning will be displayed to the user that the file could not be opened.

Так как имя файла и путь возвращается из открыть последние меню может содержать пробелы, нам нужно правильным образом экранировать этот символ перед созданием NSUrl или мы будет показано сообщение об ошибке.Because the filename and path returned from the Open Recent menu, might include a space, we need to properly escape this character before creating a NSUrl or we will get an error. Мы делаем, следующим кодом:We do that with the following code:

filename = filename.Replace (" ", "%20");

Наконец, мы создаем NSUrl , указывает на файл и используйте вспомогательный метод в приложении делегировать откройте новое окно и загрузить файл в его:Finally, we create a NSUrl that points to the file and use a helper method in the app delegate to open a new window and load the file into it:

var url = new NSUrl ("file://"+filename);
return OpenFile(url);

Чтобы получить все вместе, давайте рассмотрим пример реализации в AppDelegate.cs файла:To pull everything together, let's take a look at an example implementation in an AppDelegate.cs file:

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
    }
}

Зависимости от требований вашего приложения, может потребоваться пользователю открыть тот же файл в несколько окон, в то же время.Based on the requirements of your app, you might not want the user to open the same file in more than one window at the same time. В нашем приложении-примере если пользователь выбирает файл, который уже открыт (из последние документы или откройте …In our example app, if the user chooses a file that is already open (either from the Open Recent or Open.. элементы меню), окно, содержащее файл переводится на передний план.menu items), the window that contains the file is brought to the front.

Для этого мы использовали в наших вспомогательный метод следующий код:To accomplish this, we used the following code in our helper method:

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;
    }
}

Мы разработали наших ViewController класса, содержащего путь к файлу в его Path свойство.We designed our ViewController class to hold the path to the file in its Path property. Далее мы обходим все открытые окна в приложении.Next, we loop through all currently open windows in the app. Если файл уже открыт в одно из окон, она переводится в начале всех окон, с помощью:If the file is already open in one of the windows, it is brought to the front of all other windows using:

NSApplication.SharedApplication.Windows[n].MakeKeyAndOrderFront(this);

Если совпадений не найдено, открывается новое окно с загруженный файл указан в открыть последние меню:If no match is found, a new window is opened with the file loaded and the file is noted in the Open Recent menu:

// 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);

Работа с действиями пользовательского окнаWorking with custom window actions

Так же, как встроенный первый респондент действия, которые приходят предварительно проводных в стандартных элементов меню, можно создать настраиваемые действия и привязать их к пунктам меню в конструктор Interface Builder.Just like the built-in First Responder actions that come pre-wired to standard menu items, you can create new, custom actions and wire them to menu items in Interface Builder.

Во-первых определение пользовательского действия, на одном из контроллеров окна приложения.First, define a custom action on one of your app's window controllers. Пример:For example:

[Action("defineKeyword:")]
public void defineKeyword (NSObject sender) {
    // Preform some action when the menu is selected
    Console.WriteLine ("Request to define keyword");
}

Далее дважды щелкните файл раскадровки приложения в панели решения чтобы открыть его для редактирования в Xcode конструктора Interface Builder.Next, double-click the app's storyboard file in the Solution Pad to open it for editing in Xcode's Interface Builder. Выберите первый респондент под сцены приложения, перейдите в инспектор атрибутов:Select the First Responder under the Application Scene, then switch to the Attributes Inspector:

Инспектор атрибутовThe Attributes Inspector

Нажмите кнопку + кнопки в нижней части инспектор атрибутов для добавления нового настраиваемого действия:Click the + button at the bottom of the Attributes Inspector to add a new custom action:

Добавив новое действиеAdding a new action

Присвойте ему имя, совпадающее с именем настраиваемое действие, которое вы создали на контроллере окна:Give it the same name as the custom action that you created on your window controller:

Изменение имени действияEditing the action name

Щелкните и перетащите из пункта меню, чтобы первый респондент под сцены приложения.Control-click and drag from a menu item to the First Responder under the Application Scene. В раскрывающемся списке выберите только что созданный объект action (defineKeyword: в этом примере):From the popup list, select the new action you just created (defineKeyword: in this example):

Присоединение действиеAttaching an action

Сохранить изменения в раскадровку и вернитесь в Visual Studio для Mac синхронизировать изменения.Save the changes to the storyboard and return to Visual Studio for Mac to sync the changes. Если вы запустите приложение, пункт меню, который вы подключили настраиваемого действия будет автоматически включить или отключить (с учетом окна с помощью действия, как окно было открыто) и выбора элемента меню запустит действие:If you run the app, the menu item that you connected the custom action to will automatically be enabled/disabled (based on the window with the action being open) and selecting the menu item will fire off the action:

Тестирование нового действияTesting the new action

Добавление, редактирование и удаление менюAdding, editing, and deleting menus

Как мы уже видели в предыдущих разделах, в состав указанное количество стандартных меню и команды меню, которые автоматически активировать и отвечать на определенные элементы управления пользовательского интерфейса приложения Xamarin.Mac.As we have seen in the previous sections, a Xamarin.Mac application comes with a preset number of default menus and menu items that specific UI controls will automatically activate and respond to. Также мы видели, как добавить код в наше приложение, которое позволит также отвечать на эти элементы по умолчанию.We have also seen how to add code to our application that will also enable and respond to these default items.

В этом разделе мы рассмотрим удаление элементов меню, которые нам не нужен, реорганизация меню и добавление новых меню, пункты меню и действия.In this section we will look at removing menu items that we don't need, reorganizing menus and adding new menus, menu items and actions.

Дважды щелкните Main.storyboard файл панели решения чтобы открыть его для редактирования:Double-click the Main.storyboard file in the Solution Pad to open it for editing:

Изменение пользовательского интерфейса в XcodeEditing the UI in Xcode

Для конкретного приложения Xamarin.Mac не будет использоваться значение по умолчанию представление меню, поэтому мы собираемся удалить его.For our specific Xamarin.Mac application we are not going to be using the default View menu so we are going to remove it. В иерархия интерфейса выберите представление пункт меню, который входит в строку главного меню:In the Interface Hierarchy select the View menu item that is a part of the main menu bar:

Выбрав элемент меню представленияSelecting the View menu item

Нажмите клавишу delete или клавиши backspace, чтобы удалить меню.Press delete or backspace to delete the menu. Далее мы не собираемся использовать все элементы в формат меню и нужно переместить элементы, мы собираемся использовать из вложенного меню.Next, we aren't going to be using all of the items in the Format menu and we want to move the items we are going to use out from under the sub menus. В иерархия интерфейса выберите следующие пункты меню:In the Interface Hierarchy select the following menu items:

Выделение нескольких элементовHighlighting multiple items

Перетащите элементы в папке родительского меню во вложенном меню, где они в настоящее время:Drag the items under the parent Menu from the sub-menu where they currently are:

Перетаскивания элементов меню в меню родительскогоDragging menu items to the parent menu

Меню теперь должен выглядеть так:Your menu should now look like:

Элементы в новом расположенииThe items in the new location

Далее давайте перетащим текст подменю out из формат меню и поместите его в строку главного меню между формат и окно меню:Next let's drag the Text sub-menu out from under the Format menu and place it on the main menu bar between the Format and Window menus:

Меню текстовогоThe Text menu

Вернемся назад в разделе формат меню и delete шрифта элемент подменю.Let's go back under the Format menu and delete the Font sub-menu item. Затем выберите формат меню и переименуйте его «Шрифт»:Next, select the Format menu and rename it "Font":

В меню шрифтаThe Font menu

Теперь давайте создадим пользовательское меню стандартное фраз, которые автоматически получить добавляется к тексту в представлении текста при их выборе.Next, let's create a custom menu of predefine phrases that will automatically get appended to the text in the text view when they are selected. В поле поиска в нижней части инспектор библиотеки типа в «menu».In the search box at the bottom on the Library Inspector type in "menu." Это упростит поиск и работать со всеми элементами пользовательского интерфейса меню:This will make it easier to find and work with all of the menu UI elements:

В инспекторе библиотекиThe Library Inspector

Теперь давайте выполните следующую команду, чтобы создать наш меню:Now let's do the following to create our menu:

  1. Перетащите пункта меню из инспектор библиотеки на панель меню между текст и окно меню:Drag a Menu Item from the Library Inspector onto the menu bar between the Text and Window menus:

    Выбрав элемент меню в библиотекеSelecting a new menu item in the Library

  2. Переименуйте элемент «Фразы»:Rename the item "Phrases":

    Задание имени менюSetting the menu name

  3. Затем перетащите меню из инспектор библиотеки:Next drag a Menu from the Library Inspector:

    Меню из библиотекиSelecting a menu from the Library

  4. Затем удалите меню на новом пункта меню мы только что создали и измените ее имя на «Фразы»:Drop then Menu on the new Menu Item we just created and change its name to "Phrases":

    Изменение имени менюEditing the menu name

  5. Теперь переименуем трех стандартных пунктов меню «Address», «Дата» и «Greeting»:Now let's rename the three default Menu Items "Address", "Date," and "Greeting":

    В меню фразThe Phrases menu

  6. Давайте добавим четвертый пункта меню , перетащив пункта меню из инспектор библиотеки и вызов его «Подпись»:Let's add a fourth Menu Item by dragging a Menu Item from the Library Inspector and calling it "Signature":

    Изменение имени элемента менюEditing the menu item name

  7. Сохраните изменения в строке меню.Save the changes to the menu bar.

Теперь давайте создадим набор пользовательских действий, чтобы наши новые элементы меню предоставляются коду C#.Now let's create a set of custom actions so that our new menu items are exposed to C# code. В Xcode перейдем к Assistant представления:In Xcode let's switch to the Assistant view:

Создание необходимых действияхCreating the required actions

Давайте, сделайте следующее:Let's do the following:

  1. Control, перетащите адрес пункт меню, чтобы AppDelegate.h файла.Control-drag from the Address menu item to the AppDelegate.h file.

  2. Коммутатор подключения тип действие:Switch the Connection type to Action:

    Выбор типа действияSelecting the action type

  3. Введите имя «phraseAddress» и нажмите клавишу Connect кнопку, чтобы создать новое действие:Enter a Name of "phraseAddress" and press the Connect button to create the new action:

    Настройка действияConfiguring the action

  4. Повторите приведенные выше действия для даты, приветствия, и подпись пункты меню:Repeat the above steps for the Date, Greeting, and Signature menu items:

    Выполненные действияThe completed actions

  5. Сохраните изменения в строке меню.Save the changes to the menu bar.

Далее нам нужно создать выхода нашего представления текста, что мы уточнить его содержимое из кода.Next we need to create an outlet for our text view so that we can adjust its content from code. Выберите ViewController.h файл вспомогательном редакторе и создания новой переменной экземпляра вызывается documentText:Select the ViewController.h file in the Assistant Editor and create a new outlet called documentText:

Создание переменной экземпляраCreating an outlet

Вернитесь к Visual Studio для Mac для синхронизации изменений из Xcode.Return to Visual Studio for Mac to sync the changes from Xcode. Далее изменить ViewController.cs файл и это должно выглядеть следующим образом:Next edit the ViewController.cs file and make it look like the following:

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
    }
}

Этот класс представляет текст нашего представления текста за пределами ViewController класса, но и уведомляет делегата приложения, когда окно Получает или теряет фокус.This exposes the text of our text view outside of the ViewController class and informs the app delegate when the window gains or loses focus. Теперь редактировать AppDelegate.cs файл и это должно выглядеть следующим образом:Now edit the AppDelegate.cs file and make it look like the following:

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
    }
}

Здесь мы приняли AppDelegate разделяемый класс, чтобы мы могли использовать действия и источники, которые мы определили в конструктор Interface Builder.Here we've made the AppDelegate a partial class so that we can use the actions and outlets that we defined in Interface Builder. Мы также предоставляем textEditor для отслеживания того, какое окно находится в фокусе.We also expose a textEditor to track which window is currently in focus.

Следующие методы используются для обработки наших пользовательских меню и пункты меню:The following methods are used to handle our custom menu and menu items:

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";
}

Теперь при выполнении приложения, все элементы в фразу меню будет активна и добавит в представление текста, при выборе фразу предоставляют:Now if we run our application, all of the items in the Phrase menu will be active and will add the give phrase to the text view when selected:

Пример приложения, выполняемогоAn example of the app running

Теперь, когда у нас есть основы работы с меню приложения, работу, давайте взглянем на создание настраиваемых контекстных меню.Now that we have the basics of working with the application menu bar down, let's look at creating a custom contextual menu.

Создание меню из кодаCreating menus from code

Помимо создания меню и пунктов меню с помощью конструктора Interface Builder, возможны ситуации, когда приложения Xamarin.Mac нужно создать, изменить или удалить меню, подменю или пункта меню из кода.In addition to creating menus and menu items with Xcode's Interface Builder, there might be times when a Xamarin.Mac app needs to create, modify, or remove a menu, sub-menu, or menu item from code.

В следующем примере класс создается для хранения сведений о элементы меню и подменю, которые будут динамически создаваться в режиме реального времени:In the following example, a class is created to hold the information about the menu items and sub-menus that will be dynamically created on-the-fly:

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
    }
}

Добавление меню и элементовAdding menus and items

С этим классом, который определен, следующая процедура будет анализировать коллекцию LanguageFormatCommandобъектов и рекурсивно сборки путем их добавления к нижней части существующего меню (созданные в построителе интерфейса), который был передан в новых меню и пункты меню:With this class defined, the following routine will parse a collection of LanguageFormatCommandobjects and recursively build new menus and menu items by appending them to the bottom of the existing menu (created in Interface Builder) that has been passed in:

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);
    }
}

Для любого LanguageFormatCommand объект, имеющий пустое Title свойство, эта процедура создает пункт меню разделителя (тонкой серой линии) между разделами меню:For any LanguageFormatCommand object that has a blank Title property, this routine creates a Separator menu item (a thin gray line) between menu sections:

menuItem = NSMenuItem.SeparatorItem;

Если заголовок не указан, создается новый элемент меню с этим заголовком:If a title is provided, a new menu item with that title is created:

menuItem = new NSMenuItem (command.Title);

Если LanguageFormatCommand содержит дочерний объект LanguageFormatCommand объекты, созданные подменю и AssembleMenu метод будет вызываться рекурсивно для построения этого меню:If the LanguageFormatCommand object contains child LanguageFormatCommand objects, a sub-menu is created and the AssembleMenu method is recursively called to build out that menu:

menuItem.Submenu = new NSMenu (command.Title);
AssembleMenu (menuItem.Submenu, command.SubCommands);

Для любой новый пункт меню, который не имеет дочерних меню будет добавлен код для обработки выбранного пользователем элемента меню:For any new menu item that does not have sub-menus, code is added to handle the menu item being selected by the user:

menuItem.Activated += (sender, e) => {
    // Do something when the menu item is selected
    ...
};

Тестирование Создание менюTesting the menu creation

Со всеми приведенный выше код в месте Если следующую подборку LanguageFormatCommand объекты были созданы:With all of the above code in place, if the following collection of LanguageFormatCommand objects were created:

// 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)"));

И передачу коллекции AssembleMenu функции (с формат меню в качестве базового), будут создаваться следующие динамические меню и пункты меню:And that collection passed to the AssembleMenu function (with the Format Menu set as the base), the following dynamic menus and menu items would be created:

Новые элементы меню в запущенном приложенииThe new menu items in the running app

Удаление меню и элементовRemoving menus and items

Если вам нужно удалить из пользовательского интерфейса приложения пункт меню или пункта меню, можно использовать RemoveItemAt метод NSMenu класс ей, начинающийся с нуля основаны на использовании индекс удаляемого элемента.If you need to remove any menu or menu item from the app's user interface, you can use the RemoveItemAt method of the NSMenu class simply by giving it the zero based index of the item to remove.

Например чтобы удалить меню и элементы меню, созданные процедурой выше, можно использовать следующий код:For example, to remove the menus and menu items created by the routine above, you could use the following code:

public void UnpopulateFormattingMenu(NSMenu menu) {

    // Remove any additional items
    for (int n = (int)menu.Count - 1; n > 4; --n) {
        menu.RemoveItemAt (n);
    }
}

В случае приведенный выше код первые четыре меню элементы создаются в построителе интерфейса Xcode и размещения, доступные в приложении, поэтому они не будут удалены динамически.In the case of the code above, the first four menu items are created in Xcode's Interface Builder and aways available in the app, so they are not removed dynamically.

Контекстные менюContextual menus

Контекстные меню появляются, когда пользователь щелкает правой кнопкой мыши или элемент в окне управления щелчков.Contextual menus appear when the user right-clicks or control-clicks an item in a window. По умолчанию некоторые элементы пользовательского интерфейса, встроенные в macOS, уже имеют контекстных меню, присоединенными к ним (например, представление «текст»).By default, several of the UI elements built into macOS already have contextual menus attached to them (such as the text view). Однако возможны ситуации, когда мы хотим создать собственные настраиваемые контекстных меню для элемента пользовательского интерфейса, который мы добавили в окно.However, there might be times when we want to create our own custom contextual menus for a UI element that we have added to a window.

Изменим наш Main.storyboard в Xcode и добавьте окно окно в нашей структуре его класс для «NSPanel» в инспектор удостоверений, добавьте новый Assistant элемент окно меню и присоединить ее к нового окна с помощью Показать Segue:Let's edit our Main.storyboard file in Xcode and add a Window window to our design, set its Class to "NSPanel" in the Identity Inspector, add a new Assistant item to the Window menu, and attach it to the new window using a Show Segue:

Выбор типа переходаSetting the segue type

Давайте, сделайте следующее:Let's do the following:

  1. Перетащите метка из инспектор библиотеки на панели окна и задает его текст «Property»:Drag a Label from the Library Inspector onto the Panel window and set its text to "Property":

    Редактирование метки значениеEditing the label's value

  2. Затем перетащите меню из инспектор библиотеки на контроллера представления в иерархию представлений и элементы меню по умолчанию переименования три документа, текста и шрифта:Next drag a Menu from the Library Inspector onto the View Controller in the View Hierarchy and rename the three default menu items Document, Text and Font:

    Пункты меню требуетсяThe required menu items

  3. Теперь элемент управления, перетащите из метка свойства на меню:Now control-drag from the Property Label onto the Menu:

    Перетаскивание для создания объекта переходаDragging to create a segue

  4. В появившемся диалоговом окне выберите меню:From the popup dialog, select Menu:

    Выбор типа переходаSetting the segue type

  5. Из инспектор удостоверений, класс контроллера представления для «PanelViewController» set:From the Identity Inspector, set the View Controller's class to "PanelViewController":

    Класс segue параметровSetting the segue class

  6. Вернитесь в Visual Studio для Mac для синхронизации, а затем вернуться в конструктор Interface Builder.Switch back to Visual Studio for Mac to sync, then return to Interface Builder.

  7. Переключиться в режим вспомогательном редакторе и выберите PanelViewController.h файла.Switch to the Assistant Editor and select the PanelViewController.h file.

  8. Создайте действие для документа пункта меню вызывается propertyDocument:Create an action for the Document menu item called propertyDocument:

    Настройка действияConfiguring the action

  9. Повторите создание действия для оставшихся элементов меню:Repeat creating actions for the remaining menu items:

    Необходимые действияThe required actions

  10. Наконец, создайте выхода для метка свойства вызывается propertyLabel:Finally create an outlet for the Property Label called propertyLabel:

    Настройка выходаConfiguring the outlet

  11. Сохранить изменения и вернуться в Visual Studio для Mac синхронизировать с Xcode.Save your changes and return to Visual Studio for Mac to sync with Xcode.

Изменить PanelViewController.cs файл и добавьте следующий код:Edit the PanelViewController.cs file and add the following code:

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";
}

Теперь Если запустить приложение и щелкните правой кнопкой мыши на свойство метке на панели, мы увидим наш пользовательского контекстного меню.Now if we run the application and right-click on the property label in the panel, we'll see our custom contextual menu. Если выбрать элемент и элемент меню, изменится значение метки:If we select and item from the menu, the label's value will change:

Контекстные меню под управлениемThe contextual menu running

Далее давайте попробуем создать меню панели состояния.Next let's look at creating status bar menus.

Меню панели состоянияStatus bar menus

Меню панели состояние отображения коллекции элементов состояния команды меню, которые обеспечивают взаимодействие с или отзыв для пользователя, например меню или изображение, отражая состояние приложения.Status bar menus display a collection of status menu items that provide interaction with or feedback to the user, such as a menu or an image reflecting an application’s state. Меню строки состояния приложения включении и активации, даже если приложение выполняется в фоновом режиме.An application's status bar menu is enabled and active even if the application is running in the background. В строке состояния всей системы находится в правой части панели меню приложения и является только строки состояния, в настоящее время доступны в macOS.The system-wide status bar resides at the right side of the application menu bar and is the only Status Bar currently available in macOS.

Изменим наш AppDelegate.cs и создайте DidFinishLaunching метод выглядят следующим:Let's edit our AppDelegate.cs file and make the DidFinishLaunching method look like the following:

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; дает нам доступ к строке состояния всей системы.NSStatusBar statusBar = NSStatusBar.SystemStatusBar; gives us access to the system-wide status bar. var item = statusBar.CreateStatusItem (NSStatusItemLength.Variable); Создает новый элемент строки состояния.var item = statusBar.CreateStatusItem (NSStatusItemLength.Variable); creates a new status bar item. Здесь мы создается меню и количество элементов меню и вложите меню элемент строки состояния, который мы только что создали.From there we create a menu and a number of menu items and attach the menu to the status bar item we just created.

Если запустить приложение, отображается новый элемент строки состояния.If we run the application, the new status bar item will be displayed. Выбор элемента из меню изменится текст в представлении текста:Selecting an item from the menu will change the text in the text view:

В меню панели состояния под управлениемThe status bar menu running

Теперь давайте взглянем на создании пользовательских закрепления элементов меню.Next, let's look at creating custom dock menu items.

Меню пользовательских dockCustom dock menus

Всплывающего меню отображается для приложения Mac, когда пользователь щелкает правой кнопкой мыши или элемент управления щелкает значок приложения на панели закрепления:The dock menu appears for you Mac application when the user right-clicks or control-clicks the application's icon in the dock:

Пользовательский закрепить менюA custom dock menu

Давайте создадим пользовательский всплывающего меню для нашего приложения следующим образом:Let's create a custom dock menu for our application by doing the following:

  1. В Visual Studio для Mac, щелкните правой кнопкой мыши на проекте приложения и выберите команду добавить > новый файл... Диалоговое окно создания файла выберите Xamarin.Mac > пустое определение интерфейса, используйте «DockMenu» для имя и нажмите кнопку New кнопку, чтобы создать новый DockMenu.xib файла:In Visual Studio for Mac, right-click on the application's project and select Add > New File... From the new file dialog, select Xamarin.Mac > Empty Interface Definition, use "DockMenu" for the Name and click the New button to create the new DockMenu.xib file:

    Добавление пустое определение интерфейсаAdding an empty interface definition

  2. В панели решения, дважды щелкните DockMenu.xib файл, чтобы открыть его для редактирования в Xcode.In the Solution Pad, double-click the DockMenu.xib file to open it for editing in Xcode. Создайте новый меню со следующими элементами: Адрес, даты, приветствия, и подписиCreate a new Menu with the following items: Address, Date, Greeting, and Signature

    Размещение пользовательского интерфейсаLaying out the UI

  3. Далее подключим к нашей существующих действий, которые мы создали для наших пользовательских меню в наших новых пунктов меню Добавление, редактирование и удаление меню предыдущем разделе.Next, let's connect our new menu items to our existing actions that we created for our custom menu in the Adding, Editing and Deleting Menus section above. Переключиться в режим инспектор подключения и выберите первый респондент в иерархия интерфейса.Switch to the Connection Inspector and select the First Responder in the Interface Hierarchy. Прокрутите вниз и найдите phraseAddress: действие.Scroll down and find the phraseAddress: action. Перетащите линию от круг на это действие для адрес пункта меню:Drag a line from the circle on that action to the Address menu item:

    Перетаскивание пишем действиеDragging to wire up an action

  4. Повторите для всех остальных пунктов меню, их присоединения к их соответствующих действий:Repeat for all of the other menu items attaching them to their corresponding actions:

    Необходимые действияThe required actions

  5. Затем выберите приложения в иерархия интерфейса.Next, select the Application in the Interface Hierarchy. В инспектор подключения, перетащите линию от круг dockMenu розетки, чтобы меню, мы только что создали:In the Connection Inspector, drag a line from the circle on the dockMenu outlet to the menu we just created:

    Перетаскивание установление розеткиDragging the wire up the outlet

  6. Сохраните изменения и вернитесь в Visual Studio для Mac синхронизировать с Xcode.Save your changes and switch back to Visual Studio for Mac to sync with Xcode.

  7. Дважды щелкните Info.plist файл, чтобы открыть его для редактирования:Double-click the Info.plist file to open it for editing:

    Редактирование файла info.plistEditing the Info.plist file

  8. Нажмите кнопку источника вкладку в нижней части экрана:Click the Source tab at the bottom of the screen:

    Выбор представления источникаSelecting the Source view

  9. Нажмите кнопку добавьте новую запись, нажмите кнопку в форме плюса зеленым, задайте имя свойства в «AppleDockMenu» и значение для «DockMenu» (имя наш новый файл .xib без расширения):Click Add new entry, click the green plus button, set the property name to "AppleDockMenu" and the value to "DockMenu" (the name of our new .xib file without the extension):

    Добавление элемента DockMenuAdding the DockMenu item

Теперь если мы запустить наше приложение, щелкните правой кнопкой мыши на значок на панели Dock появится наших новых пунктов меню:Now if we run our application and right-click on its icon in the Dock, our new menu items will be displayed:

Пример всплывающего меню под управлениемAn example of the dock menu running

Если мы выбираем одну из пользовательских элементов в меню, текст в наши представления текста будет изменен.If we select one of the custom items from the menu, the text in our text view will be modified.

Кнопки, всплывающее и раскрывающихся списковPop-up button and pull-down lists

Всплывающая кнопка отображается выбранный элемент и представляет список параметров для использования при нажатии пользователем.A pop-up button displays a selected item and presents a list of options to select from when clicked by the user. Выпадающем списке — это разновидность всплывающее кнопки, обычно используется для выбора команды, относящиеся к контексту текущей задачи.A pull-down list is a type of pop-up button usually used for selecting commands specific to the context of the current task. Оба могут находиться в любом месте окна.Both can appear anywhere in a window.

Давайте создадим пользовательскую кнопку всплывающего для нашего приложения следующим образом:Let's create a custom pop-up button for our application by doing the following:

  1. Изменить Main.storyboard файл в Xcode и перетащите кнопку всплывающего окна из инспектор библиотеки на панели мы создали в окно контекстных меню раздел:Edit the Main.storyboard file in Xcode and drag a Popup Button from the Library Inspector onto the Panel window we created in the Contextual Menus section:

    Добавление кнопки всплывающее окноAdding a popup button

  2. Добавление нового элемента меню и задайте заголовки элементов во всплывающем окне, чтобы: Адрес, даты, приветствия, и подписиAdd a new menu item and set the titles of the Items in the Popup to: Address, Date, Greeting, and Signature

    Настройка пунктов менюConfiguring the menu items

  3. Далее подключим наших новых пунктов меню для существующего действия, которые мы создали для наших пользовательских меню в Добавление, редактирование и удаление меню предыдущем разделе.Next, let's connect our new menu items to the existing actions that we created for our custom menu in the Adding, Editing and Deleting Menus section above. Переключиться в режим инспектор подключения и выберите первый респондент в иерархия интерфейса.Switch to the Connection Inspector and select the First Responder in the Interface Hierarchy. Прокрутите вниз и найдите phraseAddress: действие.Scroll down and find the phraseAddress: action. Перетащите линию от круг на это действие для адрес пункта меню:Drag a line from the circle on that action to the Address menu item:

    Перетаскивание пишем действиеDragging to wire up an action

  4. Повторите для всех остальных пунктов меню, их присоединения к их соответствующих действий:Repeat for all of the other menu items attaching them to their corresponding actions:

    Все необходимые действияAll required actions

  5. Сохраните изменения и вернитесь в Visual Studio для Mac синхронизировать с Xcode.Save your changes and switch back to Visual Studio for Mac to sync with Xcode.

Теперь Если запустить наше приложение и выбрать элемент из всплывающего окна, будет изменен текст в наши представления текста:Now if we run our application and select an item from the popup, the text in our text view will change:

Пример всплывающего окна под управлениемAn example of the popup running

Можно создать и работать с помощью раскрывающихся списков в точно так же как всплывающее кнопки.You can create and work with pull-down lists in the exact same way as pop-up buttons. Вместо присоединения существующего действия, можно создать собственные настраиваемые действия так же как это делалось для наших контекстные меню в контекстных меню раздел.Instead of attaching to existing action, you could create your own custom actions just like we did for our contextual menu in the Contextual Menus section.

СводкаSummary

В этой статье были предприняты никакие подробные принципы работы с меню и пунктов меню в приложении Xamarin.Mac.This article has taken a detailed look at working with menus and menu items in a Xamarin.Mac application. Сначала мы рассмотрели меню приложения, то мы рассмотрели создание контекстных меню, затем мы рассмотрели состояния панель меню и пользовательских закрепление меню.First we examined the application's menu bar, then we looked at creating contextual menus, next we examined status bar menus and custom dock menus. Наконец мы рассматривали, всплывающих меню и раскрывающихся списков.Finally, we covered pop-up menus and pull-down Lists.