Vistas de colección en Xamarin.Mac
En este artículo se describe cómo trabajar con vistas de colección en una aplicación de Xamarin.Mac. Abarca la creación y el mantenimiento de vistas de colección en Xcode e Interface Builder y cómo trabajar con ellas mediante programación.
Al trabajar con C# y .NET en una aplicación de Xamarin.Mac, el desarrollador tiene acceso a los mismos controles de vista de colección de AppKit que un desarrollador que trabaja en Objective-C y Xcode. Dado que Xamarin.Mac se integra directamente con Xcode, el desarrollador usa Interface Builder de Xcode para crear y mantener vistas de colección.
Un NSCollectionView
muestra una cuadrícula de subvistas organizadas mediante un NSCollectionViewLayout
. Cada subvista de la cuadrícula se representa mediante un NSCollectionViewItem
que administra la carga del contenido de la vista desde un archivo .xib
.
En este artículo se describen los conceptos básicos de trabajar con vistas de colección en una aplicación de Xamarin.Mac. Se recomienda encarecidamente trabajar primero en el artículo Hello, Mac, específicamente en las secciones Introducción a Xcode e Interface Builder y Salidas y acciones, ya que trata conceptos clave y técnicas que se usan en este artículo.
Es posible que quiera echar un vistazo a la sección Exponer clases o métodos de C# a Objective-C del documento sobre Aspecto internos de Xamarin.Mac, ya que explica los comandos Register
y Export
que se usan para conectar las clases de C# a objetos Objective-C y elementos de la interfaz de usuario.
Acerca de las vistas de colección
El objetivo principal de una vista de colección (NSCollectionView
) es organizar visualmente un grupo de objetos de forma organizada mediante un diseño de vista de colección (NSCollectionViewLayout
), con cada objeto individual (NSCollectionViewItem
) obteniendo su propia vista en la colección más grande. Las vistas de colección funcionan mediante técnicas de vinculación de datos y codificación clave-valor y, como tal, debe leer la documentación sobre vinculación de datos y codificación clave-valor antes de continuar con este artículo.
La vista de colección no tiene ningún elemento de vista de colección integrado estándar (como un esquema o vista de tabla), por lo que el desarrollador es responsable de diseñar e implementar una vista prototipo con otros controles AppKit, como campos de imagen, campos de texto, etiquetas, etc. Esta vista prototipo se usará para mostrar y trabajar con cada elemento que administra la vista de colección y se almacena en un archivo .xib
.
Dado que el desarrollador es responsable de la apariencia de un elemento de vista de colección, la vista de colección no tiene compatibilidad integrada para resaltar un elemento seleccionado en la cuadrícula. La implementación de esta característica se tratará en este artículo.
Definición del modelo de datos
Antes de enlazar datos a una vista de recopilación en Interface Builder, se debe definir una clase compatible con la codificación de clave-valor (KVC)/Observación de clave-valor (KVO) en la aplicación de Xamarin.Mac para que actúe como el modelo de datos para el enlace. El modelo de datos proporciona todos los datos que se mostrarán en la colección y recibe las modificaciones de los datos que realiza el usuario en la interfaz de usuario mientras ejecuta la aplicación.
Tome el ejemplo de una aplicación que administra un grupo de empleados, se podría usar la siguiente clase para definir el modelo de datos:
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
}
}
El modelo de datos PersonModel
se usará en el resto de este artículo.
Trabajar con una vista de colección
El enlace de datos con una vista de recopilación es muy similar al enlace con una vista de tabla, ya que se usa NSCollectionViewDataSource
para proporcionar datos para la colección. Dado que la vista de colección no tiene un formato de presentación preestablecido, se requiere más trabajo para proporcionar comentarios de interacción del usuario y realizar un seguimiento de la selección del usuario.
Creación del prototipo de celda
Dado que la vista de colección no incluye un prototipo de celda predeterminado, el desarrollador deberá agregar uno o varios archivos .xib
a la aplicación Xamarin.Mac para definir el diseño y el contenido de las celdas individuales.
Haga lo siguiente:
En el Explorador de soluciones, haga clic con el botón derecho en el nombre del proyecto y seleccione Agregar>Nuevo archivo...
Seleccione Mac>Ver controlador, asígnele un nombre (como
EmployeeItem
en este ejemplo) y haga clic en el botón Nuevo para crear:Esto agregará un archivo
EmployeeItem.cs
,EmployeeItemController.cs
yEmployeeItemController.xib
a la solución del proyecto.Haga doble clic en el archivo
EmployeeItemController.xib
para abrirlo para editarlo en Interface Builder de Xcode.Agregue un
NSBox
,NSImageView
y dos controlesNSLabel
a la vista y distribúyalos de la siguiente manera:Abra el Editor del asistente y cree una Salida para el
NSBox
que se pueda usar para indicar el estado de selección de una celda:Vuelva al Editor estándar y seleccione la Vista de imagen.
En el Inspector de enlace, seleccione Enlazar a>Propietario del archivo e introduzca una ruta de acceso de clave de
self.Person.Icon
:Seleccione la primera etiqueta en el Inspector de enlace, seleccione Enlazar a>Propietario del archivo e introduzca una ruta de acceso de clave de
self.Person.Name
:Seleccione la segunda etiqueta en el Inspector de enlace, seleccione Enlazar a>Propietario del archivo e introduzca una ruta de acceso de clave de
self.Person.Occupation
:Guarde los cambios en el archivo
.xib
y vuelva a Visual Studio para sincronizar los cambios.
A continuación, edite el archivo EmployeeItemController.cs
y haga que tenga un aspecto similar al siguiente:
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
}
}
Al examinar este código con detalle, la clase hereda de NSCollectionViewItem
para que pueda actuar como prototipo para una celda vista de colección. La propiedad Person
expone la clase que se usó para enlazar datos a la vista de imágenes y etiquetas en Xcode. Se trata de una instancia del PersonModel
creado anteriormente.
La propiedad BackgroundColor
es un acceso directo al FillColor
del control NSBox
que se usará para mostrar el estado de selección de una celda. Al invalidar la propiedad Selected
del NSCollectionViewItem
, el código siguiente establece o borra este estado de selección:
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;
}
}
}
Creación del origen de datos de la vista de recopilación
Un origen de datos de vista de recopilación (NSCollectionViewDataSource
) proporciona todos los datos de una vista de recopilación y crea y rellena una celda de vista de colección (mediante el prototipo .xib
) según sea necesario para cada elemento de la colección.
Agregue una nueva clase al proyecto, llámela CollectionViewDataSource
y fíjela como la siguiente:
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
}
}
Al examinar este código con detalle, la clase hereda de NSCollectionViewDataSource
y expone una lista de instancias de PersonModel
a través de su propiedad Data
.
Puesto que esta colección solo tiene una sección, el código invalida el método GetNumberOfSections
y siempre devuelve 1
. Además, el método GetNumberofItems
se invalida en él devuelve el número de elementos de la lista de propiedades Data
.
Se llama al método GetItem
cada vez que se requiere una nueva celda y tiene un aspecto similar al siguiente:
public override NSCollectionViewItem GetItem(NSCollectionView collectionView, NSIndexPath indexPath)
{
var item = collectionView.MakeItem("EmployeeCell", indexPath) as EmployeeItemController;
item.Person = Data[(int)indexPath.Item];
return item;
}
Se llama al método MakeItem
de la vista de colección para crear o devolver una instancia reutilizable de EmployeeItemController
y su propiedad Person
se establece en el elemento que se muestra en la celda solicitada.
El EmployeeItemController
debe registrarse con el controlador de vista de colección de antemano mediante el siguiente código:
EmployeeCollection.RegisterClassForItem(typeof(EmployeeItemController), "EmployeeCell");
El identificador (EmployeeCell
) usado en la llamada MakeItem
debe coincidir con el nombre del controlador de vista que se registró con la vista de colección. Este paso se tratará en detalle a continuación.
Control de la selección de elementos
Para controlar la selección y anulación de elementos de la colección, se requerirá un NSCollectionViewDelegate
. Dado que en este ejemplo se usará el tipo de diseño integrado NSCollectionViewFlowLayout
, se requerirá una versión específica NSCollectionViewDelegateFlowLayout
de este delegado.
Agregue una nueva clase al proyecto, llámela CollectionViewDelegate
y haga que tenga un aspecto similar al siguiente:
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
}
}
Los métodos ItemsSelected
y ItemsDeselected
se invalidan y se usan para establecer o borrar la propiedad PersonSelected
del controlador de vista que controla la vista de colección cuando el usuario selecciona o anula la selección de un elemento. Esto se mostrará en detalle a continuación.
Creación de la vista de recopilación en Interface Builder
Con todas las piezas auxiliares necesarias en su lugar, el guión gráfico principal se puede editar y una vista de colección agregada a ella.
Haga lo siguiente:
Haga doble clic en el archivo
Main.Storyboard
del Explorador de soluciones para abrirlo para editarlo en Interface Builder de Xcode.Arrastre una vista de colección a la vista principal y cambie su tamaño para rellenar la vista:
Con la vista de colección seleccionada, use el Editor de restricciones para anclarla a la vista cuando se cambie el tamaño:
Asegúrese de que la vista de colección está seleccionada en la Superficie de diseño (y no la Vista de desplazamiento con borde o la Vista de clip que la contiene), cambie al Editor asistente y cree una Salida para la vista de colección:
Guarde los cambios y vuelva a Visual Studio para sincronizarlo.
Resumen
Todas las piezas auxiliares ahora se han puesto en marcha con una clase para actuar como modelo de datos (PersonModel
), se ha agregado un NSCollectionViewDataSource
para proporcionar datos, se ha creado un NSCollectionViewDelegateFlowLayout
para controlar la selección de elementos y se ha agregado un NSCollectionView
al Guión gráfico principal y se expone como una salida (EmployeeCollection
).
El último paso es editar el controlador de vista que contiene la vista de colección y reunir todas las piezas para rellenar la colección y controlar la selección de elementos.
A continuación, edite el archivo ViewController.cs
y haga que tenga un aspecto similar al siguiente:
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
}
}
Al echar un vistazo detalladamente a este código, se define una propiedad Datasource
para contener una instancia del CollectionViewDataSource
que proporcionará los datos para la vista de recopilación. Se define una propiedad PersonSelected
para contener el elemento PersonModel
que representa el elemento seleccionado actualmente en la vista colección. Esta propiedad también genera el evento SelectionChanged
cuando cambia la selección.
La clase ConfigureCollectionView
se usa para registrar el controlador de vista que actúa como prototipo de celda con la vista de colección mediante la siguiente línea:
EmployeeCollection.RegisterClassForItem(typeof(EmployeeItemController), "EmployeeCell");
Observe que el identificador (EmployeeCell
) usado para registrar el prototipo coincide con el llamado en el método GetItem
del CollectionViewDataSource
definido anteriormente:
var item = collectionView.MakeItem("EmployeeCell", indexPath) as EmployeeItemController;
...
Además, el tipo del controlador de vista debe coincidir con el nombre del archivo .xib
que define el prototipo exactamente. En el caso de este ejemplo, EmployeeItemController
y EmployeeItemController.xib
.
El diseño real de los elementos de la vista de colección se controla mediante una clase de diseño de vista de colección y se puede cambiar dinámicamente en runtime asignando una nueva instancia a la propiedad CollectionViewLayout
. Al cambiar esta propiedad, se actualiza la apariencia de la vista de colección sin animar el cambio.
Apple incluye dos tipos de diseño integrados con la vista de colección que controlará los usos más habituales: NSCollectionViewFlowLayout
y NSCollectionViewGridLayout
. Si el desarrollador necesita un formato personalizado, como colocar los elementos en un círculo, puede crear una instancia personalizada de NSCollectionViewLayout
e invalidar los métodos necesarios para lograr el efecto deseado.
En este ejemplo se usa el diseño de flujo predeterminado, por lo que crea una instancia de la clase NSCollectionViewFlowLayout
y la configura de la siguiente manera:
var flowLayout = new NSCollectionViewFlowLayout()
{
ItemSize = new CGSize(150, 150),
SectionInset = new NSEdgeInsets(10, 10, 10, 20),
MinimumInteritemSpacing = 10,
MinimumLineSpacing = 10
};
La propiedad ItemSize
define el tamaño de cada celda individual de la colección. La propiedad SectionInset
define los conjuntos desde el borde de la colección en la que se colocarán las celdas. MinimumInteritemSpacing
define el espaciado mínimo entre elementos y MinimumLineSpacing
define el espaciado mínimo entre líneas de la colección.
El diseño se asigna a la vista de colección y se adjunta una instancia del CollectionViewDelegate
para controlar la selección de elementos:
// Setup collection view
EmployeeCollection.CollectionViewLayout = flowLayout;
EmployeeCollection.Delegate = new CollectionViewDelegate(this);
El método PopulateWithData
crea una nueva instancia del CollectionViewDataSource
, la rellena con datos, la adjunta a la Vista de recopilación y llama al método ReloadData
para mostrar los elementos:
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();
}
El método ViewDidLoad
se invalida y llama a los métodos ConfigureCollectionView
y PopulateWithData
para mostrar la vista de colección final al usuario:
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Initialize Collection View
ConfigureCollectionView();
PopulateWithData();
}
Resumen
En este artículo se ha tomado un vistazo detallado al trabajo con vistas de colección en una aplicación de Xamarin.Mac. En primer lugar, examinó la exposición de una clase de C# a Objective-C mediante la codificación de clave-valor (KVC) y la observación de clave-valor (KVO). A continuación, se mostró cómo usar una clase compatible con KVO y Enlazar datos a vistas de colección en Interface Builder de Xcode. Por último, se mostró cómo interactuar con las vistas de colección en código de C#.
Vínculos relacionados
- Hello, Mac
- Enlace de datos y codificación de clave-valor
- NSCollectionView
- OS X Human Interface Guidelines (Directrices de interfaz humana de OS X)