Xamarin.Mac 中的 Windows
本文涵蓋在 Xamarin.Mac 應用程式中使用視窗和面板。 它描述在 Xcode 和 Interface Builder 中建立視窗和面板、從分鏡腳本和 .xib 檔案載入視窗和面板,並以程式設計方式加以使用。
在 Xamarin.Mac 應用程式中使用 C# 和 .NET 時,您可以存取開發人員在 和 Xcode 中Objective-C運作的相同 Windows 和面板。 由於 Xamarin.Mac 直接與 Xcode 整合,因此您可以使用 Xcode 的 Interface Builder 來建立和維護您的 Windows 和面板(或選擇性地直接在 C# 程式代碼中建立它們)。
根據其用途,Xamarin.Mac 應用程式可以在畫面上呈現一或多個 Windows,以管理和協調其顯示及使用的資訊。 視窗的主要函式如下:
- 提供可放置及管理檢視和控件的區域。
- 若要接受和回應事件,以回應使用者與鍵盤和滑鼠的互動。
Windows 可以處於無模式狀態(例如可以一次開啟多個檔的文字編輯器)或強制回應(例如,在應用程式可以繼續之前必須關閉的導出對話框)。
面板是一種特殊的 Window(基 NSWindow
類的子類別),通常會在應用程式中提供輔助功能,例如文字格式偵測器和系統色彩選擇器等公用程序視窗。
在本文中,我們將討論在 Xamarin.Mac 應用程式中使用 Windows 和面板的基本概念。 強烈建議您先完成 Hello,Mac 文章,特別是 Xcode 和 Interface Builder 和 Outlets 和 Actions 簡介小節,因為它涵蓋我們將在本文中使用的重要概念和技術。
您可能也想要查看 Xamarin.Mac Internals 檔的公開 C# 類別/方法Objective-C一節,它也會說明 Register
用來將 C# 類別連接至Objective-C物件和 UI 元素的 和 Export
命令。
視窗簡介
如上所述,Window 提供一個區域,其中檢視和控件可以根據用戶互動(透過鍵盤或滑鼠)來放置及管理及回應事件。
根據 Apple 的說法,macOS 應用程式中有五種主要的 Windows 類型:
- 文件視窗 - 文件視窗 包含檔案型用戶數據,例如電子錶格或文字檔。
- 應用程式視窗 - 應用程式視窗是非檔案型應用程式的主要視窗(例如 Mac 上的行事曆應用程式)。
- 面板 - 面板會浮動在其他視窗上方,並提供使用者可在開啟檔時使用的工具或控件。 在某些情況下,面板可以是半透明(例如使用大型圖形時)。
- 對話框 - 對話框隨即出現,以回應使用者動作,且通常會提供使用者完成動作的方式。 對話框需要用戶回應,才能關閉。 (請參閱 使用對話框 )
- 警示 - 警示是特殊類型的對話框,會在發生嚴重問題時出現(例如錯誤)或警告(例如準備刪除檔案)。 因為警示是對話框,所以也需要用戶回應才能關閉。 (請參閱 使用警示)
如需詳細資訊,請參閱 Apple macOS 設計主題的 About Windows 一節。
主要、索引鍵和非使用中的視窗
Xamarin.Mac 應用程式中的 Windows 可以根據使用者目前與其互動的方式,以不同的方式外觀和行為。 目前使用者關注焦點的最重要檔或應用程式視窗稱為 主視窗。 在大部分情況下,此視窗也會是 [索引鍵視窗 ] (目前接受使用者輸入的視窗)。 但這種情況不一定如此,例如,色彩選擇器可以開啟,而且是使用者正在與之互動的索引鍵視窗,以變更文檔視窗中專案的狀態(這仍然是主視窗)。
Main 和 Key Windows(如果個別的視窗)一律為作用中, 非作用中的 Windows 是不在前景的視窗。 例如,文本編輯器應用程式一次可以開啟一個以上的檔,只有主視窗會使用中,所有其他檔都會處於非使用中狀態。
如需詳細資訊,請參閱 Apple macOS 設計主題的 About Windows 一節。
命名視窗
視窗可以顯示標題列,而且當標題顯示時,通常是應用程式的名稱、正在處理的檔名稱或視窗的函式(例如 Inspector)。 某些應用程式不會顯示標題列,因為它們可透過視線辨識,而且無法與檔搭配使用。
Apple 建議下列指導方針:
- 使用您的應用程式名稱作為主要非文檔視窗的標題。
- 將新的文件視窗
untitled
命名為 。 對於第一份新檔,請勿將數位附加至標題(例如untitled 1
)。 如果使用者在儲存第一個檔之前建立另一個新檔,請呼叫該視窗untitled 2
、untitled 3
等。
如需詳細資訊,請參閱Apple macOS設計主題的命名Windows 一節。
全螢幕視窗
在macOS中,應用程式的視窗可以全螢幕隱藏所有內容,包括應用程式功能表欄(可藉由將游標移至螢幕頂端來顯示),以提供與內容分心的免費互動。
Apple 建議下列指導方針:
- 判斷視窗是否適合全螢幕。 提供簡短互動的應用程式(例如計算機)不應該提供全螢幕模式。
- 如果全螢幕工作需要工具列,則顯示工具列。 一般而言,在全螢幕模式中隱藏工具列。
- 全螢幕視窗應該具有使用者完成工作所需的所有功能。
- 可能的話,請避免使用者在全螢幕視窗中進行 Finder 互動。
- 利用增加的螢幕空間,而不將焦點從主要工作移開。
如需詳細資訊,請參閱Apple macOS設計主題的全螢幕 Windows 一節。
窗格
面板是一個輔助視窗,其中包含會影響使用中檔或選取範圍的控件和選項(例如系統色彩選擇器):
面板可以是 應用程式特定 或 全系統。 應用程式特定面板會浮動在應用程式文檔視窗的頂端,並在應用程式處於背景時消失。 全系統面板(例如 字 型面板),無論應用程式為何,都會浮動在所有開啟的視窗上。
Apple 建議下列指導方針:
- 一般而言,使用標準面板時,透明面板應該只謹慎使用,並用於圖形密集的工作。
- 請考慮使用面板讓用戶輕鬆存取直接影響其工作的重要控件或資訊。
- 視需要隱藏和顯示面板。
- 面板應該一律包含標題列。
- 面板不應包含作用中的最小化按鈕。
督察
大部分的新式 macOS 應用程式都會呈現會影響使用中檔或選取項目的輔助控件和選項,做為 主視窗的一部分的偵測器 (例如如下所示的 Pages 應用程式),而不是使用 Panel Windows:
如需詳細資訊,請參閱Apple macOS設計主題的面板一節。
在 Xcode 中建立和維護視窗
當您建立新的 Xamarin.Mac Cocoa 應用程式時,預設會取得標準空白視窗。 這個視窗會在項目中自動包含的檔案中定義 .storyboard
。 若要編輯您的 Windows 設計,請在 方案總管 中按兩下Main.storyboard
檔案:
這會在 Xcode 的 Interface Builder 中開啟視窗設計:
在屬性 偵測器中,有數個屬性可用來定義及控制視窗:
- 標題 - 這是將在視窗標題列中顯示的文字。
- 自動儲存 - 這是 當視窗的位置和設定自動儲存時,用來識別元視窗的索引鍵 。
- 標題列 - 視窗是否顯示標題列。
- 統一標題和工具列 - 如果視窗包含工具列 ,則應該是標題列的一部分。
- 完整大小的內容檢視 - 允許視窗的內容區域在標題列下。
- 陰影 - 視窗是否有陰影。
- 紋理 - 紋理視窗可以使用效果(如活力),並可透過拖曳其身體上的任何位置來移動。
- 關閉 -視窗是否有關閉按鈕。
- 最小化 - 視窗是否有最小化按鈕。
- 重設大小 - 視窗是否有重設大小控制件。
- 工具列按鈕 - 視窗是否有隱藏/顯示工具列按鈕。
- 可 還原 - 視窗的位置和設定會自動儲存和還原。
- 在啟動時 可見 - 載入檔案時
.xib
會自動顯示視窗。 - 在停用 時隱藏 - 當應用程式進入背景時,視窗會隱藏。
- 關閉 時釋放 - 視窗是否在關閉時從記憶體中清除。
- 永遠顯示工具提示 - 工具提示是否持續顯示。
- 重新計算檢視迴圈 - 這是在繪製視窗之前重新計算的檢視順序。
- 空格、 公開 和 迴圈 - 所有都會定義視窗在這些 macOS 環境中的行為方式。
- 全螢幕 - 判斷此視窗是否可以進入全螢幕模式。
- 動畫 -控制視窗可用的動畫類型。
- 外觀 -控制窗口的外觀。 目前只有一個外觀,水。
如需詳細資訊,請參閱Apple 的 Windows 和 NSWindow 簡介檔。
設定預設大小和位置
若要設定視窗的初始位置並控制其大小,請切換至 [大小偵測器]:
您可以從這裡設定視窗的初始大小、提供最小和大小上限、在畫面上設定初始位置,以及控制視窗周圍的框線。
設定自定義主視窗控制器
若要能夠建立輸出和動作,將UI元素公開至 C# 程式代碼,Xamarin.Mac 應用程式必須使用自定義視窗控制器。
執行下列操作:
在 Xcode 的 Interface Builder 中開啟應用程式的分鏡腳本。
NSWindowController
在[設計介面] 中選取 。切換至 [ 身分識別偵測器 ] 檢視,然後輸入
WindowController
作為 [類別名稱]:儲存變更並返回 Visual Studio for Mac 進行同步處理。
WindowController.cs
Visual Studio for Mac 中的 方案總管 中,將會將檔案新增至您的 Project:在 Xcode 的介面產生器中重新開啟分鏡腳本。
檔案
WindowController.h
將可供使用:
新增UI元素
若要定義視窗的內容,請將控件從 [鏈接庫偵測器 ] 拖曳至 [介面編輯器]。 如需使用介面產生器建立和啟用控件的詳細資訊,請參閱 Xcode 和 Interface Builder 簡介檔。
例如,讓我們將工具列從連結庫偵測器拖曳到介面編輯器中的視窗:
接下來,拖曳文字 檢視 並調整其大小,以填滿工具欄底下的區域:
由於我們希望 文字檢視 隨著視窗大小變更而縮小和成長,因此讓我們切換至 [條件約束編輯器 ],並新增下列條件約束:
按兩下編輯器頂端的四 個紅色 I-Beam, 然後按兩下 [新增4個條件約束],我們會告訴文字檢視要堅持指定的 X、Y 座標,並在視窗重設大小時水準和垂直放大或縮小。
最後,使用輸出將文字檢視公開為程式代碼(請務必選取檔案ViewController.h
):
儲存變更並切換回 Visual Studio for Mac 以與 Xcode 同步。
標準視窗工作流程
對於您在 Xamarin.Mac 應用程式中建立及使用的任何視窗,此程式基本上與我們先前所做的相同:
- 對於非預設新增至專案的新視窗,請將新的視窗定義新增至專案。 以下將詳細討論這一點。
- 按兩下
Main.storyboard
檔案,開啟在 Xcode 介面產生器中編輯的窗口設計。 - 將新的視窗拖曳至使用者介面的設計,並使用 Segues 將視窗連結至主視窗(如需詳細資訊,請參閱使用分鏡腳本檔的 Segues 一節)。
- 在屬性偵測器和大小偵測器中設定任何必要的視窗屬性。
- 拖曳至建置介面所需的控件,並在屬性偵測器中設定它們。
- 使用大小偵測器來處理UI元素的大小調整。
- 透過 輸出 和 動作,將視窗的UI元素公開至 C# 程式代碼。
- 儲存變更並切換回 Visual Studio for Mac 以與 Xcode 同步。
既然我們已建立基本窗口,我們將查看 Xamarin.Mac 應用程式在使用視窗時執行的一般程式。
顯示預設視窗
根據預設,新的 Xamarin.Mac 應用程式會在啟動時自動顯示檔案中 MainWindow.xib
定義的視窗:
由於我們修改了上述窗口的設計,因此它現在包含預設的工具列和 文字檢視 控件。 檔案中的 Info.plist
下一節負責顯示此視窗:
[ 主要介面 ] 下拉式清單用來選取將作為主要應用程式 UI 的分鏡腳本(在此案例中為 Main.storyboard
)。
檢視控制器會自動新增至專案,以控制顯示的主視窗(及其主要檢視)。 它定義於檔案中,ViewController.cs
並附加至身分識別偵測器下介面產生器的檔案擁有者:
針對我們的窗口,我們想要在它第一次開啟時擁有的 untitled
標題,因此讓我們覆寫 ViewWillAppear
中的 ViewController.cs
方法,如下所示:
public override void ViewWillAppear ()
{
base.ViewWillAppear ();
// Set Window Title
this.View.Window.Title = "untitled";
}
注意
視窗的 Title
屬性是在 方法中 ViewWillAppear
設定,而不是 ViewDidLoad
方法,因為雖然檢視可能會載入記憶體中,但尚未完全具現化。 在 Title
方法中 ViewDidLoad
存取 屬性時,我們將會收到 null
例外狀況,因為視窗尚未建構並連到 屬性。
以程式設計方式關閉視窗
您可能想要以程式設計方式關閉 Xamarin.Mac 應用程式中的視窗,而不是讓使用者按兩下視窗的 [關閉 ] 按鈕或使用選單項。 macOS 提供兩種不同的方式,以程式設計方式關閉 NSWindow
: PerformClose
和 Close
。
PerformClose
PerformClose
呼叫 的 方法NSWindow
會模擬使用者按兩下視窗的 [關閉] 按鈕,方法是暫時反白顯示按鈕,然後關閉視窗。
如果應用程式實作 NSWindow
的 WillClose
事件,則會在關閉視窗之前引發它。 如果事件傳 false
回 ,則不會關閉視窗。 如果視窗沒有 [關閉 ] 按鈕或因任何原因而無法關閉,則OS會發出警示音效。
例如:
MyWindow.PerformClose(this);
會嘗試關閉 MyWindow
NSWindow
實例。 如果成功,視窗將會關閉,否則會發出警示音效,且 會保持開啟狀態。
關閉
Close
呼叫 的 方法NSWindow
不會模擬使用者按兩下視窗的 [關閉] 按鈕,方法是暫時醒目提示按鈕,而只會關閉視窗。
視窗不需要顯示關閉,而且 NSWindowWillCloseNotification
通知會張貼到關閉視窗的默認通知中心。
方法 Close
與 方法不同,有兩個重要方式 PerformClose
:
- 它不會嘗試引發
WillClose
事件。 - 它不會模擬使用者按兩下 [關閉 ] 按鈕,方法是暫時醒目提示按鈕。
例如:
MyWindow.Close();
會關閉 MyWindow
NSWindow
實例。
修改過的窗口內容
在macOS中,Apple提供了一種方式來通知使用者 Window (NSWindow
) 的內容已由使用者修改,而且需要儲存。 如果 Window 包含修改的內容,則會在 [ 關閉 ] 小工具中顯示一個小黑點:
如果使用者嘗試關閉視窗或結束 Mac 應用程式,而視窗內容有未儲存的變更,您應該先顯示 對話框 或 強制回應表 ,並允許使用者先儲存變更:
將視窗標示為已修改
若要將 Window 標示為已修改的內容,請使用下列程式代碼:
// Mark Window content as modified
Window.DocumentEdited = true;
一旦儲存變更之後,請使用下列專案清除已修改的旗標:
// Mark Window content as not modified
Window.DocumentEdited = false;
關閉視窗之前儲存變更
若要監看使用者關閉 Window 並允許他們事先儲存修改的內容,您必須建立 的 NSWindowDelegate
子類別並覆寫其 WindowShouldClose
方法。 例如:
using System;
using AppKit;
using System.IO;
using Foundation;
namespace SourceWriter
{
public class EditorWindowDelegate : NSWindowDelegate
{
#region Computed Properties
public NSWindow Window { get; set;}
#endregion
#region constructors
public EditorWindowDelegate (NSWindow window)
{
// Initialize
this.Window = window;
}
#endregion
#region Override Methods
public override bool WindowShouldClose (Foundation.NSObject sender)
{
// is the window dirty?
if (Window.DocumentEdited) {
var alert = new NSAlert () {
AlertStyle = NSAlertStyle.Critical,
InformativeText = "Save changes to document before closing window?",
MessageText = "Save Document",
};
alert.AddButton ("Save");
alert.AddButton ("Lose Changes");
alert.AddButton ("Cancel");
var result = alert.RunSheetModal (Window);
// Take action based on result
switch (result) {
case 1000:
// Grab controller
var viewController = Window.ContentViewController as ViewController;
// Already saved?
if (Window.RepresentedUrl != null) {
var path = Window.RepresentedUrl.Path;
// Save changes to file
File.WriteAllText (path, viewController.Text);
return true;
} else {
var dlg = new NSSavePanel ();
dlg.Title = "Save Document";
dlg.BeginSheet (Window, (rslt) => {
// File selected?
if (rslt == 1) {
var path = dlg.Url.Path;
File.WriteAllText (path, viewController.Text);
Window.DocumentEdited = false;
viewController.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
viewController.View.Window.RepresentedUrl = dlg.Url;
Window.Close();
}
});
return true;
}
return false;
case 1001:
// Lose Changes
return true;
case 1002:
// Cancel
return false;
}
}
return true;
}
#endregion
}
}
使用下列程式代碼,將此委派的實體附加至視窗:
// Set delegate
Window.Delegate = new EditorWindowDelegate(Window);
在關閉應用程式之前儲存變更
最後,您的 Xamarin.Mac 應用程式應該檢查其任何 Windows 是否包含已修改的內容,並允許使用者在結束之前儲存變更。 若要這樣做,請編輯您的 AppDelegate.cs
檔案、覆寫 ApplicationShouldTerminate
方法,並使其看起來如下:
public override NSApplicationTerminateReply ApplicationShouldTerminate (NSApplication sender)
{
// See if any window needs to be saved first
foreach (NSWindow window in NSApplication.SharedApplication.Windows) {
if (window.Delegate != null && !window.Delegate.WindowShouldClose (this)) {
// Did the window terminate the close?
return NSApplicationTerminateReply.Cancel;
}
}
// Allow normal termination
return NSApplicationTerminateReply.Now;
}
使用多個視窗
大部分的檔型 Mac 應用程式都可以同時編輯多個檔案。 例如,文本編輯器可以同時開啟多個文本檔進行編輯。 根據預設,新的 Xamarin.Mac 應用程式具有 [檔案] 功能表,且 [新增] 專案會自動連線到 newDocument:
[動作]。
下列程式代碼會啟動這個新專案,並允許用戶開啟主視窗的多個複本,一次編輯多個檔。
編輯檔案並 AppDelegate.cs
新增下列計算屬性:
public int UntitledWindowCount { get; set;} =1;
使用此項目來追蹤未儲存的檔案數目,以便我們可以向使用者提供意見反應(根據上述的 Apple 指導方針)。
接下來,新增下列方法:
[Export ("newDocument:")]
void NewDocument (NSObject sender) {
// Get new window
var storyboard = NSStoryboard.FromName ("Main", null);
var controller = storyboard.InstantiateControllerWithIdentifier ("MainWindow") as NSWindowController;
// Display
controller.ShowWindow(this);
// Set the title
controller.Window.Title = (++UntitledWindowCount == 1) ? "untitled" : string.Format ("untitled {0}", UntitledWindowCount);
}
此程式代碼會建立新版的視窗控制器、載入新的視窗、使其成為主視窗和索引鍵視窗,並將它設定為標題。 現在,如果我們執行應用程式,然後從 [檔案] 功能選取 [新增],就會開啟並顯示新的編輯器視窗:
如果我們開啟 Windows 選單,您可以看到應用程式會自動追蹤及處理開啟的視窗:
如需在 Xamarin.Mac 應用程式中使用功能表的詳細資訊,請參閱使用 功能表 檔。
取得目前使用中的視窗
在可以開啟多個視窗的 Xamarin.Mac 應用程式中,有時候您需要取得目前最上層視窗(關鍵視窗)。 下列程式代碼會傳回金鑰視窗:
var window = NSApplication.SharedApplication.KeyWindow;
它可以在任何需要存取目前索引鍵視窗的類別或方法中呼叫。 如果目前未開啟任何視窗,則會傳回 null
。
存取所有應用程式視窗
有時候您可能需要存取 Xamarin.Mac 應用程式目前開啟的所有視窗。 例如,若要查看使用者想要開啟的檔案是否已在結束窗口中開啟。
會 NSApplication.SharedApplication
維護 Windows
屬性,其中包含應用程式中所有開啟視窗的陣列。 您可以逐一查看此陣列,以存取所有應用程式的目前視窗。 例如:
// 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
屬性的值。 如果檔案已經開啟,我們會將該視窗帶到前面。
調整程式代碼中的視窗大小
有時候應用程式需要調整程式代碼中的視窗大小。 若要調整視窗的大小並重新置放,您可以調整其 Frame
屬性。 調整視窗大小時,您通常也需要調整其原點,因為macOS的座標系統,讓視窗保持在相同的位置。
與左上角代表 (0,0) 的 iOS 不同,macOS 會使用數學座標系統,其中螢幕左下角代表 (0,0)。 在 iOS 中,當您向下向右移動時,座標會增加。 在macOS中,座標的值會向上增加到右邊。
下列範例程式代碼會調整視窗的大小:
nfloat y = 0;
// Calculate new origin
y = Frame.Y - (768 - Frame.Height);
// Resize and position window
CGRect frame = new CGRect (Frame.X, y, 1024, 768);
SetFrame (frame, true);
重要
當您在程式代碼中調整視窗大小和位置時,您必須確定遵守您在 Interface Builder 中設定的最小和最大大小。 這不會自動接受,而且您將能夠讓視窗變大或小於這些限制。
監視視窗大小變更
有時候您可能需要監視 Xamarin.Mac 應用程式內 Window 大小的變更。 例如,若要重繪內容以符合新的大小。
若要監視大小變更,請先確定您已在 Xcode 的 Interface Builder 中指派視窗控制器的自定義類別。 例如, MasterWindowController
在下列內容中:
接下來,編輯自定義的 Window 控制器類別,並監視 DidResize
控制器視窗上的事件,以通知即時大小變更。 例如:
public override void WindowDidLoad ()
{
base.WindowDidLoad ();
Window.DidResize += (sender, e) => {
// Do something as the window is being live resized
};
}
您可以選擇性地使用 DidEndLiveResize
事件,只有在使用者完成變更 Window 的大小之後,才會收到通知。 例如:
public override void WindowDidLoad ()
{
base.WindowDidLoad ();
Window.DidEndLiveResize += (sender, e) => {
// Do something after the user's finished resizing
// the window
};
}
設定視窗的標題和表示的檔案
使用代表文件的視窗時,具有 DocumentEdited
屬性,NSWindow
如果設定為true
在 [關閉] 按鈕中顯示一個小點,讓使用者指出檔案已修改,而且應該在關閉之前儲存。
讓我們編輯檔案 ViewController.cs
並進行下列變更:
public bool DocumentEdited {
get { return View.Window.DocumentEdited; }
set { View.Window.DocumentEdited = value; }
}
...
public override void ViewWillAppear ()
{
base.ViewWillAppear ();
// Set Window Title
this.View.Window.Title = "untitled";
View.Window.WillClose += (sender, e) => {
// is the window dirty?
if (DocumentEdited) {
var alert = new NSAlert () {
AlertStyle = NSAlertStyle.Critical,
InformativeText = "We need to give the user the ability to save the document here...",
MessageText = "Save Document",
};
alert.RunModal ();
}
};
}
public override void AwakeFromNib ()
{
base.AwakeFromNib ();
// Show when the document is edited
DocumentEditor.TextDidChange += (sender, e) => {
// Mark the document as dirty
DocumentEdited = true;
};
// Overriding this delegate is required to monitor the TextDidChange event
DocumentEditor.ShouldChangeTextInRanges += (NSTextView view, NSValue[] values, string[] replacements) => {
return true;
};
}
我們也在視窗上監視 WillClose
事件,並檢查屬性的狀態 DocumentEdited
。 true
如果需要讓用戶能夠將變更儲存至檔案。 如果我們執行應用程式並輸入文字,則會顯示點:
如果您嘗試關閉視窗,您會收到警示:
如果您要從檔案載入檔,請使用 window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
方法將視窗的標題設定為檔名(假設 path
是代表要開啟之檔案的字串)。 此外,您可以使用 方法來設定檔案 window.RepresentedUrl = url;
的URL。
如果 URL 指向 OS 已知的檔類型,其圖示會顯示在標題欄中。 如果使用者以滑鼠右鍵按下圖示,則會顯示檔案的路徑。
編輯檔案並 AppDelegate.cs
新增下列方法:
[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) {
var path = url.Path;
// 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.View.Window.SetTitleWithRepresentedFilename (Path.GetFileName(path));
viewController.View.Window.RepresentedUrl = url;
}
}
}
現在,如果我們執行應用程式,請從 [檔案] 功能表中選取 [開啟...],從 [開啟對話框] 中選取文本檔,然後開啟它:
將會顯示檔案,且標題會以檔案的圖示進行設定:
將新視窗新增至專案
除了主文檔視窗之外,Xamarin.Mac 應用程式可能需要向用戶顯示其他類型的視窗,例如 [喜好設定] 或 [偵測器面板]。
若要新增視窗,請執行下列動作:
在 方案總管 中,按兩下
Main.storyboard
檔案以開啟檔案,以在 Xcode 的 Interface Builder 中編輯。從 [連結庫] 拖曳新的視窗控制器,並將其放在設計介面上:
在身 分識別偵測器中,輸入
PreferencesWindow
分 鏡腳本標識碼:設計介面:
開啟應用程式功能表 (
MacWindows
),選取 [喜好設定...],單擊控件並拖曳至新的視窗:從快捷功能表選取 [ 顯示 ]。
儲存變更並返回 Visual Studio for Mac 以與 Xcode 同步。
如果我們執行程式代碼,並從應用程式選單選取 [喜好設定...],則會顯示視窗:
使用面板
如本文開頭所述,面板會浮動在其他視窗上方,並提供使用者可在開啟檔時使用的工具或控件。
就像您在 Xamarin.Mac 應用程式中建立和使用的任何其他視窗類型一樣,程式基本上相同:
- 將新的視窗定義新增至專案。
- 按兩下
.xib
檔案,開啟在 Xcode 介面產生器中編輯的窗口設計。 - 在屬性偵測器和大小偵測器中設定任何必要的視窗屬性。
- 拖曳至建置介面所需的控件,並在屬性偵測器中設定它們。
- 使用大小偵測器來處理UI元素的大小調整。
- 透過 輸出 和 動作,將視窗的UI元素公開至 C# 程式代碼。
- 儲存變更並切換回 Visual Studio for Mac 以與 Xcode 同步。
在屬性偵測器中,您有下列面板專屬的選項:
- 樣式 - 可讓您調整面板的樣式:一般面板(看起來像標準視窗)、公用程式面板(具有較小的標題欄)、HUD 面板(是半透明,標題欄是背景的一部分)。
- 非啟用 - 在面板中判斷會成為金鑰視窗。
- 文件強制回應 - 如果 Document Modal ,面板只會浮動在應用程式的視窗上方,否則會浮動在全部上方。
若要新增面板,請執行下列動作:
在 方案總管 中,以滑鼠右鍵按兩下 [專案],然後選取 [新增>檔案...]。
在 [新增檔案] 對話框中,選取具有控制器的 Xamarin.Mac>Cocoa Window:
輸入
DocumentPanel
作為 [名稱],然後按一下 [新增] 按鈕。按兩下
DocumentPanel.xib
檔案,以在介面產生器中開啟它以進行編輯:刪除現有的視窗,並從介面編輯器中的 [連結庫偵測器] 拖曳面板:
將面板連結至檔案的擁有者 - 窗口 - 輸出:
切換至 Identity Inspector ,並將 Panel 的類別設定為
DocumentPanel
:儲存變更並返回 Visual Studio for Mac 以與 Xcode 同步。
編輯檔案,
DocumentPanel.cs
並將類別定義變更為下列專案:public partial class DocumentPanel : NSPanel
儲存對檔案所做的變更。
AppDelegate.cs
編輯檔案,並讓 DidFinishLaunching
方法看起來如下:
public override void DidFinishLaunching (NSNotification notification)
{
// Display panel
var panel = new DocumentPanelController ();
panel.Window.MakeKeyAndOrderFront (this);
}
如果我們執行應用程式,將會顯示面板:
重要
面板 Windows 已被 Apple 取代,應該取代為 Inspector 介面。
摘要
本文已詳細探討在 Xamarin.Mac 應用程式中使用 Windows 和面板。 我們看到了 Windows 和面板的不同類型和用法、如何在 Xcode 的 Interface Builder 中建立和維護 Windows 和面板,以及如何在 C# 程式代碼中使用 Windows 和面板。