Zobrazení kolekcí v Xamarin. Mac

Tento článek popisuje práci s pohledy na shromažďování v aplikaci Xamarin. Mac. Zahrnuje vytváření a správu zobrazení kolekcí v Xcode a Interface Builder a práci s nimi prostřednictvím kódu programu.

Při práci s C# a .NET v aplikaci Xamarin. Mac má vývojář přístup ke stejnému zobrazení kolekce Appkitu, že vývojář pracuje v Objective-C a Objective-C . Protože se Xamarin. Mac integruje přímo s Xcode, vývojář používá Interface Builder Xcode k vytváření a udržování zobrazení kolekcí.

NSCollectionViewZobrazí mřížku podzobrazení uspořádaných pomocí NSCollectionViewLayout . Každé dílčí zobrazení v mřížce je reprezentované, NSCollectionViewItem které spravuje načítání obsahu zobrazení ze .xib souboru.

Příklad spuštění aplikace

Tento článek popisuje základy práce s pohledy na shromažďování v aplikaci Xamarin. Mac. Důrazně doporučujeme, abyste nejprve pracovali v článku Hello, Mac , konkrétně v částech Úvod k Xcode a Interface Builder a akcím , které se týkají klíčových konceptů a postupů, které se používají v celém rámci tohoto článku.

Můžete se podívat i na část dokumentu s dalšími Exposing C# classes / methods to Objective-CExposing C# classes / methods to Objective-C a vysvětluje RegisterExport příkazy a používané k navýšení tříd jazyka C# do Objective-C objektů a prvků uživatelského rozhraní.

O zobrazeních kolekce

Hlavním cílem zobrazení kolekce ( NSCollectionView ) je vizuálně uspořádat skupinu objektů uspořádaným způsobem pomocí rozložení zobrazení kolekce ( NSCollectionViewLayout ), přičemž každý jednotlivý objekt ( NSCollectionViewItem ) získá vlastní zobrazení ve větší kolekci. Zobrazení kolekcí fungují prostřednictvím datových vazeb a Key-Value techniky kódování a jako takové si měli před pokračováním v tomto článku přečíst dokumentaci pro vytváření datových vazeb a Key-Value kódování .

Zobrazení kolekce nemá žádnou standardní, vestavěnou položku zobrazení kolekce (jako je například osnova nebo zobrazení tabulky), takže vývojář zodpovídá za návrh a implementaci zobrazení prototypu pomocí jiných ovládacích prvků appkitu, jako jsou například pole obrázků, textová pole, popisky atd. Toto zobrazení prototypu se použije k zobrazení a práci s každou položkou spravovanou zobrazením kolekce a je uložená v souboru.

Vzhledem k tomu, že vývojář zodpovídá za vzhled a chování položky zobrazení kolekce, nemá zobrazení kolekce žádnou vestavěnou podporu pro zvýraznění vybrané položky v mřížce. Implementace této funkce bude popsaná v tomto článku.

Definování datového modelu

Před vytvořením datové vazby zobrazení kolekce v Interface Builder musí být v aplikaci Xamarin. Mac definovaná třída/Key-Valueing (KVO) Key-Value, která má sloužit jako datový model pro vazbu. Datový model poskytuje všechna data, která se zobrazí v kolekci, a přijímá jakékoli úpravy dat, která uživatel v uživatelském rozhraní provádí při spuštění aplikace.

Vezměte v úvahu příklad aplikace, která spravuje skupinu zaměstnanců. k definování datového modelu se dá použít následující třída:

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

PersonModelDatový model bude použit v celém zbytku tohoto článku.

Práce se zobrazením kolekce

Datová vazba s zobrazením kolekce je velmi podobná vazbě s tabulkovým zobrazením, jak NSCollectionViewDataSource je použito k poskytnutí dat pro kolekci. Vzhledem k tomu, že zobrazení kolekce nemá nastavený formát zobrazení, je potřeba více práce, aby se zajistila zpětná vazba interakce s uživatelem a sledování výběru uživatele.

Vytváření prototypu buňky

Vzhledem k tomu, že zobrazení kolekce neobsahuje výchozí prototyp buňky, vývojář bude muset do .xib aplikace Xamarin. Mac přidat jeden nebo více souborů, aby bylo možné definovat rozložení a obsah jednotlivých buněk.

Postupujte následovně:

  1. V Průzkumník řešeníklikněte pravým tlačítkem myši na název projektu a vyberte možnost Přidatnový soubor...

  2. Vyberte MacView Controller, přiřaďte mu název (například v tomto příkladu) a kliknutím na tlačítko Nový vytvořte:

    Přidává se nový kontroler zobrazení.

    Tím se EmployeeItem.csEmployeeItemController.csEmployeeItemController.xib do řešení projektu přidá soubor a.

  3. Dvojím kliknutím na EmployeeItemController.xib soubor ho otevřete pro úpravy v Interface Builder Xcode.

  4. Přidejte NSBoxNSImageView do zobrazení a dva NSLabel ovládací prvky a rozložte je následujícím způsobem:

    Návrh rozložení prototypu buňky

  5. Otevřete Editor pomocníka a vytvořte výstup pro, aby se mohl použít k označení stavu výběru buňky:

    Vystavení NSBox ve výstupu

  6. Vraťte se ke standardnímu editoru a vyberte zobrazení obrázku.

  7. V inspektoru vazbyvyberte možnost svázat svlastníkem souboru a zadejte cestu k klíčovému modelu :

    Svázání ikony

  8. Vyberte první popisek a v inspektoru vazbyvyberte svázat svlastníkem souboru a zadejte cestu k klíčovému modelu :

    Vytvoření vazby názvu

  9. Vyberte druhý popisek a v inspektoru vazbyvyberte svázat svlastníkem souboru a zadejte cestu k klíčovému modelu :

    Vytvoření vazby na povolání

  10. uložte změny do .xib souboru a vraťte se do Visual Studio a synchronizujte změny.

Upravte EmployeeItemController.cs soubor a nastavte jeho vzhled jako na následující:

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

Podrobné prohlížení tohoto kódu, třída dědí z, NSCollectionViewItem takže může fungovat jako prototyp pro buňku zobrazení kolekce. PersonVlastnost zpřístupňuje třídu, která byla použita k vytvoření vazby dat k zobrazení obrázku a popiskům v Xcode. Toto je instance PersonModel vytvořená výše.

BackgroundColorVlastnost je zástupce NSBox ovládacího prvku FillColor , který bude použit k zobrazení stavu výběru buňky. Přepsáním Selected vlastnosti NSCollectionViewItem , následující kód nastaví nebo vymaže tento stav výběru:

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

Vytváření zdroje dat zobrazení kolekce

Zdroj dat zobrazení kolekce ( NSCollectionViewDataSource ) poskytuje všechna data pro zobrazení kolekce a vytvoří a naplní buňku zobrazení kolekce (pomocí .xib prototypu) podle požadavku pro každou položku v kolekci.

Přidejte do projektu novou třídu, zavolejte ji CollectionViewDataSource a nastavte ji jako následující:

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

Podrobné prohlížení tohoto kódu, třída dědí z NSCollectionViewDataSource a zpřístupňuje seznam PersonModel instancí prostřednictvím své Data Vlastnosti.

Vzhledem k tomu, že tato kolekce má pouze jeden oddíl, kód přepíše GetNumberOfSections metodu a vždy vrátí 1 . Kromě toho GetNumberofItems je metoda přepsána, vrátí počet položek v Data seznamu vlastností.

GetItemMetoda je volána vždy, když je vyžadována nová buňka a vypadá takto:

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

    return item;
}

MakeItemMetoda zobrazení kolekce je volána k vytvoření nebo vrácení opakovaně použitelné instance EmployeeItemController a její Person vlastnost je nastavena na položku zobrazenou v požadované buňce.

Rozhraní EmployeeItemController musí být registrováno v kontroleru zobrazení kolekce předem pomocí následujícího kódu:

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

Identifikátor ( ) použitý v MakeItem volání MakeItem odpovídat názvu kontroleru zobrazení, který byl zaregistrován v zobrazení kolekce. Tento krok se podrobněji popisuje níže.

Zpracování výběru položky

Aby bylo možné zpracovat výběr a zrušit výběr položek v kolekci, NSCollectionViewDelegate bude vyžadován. Vzhledem k tomu, že tento příklad bude používat vestavěný NSCollectionViewFlowLayout Typ rozložení, NSCollectionViewDelegateFlowLayout bude nutné zadat konkrétní verzi tohoto delegáta.

Přidejte do projektu novou třídu, zavolejte ji CollectionViewDelegate a nastavte ji tak, aby vypadala takto:

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

ItemsSelectedMetody a ItemsDeselected jsou přepsány a použity k nastavení nebo zrušení PersonSelected vlastnosti kontroleru zobrazení, který zpracovává zobrazení kolekce, když uživatel vybere nebo zruší výběr položky. Tato informace se zobrazí podrobněji.

Vytváření zobrazení kolekce v Interface Builder

U všech požadovaných podpůrných dílů je možné upravit hlavní scénář a přidat do něj zobrazení kolekce.

Postupujte následovně:

  1. Dvojím kliknutím na Main.Storyboard soubor v Main.Storyboard ho otevřete pro úpravy v Interface Builder Xcode.

  2. Přetáhněte zobrazení kolekce do hlavního zobrazení a změňte jeho velikost tak, aby se toto zobrazení vyplnilo:

    Přidání zobrazení kolekce do rozložení

  3. Když je vybrané zobrazení kolekce, použijte Editor omezení k jeho připnutí do zobrazení při změně velikosti:

    Snímek obrazovky ukazuje přidat nová omezení.

  4. Zajistěte, aby bylo v návrhová plocha vybráno zobrazení kolekce (nikoli zobrazení ohraničené posuvníkem nebo zobrazením klipu , které ho obsahuje), přepněte do editoru pomocníka a vytvořte výstup pro zobrazení kolekce:

    Snímek obrazovky se zobrazí v editoru pomocníka, kde můžete vytvořit zásuvku.

  5. uložte změny a vraťte se do Visual Studio k synchronizaci.

Společné přenesení

Všechny doprovodné součásti byly nyní vloženy do třídy, která má sloužit jako datový model ( PersonModel ), byl NSCollectionViewDataSource přidán pro zadávání dat, NSCollectionViewDelegateFlowLayout byl vytvořen pro zpracování výběru položek a NSCollectionView byl přidán do hlavního scénáře a vystavený jako zásuvka ( EmployeeCollection ).

Posledním krokem je upravit kontroler zobrazení, který obsahuje zobrazení kolekce, a přenést všechny části dohromady k naplnění kolekce a zpracování výběru položek.

Upravte ViewController.cs soubor a nastavte jeho vzhled jako na následující:

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

Podívá se na tento kód podrobněji. Datasource vlastnost je definována tak, aby obsahovala instanci CollectionViewDataSource , která bude poskytovat data pro zobrazení kolekce. PersonSelectedVlastnost je definována tak, aby obsahovala PersonModel reprezentující aktuálně vybranou položku v zobrazení kolekce. Tato vlastnost také vyvolá SelectionChanged událost při změně výběru.

ConfigureCollectionViewTřída se používá k registraci kontroleru zobrazení, který funguje jako prototyp buňky, pomocí zobrazení kolekce s použitím následujícího řádku:

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

Všimněte si, že identifikátor ( ) použitý k registraci prototypu odpovídá metodě, která je volána v GetItem metodě CollectionViewDataSource definované výše:

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

Navíc musí typ kontroleru zobrazení odpovídat názvu souboru, který definuje prototyp přesně. V případě tohoto příkladu EmployeeItemController a EmployeeItemController.xib .

Skutečné rozložení položek v zobrazení kolekce je řízeno třídou rozložení zobrazení kolekce a lze je dynamicky měnit za běhu, a to tak, že do vlastnosti přiřadíte novou instanci CollectionViewLayout . Změna této vlastnosti aktualizuje vzhled zobrazení kolekce bez animace změny.

Společnost Apple dodává dva předdefinované typy rozložení se zobrazením kolekce, které bude zpracovávat nejčastěji používané účely: NSCollectionViewFlowLayout a NSCollectionViewGridLayout . Pokud vývojář požaduje vlastní formát, jako je například navýšení položek v kruhu, může vytvořit vlastní instanci NSCollectionViewLayout a přepsat požadované metody, aby dosáhli požadovaného efektu.

Tento příklad používá výchozí rozložení toku, takže vytvoří instanci NSCollectionViewFlowLayout třídy a nakonfiguruje ji takto:

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

ItemSizeVlastnost definuje velikost každé jednotlivé buňky v kolekci. SectionInsetVlastnost definuje inmnožiny od okraje kolekce, do které budou buňky rozloženy. MinimumInteritemSpacing definuje minimální mezery mezi položkami a definuje minimální mezery mezi řádky MinimumLineSpacing v kolekci.

Rozložení je přiřazeno zobrazení kolekce a instance je připojena ke CollectionViewDelegate zpracování výběru položky:

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

Metoda vytvoří novou instanci objektu , naplní ji daty, připojí ji k zobrazení kolekce a zavolá metodu pro PopulateWithDataCollectionViewDataSource zobrazení ReloadData položek:

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

Metoda se přepíše a zavolá metody a , aby se uživateli zobrazí konečné zobrazení ViewDidLoadConfigureCollectionViewPopulateWithData kolekce:

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

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

Souhrn

Tento článek podrobně popisuje práci se zobrazeními kolekcí v aplikaci Xamarin.Mac. Nejprve se podíval na vystavení třídy C# pro pomocí Objective-C KVC (Key-Value Coding) a KVO (Key-Value Observing). Dále se ukázalo, jak používat třídu kompatibilní s KVO a datovou vazbu na zobrazení kolekce v Interface Builder Xcode. Nakonec ukázal, jak pracovat se zobrazeními kolekcí v kódu jazyka C#.