Xamarin.Mac 中的集合檢視

本文說明在 Xamarin.Mac 應用程式中使用集合檢視。 它涵蓋在 Xcode 和 Interface Builder 中建立和維護集合檢視,並以程式設計方式使用這些檢視。

在 Xamarin.Mac 應用程式中使用 C# 和 .NET 時,開發人員可以存取開發人員在 和 XcodeObjective-C運作的相同 AppKit 集合檢視控件。 由於 Xamarin.Mac 直接與 Xcode 整合,因此開發人員會使用 Xcode 的 介面產生器 來建立及維護集合檢視。

會顯示 NSCollectionView 使用 NSCollectionViewLayout組織之子檢視的方格。 方格中的每個子檢視都會以 NSCollectionViewItem ,管理從 .xib 檔案載入檢視的內容。

範例應用程式執行

本文涵蓋在 Xamarin.Mac 應用程式中使用集合檢視的基本概念。 強烈建議您先完成 Hello,Mac 文章,特別是 Xcode 和 Interface Builder 和 Outlets 和 Actions 簡介小節,因為它涵蓋本文中所使用的重要概念和技術。

您可能也想要查看 Xamarin.Mac Internals 檔的公開 C# 類別/方法Objective-C一節,它也會說明 Register 用來將 C# 類別連接至Objective-C物件和 UI 元素的 和 Export 命令。

關於集合檢視

集合檢視 (NSCollectionView) 的主要目標是使用集合檢視版面配置 ,以有條理的方式排列一組物件,而每個個別物件 (NSCollectionViewLayoutNSCollectionViewItem) 都會在較大的集合中取得自己的 View。 集合檢視可透過數據系結和索引鍵/值編碼技術運作,因此,您應該先閱讀 數據系結和索引鍵/值編碼 檔,再繼續進行本文。

集合檢視沒有標準、內建的集合檢視專案(例如大綱或表格檢視),因此開發人員會負責使用影像欄位、文字字段、卷標等其他 AppKit 控件來設計和實 作原型檢視 。此原型檢視將用來顯示及處理集合檢視所管理的每個專案,並儲存在檔案中 .xib

由於開發人員負責集合檢視專案的外觀和風格,因此集合檢視沒有內建支援,無法反白顯示方格中選取的專案。 本文將涵蓋實作這項功能。

定義數據模型

在介面產生器中的數據系結集合檢視之前,必須在 Xamarin.Mac 應用程式中定義索引鍵/值編碼 (KVC)/Key-Value Observing (KVO) 相容類別,才能做為 系結的數據模型 。 數據模型會提供集合中顯示的所有數據,並在執行應用程式時接收使用者對UI中所做的任何修改。

以管理一組員工的應用程式為例,可以使用下列類別來定義數據模型:

using System;
using Foundation;
using AppKit;

namespace MacDatabinding
{
    [Register("PersonModel")]
    public class PersonModel : NSObject
    {
        #region Private Variables
        private string _name = "";
        private string _occupation = "";
        private bool _isManager = false;
        private NSMutableArray _people = new NSMutableArray();
        #endregion

        #region Computed Properties
        [Export("Name")]
        public string Name {
            get { return _name; }
            set {
                WillChangeValue ("Name");
                _name = value;
                DidChangeValue ("Name");
            }
        }

        [Export("Occupation")]
        public string Occupation {
            get { return _occupation; }
            set {
                WillChangeValue ("Occupation");
                _occupation = value;
                DidChangeValue ("Occupation");
            }
        }

        [Export("isManager")]
        public bool isManager {
            get { return _isManager; }
            set {
                WillChangeValue ("isManager");
                WillChangeValue ("Icon");
                _isManager = value;
                DidChangeValue ("isManager");
                DidChangeValue ("Icon");
            }
        }

        [Export("isEmployee")]
        public bool isEmployee {
            get { return (NumberOfEmployees == 0); }
        }

        [Export("Icon")]
        public NSImage Icon
        {
            get
            {
                if (isManager)
                {
                    return NSImage.ImageNamed("IconGroup");
                }
                else
                {
                    return NSImage.ImageNamed("IconUser");
                }
            }
        }

        [Export("personModelArray")]
        public NSArray People {
            get { return _people; }
        }

        [Export("NumberOfEmployees")]
        public nint NumberOfEmployees {
            get { return (nint)_people.Count; }
        }
        #endregion

        #region Constructors
        public PersonModel ()
        {
        }

        public PersonModel (string name, string occupation)
        {
            // Initialize
            this.Name = name;
            this.Occupation = occupation;
        }

        public PersonModel (string name, string occupation, bool manager)
        {
            // Initialize
            this.Name = name;
            this.Occupation = occupation;
            this.isManager = manager;
        }
        #endregion

        #region Array Controller Methods
        [Export("addObject:")]
        public void AddPerson(PersonModel person) {
            WillChangeValue ("personModelArray");
            isManager = true;
            _people.Add (person);
            DidChangeValue ("personModelArray");
        }

        [Export("insertObject:inPersonModelArrayAtIndex:")]
        public void InsertPerson(PersonModel person, nint index) {
            WillChangeValue ("personModelArray");
            _people.Insert (person, index);
            DidChangeValue ("personModelArray");
        }

        [Export("removeObjectFromPersonModelArrayAtIndex:")]
        public void RemovePerson(nint index) {
            WillChangeValue ("personModelArray");
            _people.RemoveObject (index);
            DidChangeValue ("personModelArray");
        }

        [Export("setPersonModelArray:")]
        public void SetPeople(NSMutableArray array) {
            WillChangeValue ("personModelArray");
            _people = array;
            DidChangeValue ("personModelArray");
        }
        #endregion
    }
}

本文 PersonModel 其餘部分都會使用數據模型。

使用集合檢視

具有集合檢視的數據系結與數據表檢視非常類似,如同 NSCollectionViewDataSource 用來提供集合數據一樣。 由於集合檢視沒有預設的顯示格式,因此需要更多工作才能提供使用者互動意見反應,以及追蹤用戶選取專案。

建立儲存格原型

由於集合檢視不包含預設儲存格原型,開發人員必須將一或多個 .xib 檔案新增至 Xamarin.Mac 應用程式,以定義個別儲存格的配置和內容。

執行下列操作:

  1. 在 方案總管,以滑鼠右鍵按下專案名稱,然後選取 [新增>檔案...

  2. 選取 [Mac>檢視控制器],為其指定名稱(例如EmployeeItem在此範例中),然後按兩下 [新增] 按鈕以建立:

    新增檢視控制器

    這會將、 EmployeeItemController.csEmployeeItemController.xib 檔案新增EmployeeItem.cs至專案的方案。

  3. 按兩下 EmployeeItemController.xib 檔案以開啟檔案,以在 Xcode 的 Interface Builder 中編輯。

  4. 將、 NSImageView 和 兩NSLabelNSBox控件新增至檢視,並如下所示加以配置:

    設計儲存格原型的配置

  5. 開啟 [小幫手編輯器] 並建立 的 [輸出NSBox],以便用來指出單元格的選取狀態:

    在輸出中公開 NSBox

  6. 返回 標準編輯器 ,然後選取 [影像檢視]。

  7. 在系結偵測器中,選取 [系結至>檔案的擁有者],然後輸入 的模型密鑰路徑:self.Person.Icon

    系結圖示

  8. 選取第一個標籤,然後在繫結偵測器中,選取 [系結至>檔案的擁有者],然後輸入 的模型密鑰路徑:self.Person.Name

    系結名稱

  9. 選取第二個標籤,然後在 [系結檢查] 中,選取 [系結至>檔案的擁有者],然後輸入 的模型密鑰路徑:self.Person.Occupation

    系結職業

  10. 將變更儲存至 .xib 檔案,並返回 Visual Studio 以同步處理變更。

EmployeeItemController.cs編輯檔案,使其看起來如下:

using System;
using System.Collections.Generic;
using System.Linq;
using Foundation;
using AppKit;

namespace MacCollectionNew
{
    /// <summary>
    /// The Employee item controller handles the display of the individual items that will
    /// be displayed in the collection view as defined in the associated .XIB file.
    /// </summary>
    public partial class EmployeeItemController : NSCollectionViewItem
    {
        #region Private Variables
        /// <summary>
        /// The person that will be displayed.
        /// </summary>
        private PersonModel _person;
        #endregion

        #region Computed Properties
        // strongly typed view accessor
        public new EmployeeItem View
        {
            get
            {
                return (EmployeeItem)base.View;
            }
        }

        /// <summary>
        /// Gets or sets the person.
        /// </summary>
        /// <value>The person that this item belongs to.</value>
        [Export("Person")]
        public PersonModel Person
        {
            get { return _person; }
            set
            {
                WillChangeValue("Person");
                _person = value;
                DidChangeValue("Person");
            }
        }

        /// <summary>
        /// Gets or sets the color of the background for the item.
        /// </summary>
        /// <value>The color of the background.</value>
        public NSColor BackgroundColor {
            get { return Background.FillColor; }
            set { Background.FillColor = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="T:MacCollectionNew.EmployeeItemController"/> is selected.
        /// </summary>
        /// <value><c>true</c> if selected; otherwise, <c>false</c>.</value>
        /// <remarks>This also changes the background color based on the selected state
        /// of the item.</remarks>
        public override bool Selected
        {
            get
            {
                return base.Selected;
            }
            set
            {
                base.Selected = value;

                // Set background color based on the selection state
                if (value) {
                    BackgroundColor = NSColor.DarkGray;
                } else {
                    BackgroundColor = NSColor.LightGray;
                }
            }
        }
        #endregion

        #region Constructors
        // Called when created from unmanaged code
        public EmployeeItemController(IntPtr handle) : base(handle)
        {
            Initialize();
        }

        // Called when created directly from a XIB file
        [Export("initWithCoder:")]
        public EmployeeItemController(NSCoder coder) : base(coder)
        {
            Initialize();
        }

        // Call to load from the XIB/NIB file
        public EmployeeItemController() : base("EmployeeItem", NSBundle.MainBundle)
        {
            Initialize();
        }

        // Added to support loading from XIB/NIB
        public EmployeeItemController(string nibName, NSBundle nibBundle) : base(nibName, nibBundle) {

            Initialize();
        }

        // Shared initialization code
        void Initialize()
        {
        }
        #endregion
    }
}

詳細查看此程式代碼,類別繼承自 NSCollectionViewItem ,因此它可以做為集合檢視儲存格的原型。 屬性 Person 會公開用來將數據系結至 Xcode 中影像檢視和標籤的類別。 這是上述所建立的 PersonModel 實例。

屬性BackgroundColor是控制件的FillColor快捷方式NSBox,將用來顯示儲存格的選取狀態。 藉由覆寫 SelectedNSCollectionViewItem屬性,下列程式代碼會設定或清除此選取狀態:

public override bool Selected
{
    get
    {
        return base.Selected;
    }
    set
    {
        base.Selected = value;

        // Set background color based on the selection state
        if (value) {
            BackgroundColor = NSColor.DarkGray;
        } else {
            BackgroundColor = NSColor.LightGray;
        }
    }
}

建立集合檢視數據源

集合檢視數據源 (NSCollectionViewDataSource) 會提供集合檢視的所有數據,並建立並填入集合檢視數據格(使用 .xib 原型),作為集合中每個專案的必要專案。

新增項目類別、呼叫它 CollectionViewDataSource 並使其看起來如下:

using System;
using System.Collections.Generic;
using AppKit;
using Foundation;

namespace MacCollectionNew
{
    /// <summary>
    /// Collection view data source provides the data for the collection view.
    /// </summary>
    public class CollectionViewDataSource : NSCollectionViewDataSource
    {
        #region Computed Properties
        /// <summary>
        /// Gets or sets the parent collection view.
        /// </summary>
        /// <value>The parent collection view.</value>
        public NSCollectionView ParentCollectionView { get; set; }

        /// <summary>
        /// Gets or sets the data that will be displayed in the collection.
        /// </summary>
        /// <value>A collection of PersonModel objects.</value>
        public List<PersonModel> Data { get; set; } = new List<PersonModel>();
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="T:MacCollectionNew.CollectionViewDataSource"/> class.
        /// </summary>
        /// <param name="parent">The parent collection that this datasource will provide data for.</param>
        public CollectionViewDataSource(NSCollectionView parent)
        {
            // Initialize
            ParentCollectionView = parent;

            // Attach to collection view
            parent.DataSource = this;

        }
        #endregion

        #region Override Methods
        /// <summary>
        /// Gets the number of sections.
        /// </summary>
        /// <returns>The number of sections.</returns>
        /// <param name="collectionView">The parent Collection view.</param>
        public override nint GetNumberOfSections(NSCollectionView collectionView)
        {
            // There is only one section in this view
            return 1;
        }

        /// <summary>
        /// Gets the number of items in the given section.
        /// </summary>
        /// <returns>The number of items.</returns>
        /// <param name="collectionView">The parent Collection view.</param>
        /// <param name="section">The Section number to count items for.</param>
        public override nint GetNumberofItems(NSCollectionView collectionView, nint section)
        {
            // Return the number of items
            return Data.Count;
        }

        /// <summary>
        /// Gets the item for the give section and item index.
        /// </summary>
        /// <returns>The item.</returns>
        /// <param name="collectionView">The parent Collection view.</param>
        /// <param name="indexPath">Index path specifying the section and index.</param>
        public override NSCollectionViewItem GetItem(NSCollectionView collectionView, NSIndexPath indexPath)
        {
            var item = collectionView.MakeItem("EmployeeCell", indexPath) as EmployeeItemController;
            item.Person = Data[(int)indexPath.Item];

            return item;
        }
        #endregion
    }
}

詳細查看此程式代碼,類別會繼承自 NSCollectionViewDataSource ,並透過其 Data 屬性公開實例清單PersonModel

由於這個集合只有一個區段,因此程式代碼會 GetNumberOfSections 覆寫 方法,而且一律會傳 1回 。 此外, GetNumberofItems 方法會在其上覆寫,以傳回屬性清單中的項目 Data 數目。

GetItem每當需要新的儲存格時,就會呼叫 方法,如下所示:

public override NSCollectionViewItem GetItem(NSCollectionView collectionView, NSIndexPath indexPath)
{
    var item = collectionView.MakeItem("EmployeeCell", indexPath) as EmployeeItemController;
    item.Person = Data[(int)indexPath.Item];

    return item;
}

呼叫 MakeItem 集合檢視的 方法來建立或傳回 可重複使用的 EmployeeItemController 實例,而且其 Person 屬性會設定為在要求單元格中顯示的專案。

EmployeeItemController必須使用下列程式代碼事先向集合檢視控制器註冊 :

EmployeeCollection.RegisterClassForItem(typeof(EmployeeItemController), "EmployeeCell");

呼叫中使用的MakeItem識別碼EmployeeCell) 必須符合已向集合檢視註冊的檢視控制器名稱。 下列步驟將詳細說明。

處理項目選取

若要處理集合中項目的選取和取消選取,將需要 。NSCollectionViewDelegate 由於此範例將使用內 NSCollectionViewFlowLayout 建的版面配置類型, NSCollectionViewDelegateFlowLayout 因此需要此委派的特定版本。

將新類別新增至專案、呼叫它 CollectionViewDelegate ,並使其看起來如下:

using System;
using Foundation;
using AppKit;

namespace MacCollectionNew
{
    /// <summary>
    /// Collection view delegate handles user interaction with the elements of the
    /// collection view for the Flow-Based layout type.
    /// </summary>
    public class CollectionViewDelegate : NSCollectionViewDelegateFlowLayout
    {
        #region Computed Properties
        /// <summary>
        /// Gets or sets the parent view controller.
        /// </summary>
        /// <value>The parent view controller.</value>
        public ViewController ParentViewController { get; set; }
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="T:MacCollectionNew.CollectionViewDelegate"/> class.
        /// </summary>
        /// <param name="parentViewController">Parent view controller.</param>
        public CollectionViewDelegate(ViewController parentViewController)
        {
            // Initialize
            ParentViewController = parentViewController;
        }
        #endregion

        #region Override Methods
        /// <summary>
        /// Handles one or more items being selected.
        /// </summary>
        /// <param name="collectionView">The parent Collection view.</param>
        /// <param name="indexPaths">The Index paths of the items being selected.</param>
        public override void ItemsSelected(NSCollectionView collectionView, NSSet indexPaths)
        {
            // Dereference path
            var paths = indexPaths.ToArray<NSIndexPath>();
            var index = (int)paths[0].Item;

            // Save the selected item
            ParentViewController.PersonSelected = ParentViewController.Datasource.Data[index];

        }

        /// <summary>
        /// Handles one or more items being deselected.
        /// </summary>
        /// <param name="collectionView">The parent Collection view.</param>
        /// <param name="indexPaths">The Index paths of the items being deselected.</param>
        public override void ItemsDeselected(NSCollectionView collectionView, NSSet indexPaths)
        {
            // Dereference path
            var paths = indexPaths.ToArray<NSIndexPath>();
            var index = paths[0].Item;

            // Clear selection
            ParentViewController.PersonSelected = null;
        }
        #endregion
    }
}

ItemsSelectedItemsDeselected 方法會覆寫,並用來設定或清除PersonSelected當用戶選取或取消選取專案時,正在處理集合檢視的檢視控制器屬性。 以下將詳細說明這一點。

在介面產生器中建立集合檢視

有了所有必要的支持專案,即可編輯主分鏡腳本,並新增集合檢視。

執行下列操作:

  1. 按兩下 Main.Storyboard 方案總管 中的檔案,以開啟它,以在 Xcode 的 Interface Builder 中編輯。

  2. 將集合檢視拖曳至主要檢視,並重設大小以填滿檢視:

    將集合檢視新增至版面配置

  3. 選取 [集合檢視] 之後,請使用 [條件約束編輯器] 在調整大小時將它釘選到 [檢視]:

    顯示 [新增條件約束] 的螢幕快照。

  4. 確定已選取 [設計介面] 中的 [集合檢視] (而非包含它的框線卷動檢視剪輯檢視),切換至 [助理編輯器],並建立集合檢視的 [輸出]:

    此螢幕快照顯示您可以在其中建立輸出的助理編輯器。

  5. 儲存變更並返回Visual Studio進行同步處理。

將其全部整合在一起

現在,所有支持專案都已到位,類別可用來作為數據模型(PersonModel)、 NSCollectionViewDataSource 已新增 來提供數據、 NSCollectionViewDelegateFlowLayout 建立來處理專案選取專案,並將 NSCollectionView 新增至 Main Storyboard,並公開為出口(EmployeeCollection)。

最後一個步驟是編輯包含集合檢視的檢視控制器,並將所有片段結合在一起,以填入集合並處理專案選取專案。

ViewController.cs編輯檔案,使其看起來如下:

using System;
using AppKit;
using Foundation;
using CoreGraphics;

namespace MacCollectionNew
{
    /// <summary>
    /// The View controller controls the main view that houses the Collection View.
    /// </summary>
    public partial class ViewController : NSViewController
    {
        #region Private Variables
        private PersonModel _personSelected;
        private bool shouldEdit = true;
        #endregion

        #region Computed Properties
        /// <summary>
        /// Gets or sets the datasource that provides the data to display in the
        /// Collection View.
        /// </summary>
        /// <value>The datasource.</value>
        public CollectionViewDataSource Datasource { get; set; }

        /// <summary>
        /// Gets or sets the person currently selected in the collection view.
        /// </summary>
        /// <value>The person selected or <c>null</c> if no person is selected.</value>
        [Export("PersonSelected")]
        public PersonModel PersonSelected
        {
            get { return _personSelected; }
            set
            {
                WillChangeValue("PersonSelected");
                _personSelected = value;
                DidChangeValue("PersonSelected");
                RaiseSelectionChanged();
            }
        }
        #endregion

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="T:MacCollectionNew.ViewController"/> class.
        /// </summary>
        /// <param name="handle">Handle.</param>
        public ViewController(IntPtr handle) : base(handle)
        {
        }
        #endregion

        #region Override Methods
        /// <summary>
        /// Called after the view has finished loading from the Storyboard to allow it to
        /// be configured before displaying to the user.
        /// </summary>
        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // Initialize Collection View
            ConfigureCollectionView();
            PopulateWithData();
        }
        #endregion

        #region Private Methods
        /// <summary>
        /// Configures the collection view.
        /// </summary>
        private void ConfigureCollectionView()
        {
            EmployeeCollection.RegisterClassForItem(typeof(EmployeeItemController), "EmployeeCell");

            // Create a flow layout
            var flowLayout = new NSCollectionViewFlowLayout()
            {
                ItemSize = new CGSize(150, 150),
                SectionInset = new NSEdgeInsets(10, 10, 10, 20),
                MinimumInteritemSpacing = 10,
                MinimumLineSpacing = 10
            };
            EmployeeCollection.WantsLayer = true;

            // Setup collection view
            EmployeeCollection.CollectionViewLayout = flowLayout;
            EmployeeCollection.Delegate = new CollectionViewDelegate(this);

        }

        /// <summary>
        /// Populates the Datasource with data and attaches it to the collection view.
        /// </summary>
        private void PopulateWithData()
        {
            // Make datasource
            Datasource = new CollectionViewDataSource(EmployeeCollection);

            // Build list of employees
            Datasource.Data.Add(new PersonModel("Craig Dunn", "Documentation Manager", true));
            Datasource.Data.Add(new PersonModel("Amy Burns", "Technical Writer"));
            Datasource.Data.Add(new PersonModel("Joel Martinez", "Web & Infrastructure"));
            Datasource.Data.Add(new PersonModel("Kevin Mullins", "Technical Writer"));
            Datasource.Data.Add(new PersonModel("Mark McLemore", "Technical Writer"));
            Datasource.Data.Add(new PersonModel("Tom Opgenorth", "Technical Writer"));
            Datasource.Data.Add(new PersonModel("Larry O'Brien", "API Docs Manager", true));
            Datasource.Data.Add(new PersonModel("Mike Norman", "API Documentor"));

            // Populate collection view
            EmployeeCollection.ReloadData();
        }
        #endregion

        #region Events
        /// <summary>
        /// Selection changed delegate.
        /// </summary>
        public delegate void SelectionChangedDelegate();

        /// <summary>
        /// Occurs when selection changed.
        /// </summary>
        public event SelectionChangedDelegate SelectionChanged;

        /// <summary>
        /// Raises the selection changed event.
        /// </summary>
        internal void RaiseSelectionChanged() {
            // Inform caller
            if (this.SelectionChanged != null) SelectionChanged();
        }
        #endregion
    }
}

詳細查看此程式代碼時, Datasource 會定義 屬性來保存 CollectionViewDataSource 實例,以提供集合檢視的數據。 PersonSelected屬性的定義是保留PersonModel代表集合檢視中目前選取項目的 。 當選取範圍變更時, SelectionChanged 這個屬性也會引發 事件。

類別 ConfigureCollectionView 是用來使用下列這一行,向集合檢視註冊做為單元格原型的檢視控制器:

EmployeeCollection.RegisterClassForItem(typeof(EmployeeItemController), "EmployeeCell");

請注意,用來註冊原型的識別碼 (EmployeeCell) 符合上述所定義 方法中GetItem呼叫的CollectionViewDataSource識別碼

var item = collectionView.MakeItem("EmployeeCell", indexPath) as EmployeeItemController;
...

此外,檢視控制器的類型必須完全符合.xib定義原型的檔名。 在這裡範例和 的案例中。 EmployeeItemControllerEmployeeItemController.xib

集合檢視中項目的實際配置是由集合檢視版面配置類別所控制,而且可以在運行時間動態變更,方法是將新的實例指派給 CollectionViewLayout 屬性。 變更此屬性會更新集合檢視外觀,而不會以動畫顯示變更。

Apple 隨附兩種內建版面配置類型,其中包含將處理最典型用途的集合檢視: NSCollectionViewFlowLayoutNSCollectionViewGridLayout。 如果開發人員需要自定義格式,例如將專案配置在圓形中,他們可以建立的自定義實例 NSCollectionViewLayout ,並覆寫必要的方法,以達到所需的效果。

此範例會使用預設流程配置,因此它會建立 類別的 NSCollectionViewFlowLayout 實例,並將它設定如下:

var flowLayout = new NSCollectionViewFlowLayout()
{
    ItemSize = new CGSize(150, 150),
    SectionInset = new NSEdgeInsets(10, 10, 10, 20),
    MinimumInteritemSpacing = 10,
    MinimumLineSpacing = 10
};

屬性 ItemSize 會定義集合中每個個別儲存格的大小。 屬性 SectionInset 會從集合邊緣定義要配置儲存格的內嵌。 MinimumInteritemSpacing 定義專案之間的最小間距,並 MinimumLineSpacing 定義集合中行之間的最小間距。

配置會指派給集合檢視,而的 CollectionViewDelegate 實例會附加以處理專案選取專案:

// Setup collection view
EmployeeCollection.CollectionViewLayout = flowLayout;
EmployeeCollection.Delegate = new CollectionViewDelegate(this);

PopulateWithData方法會建立 的新實例CollectionViewDataSource,並填入數據、將它附加至集合檢視,並呼叫 ReloadData 方法來顯示專案:

private void PopulateWithData()
{
    // Make datasource
    Datasource = new CollectionViewDataSource(EmployeeCollection);

    // Build list of employees
    Datasource.Data.Add(new PersonModel("Craig Dunn", "Documentation Manager", true));
    ...

    // Populate collection view
    EmployeeCollection.ReloadData();
}

方法 ViewDidLoad 會覆寫並呼叫 ConfigureCollectionViewPopulateWithData 方法,向用戶顯示最終的集合檢視:

public override void ViewDidLoad()
{
    base.ViewDidLoad();

    // Initialize Collection View
    ConfigureCollectionView();
    PopulateWithData();
}

摘要

本文已詳細探討在 Xamarin.Mac 應用程式中使用集合檢視。 首先,它會使用索引鍵/值編碼 (KVC) 和 Key-Value Observing (KVO) 將 C# 類別公開至 Objective-C 。 接下來,它示範如何使用 KVO 相容類別,並將它系結至 Xcode 介面產生器中的集合檢視。 最後,它示範如何在 C# 程式代碼中與集合檢視互動。