Quelllisten in Xamarin.Mac
In diesem Artikel wird die Arbeit mit Quelllisten in einer Xamarin.Mac-Anwendung behandelt. Es beschreibt das Erstellen und Verwalten von Quelllisten im Xcode- und Schnittstellen-Generator und die Interaktion mit ihnen im C#-Code.
Beim Arbeiten mit C# und .NET in einer Xamarin.Mac-Anwendung haben Sie Zugriff auf die gleichen Quelllisten, in Objective-C denen ein Entwickler arbeitet und Xcode ausführt. Da Xamarin.Mac direkt in Xcode integriert ist, können Sie den Schnittstellen-Generator von Xcode verwenden, um Quelllisten zu erstellen und zu verwalten (oder sie optional direkt im C#-Code zu erstellen).
Eine Quellliste ist ein spezieller Typ von Gliederungsansicht, der verwendet wird, um die Quelle einer Aktion anzuzeigen, z. B. die Seitenleiste in Finder oder iTunes.
In diesem Artikel behandeln wir die Grundlagen der Arbeit mit Quelllisten in einer Xamarin.Mac-Anwendung. Es wird dringend empfohlen, dass Sie zuerst den Artikel "Hello, Mac " durcharbeiten, insbesondere die Abschnitte "Einführung in Xcode" und "Interface Builder " und "Outlets" und "Actions ", da es sich um wichtige Konzepte und Techniken handelt, die wir in diesem Artikel verwenden werden.
Möglicherweise möchten Sie sich auch die Verfügbarmachen von C#-Klassen /-Methoden im Objective-CAbschnitt des Xamarin.Mac Internals-Dokuments ansehen, und es werden die befehle Export
erläutert, die Register
zum Verketten Ihrer C#-Klassen mit Objective-C Objekten und UI-Elementen verwendet werden.
Einführung in Quelllisten
Wie oben erwähnt, ist eine Quellliste ein spezieller Typ von Gliederungsansicht, der verwendet wird, um die Quelle einer Aktion anzuzeigen, z. B. die Seitenleiste in Finder oder iTunes. Eine Quellliste ist ein Tabellentyp, der es dem Benutzer ermöglicht, Zeilen mit hierarchischen Daten zu erweitern oder zu reduzieren. Im Gegensatz zu einer Tabellenansicht befinden sich Elemente in einer Quellliste nicht in einer flachen Liste, sie sind in einer Hierarchie angeordnet, z. B. Dateien und Ordner auf einer Festplatte. Wenn ein Element in einer Quellliste andere Elemente enthält, kann es vom Benutzer erweitert oder reduziert werden.
Die Quellliste ist eine speziell formatierte Gliederungsansicht (NSOutlineView
), bei der es sich selbst um eine Unterklasse der Tabellenansicht (NSTableView
) handelt und als solche einen Großteil ihres Verhaltens von der übergeordneten Klasse erbt. Daher werden viele Vorgänge, die von einer Gliederungsansicht unterstützt werden, auch von einer Quellliste unterstützt. Eine Xamarin.Mac-Anwendung verfügt über die Kontrolle über diese Features und kann die Parameter der Quellliste (entweder im Code oder im Schnittstellen-Generator) konfigurieren, um bestimmte Vorgänge zuzulassen oder zu verbieten.
Eine Quellliste speichert keine eigenen Daten, sondern basiert auf einer Datenquelle (NSOutlineViewDataSource
), um sowohl die erforderlichen Zeilen als auch die erforderlichen Spalten bereitzustellen.
Das Verhalten einer Quellliste kann angepasst werden, indem eine Unterklasse des Gliederungsansichtsdelegats (NSOutlineViewDelegate
) bereitgestellt wird, um den Gliederungstyp zum Auswählen von Funktionen, Elementauswahl und -bearbeitung, benutzerdefinierten Nachverfolgung und benutzerdefinierten Ansichten für einzelne Elemente zu unterstützen.
Da eine Quellliste einen Großteil des Verhaltens und der Funktionalität mit einer Tabellenansicht und einer Gliederungsansicht teilt, sollten Sie die Dokumentation zu Tabellenansichten und Gliederungsansichten durchgehen, bevor Sie mit diesem Artikel fortfahren.
Arbeiten mit Quelllisten
Eine Quellliste ist ein spezieller Typ von Gliederungsansicht, der verwendet wird, um die Quelle einer Aktion anzuzeigen, z. B. die Seitenleiste in Finder oder iTunes. Im Gegensatz zu Gliederungsansichten erstellen wir vor dem Definieren unserer Quellliste im Schnittstellen-Generator die Sicherungsklassen in Xamarin.Mac.
Als Erstes erstellen wir eine neue SourceListItem
Klasse, um die Daten für unsere Quellliste zu enthalten. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie "Neue Datei hinzufügen>" aus... Wählen Sie "Allgemein>leere Klasse" aus, geben Sie SourceListItem
den Namen ein, und klicken Sie auf die Schaltfläche "Neu":
Stellen Sie sicher, dass die SourceListItem.cs
Datei wie folgt aussieht:
using System;
using System.Collections;
using System.Collections.Generic;
using AppKit;
using Foundation;
namespace MacOutlines
{
public class SourceListItem: NSObject, IEnumerator, IEnumerable
{
#region Private Properties
private string _title;
private NSImage _icon;
private string _tag;
private List<SourceListItem> _items = new List<SourceListItem> ();
#endregion
#region Computed Properties
public string Title {
get { return _title; }
set { _title = value; }
}
public NSImage Icon {
get { return _icon; }
set { _icon = value; }
}
public string Tag {
get { return _tag; }
set { _tag=value; }
}
#endregion
#region Indexer
public SourceListItem this[int index]
{
get
{
return _items[index];
}
set
{
_items[index] = value;
}
}
public int Count {
get { return _items.Count; }
}
public bool HasChildren {
get { return (Count > 0); }
}
#endregion
#region Enumerable Routines
private int _position = -1;
public IEnumerator GetEnumerator()
{
_position = -1;
return (IEnumerator)this;
}
public bool MoveNext()
{
_position++;
return (_position < _items.Count);
}
public void Reset()
{_position = -1;}
public object Current
{
get
{
try
{
return _items[_position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
#endregion
#region Constructors
public SourceListItem ()
{
}
public SourceListItem (string title)
{
// Initialize
this._title = title;
}
public SourceListItem (string title, string icon)
{
// Initialize
this._title = title;
this._icon = NSImage.ImageNamed (icon);
}
public SourceListItem (string title, string icon, ClickedDelegate clicked)
{
// Initialize
this._title = title;
this._icon = NSImage.ImageNamed (icon);
this.Clicked = clicked;
}
public SourceListItem (string title, NSImage icon)
{
// Initialize
this._title = title;
this._icon = icon;
}
public SourceListItem (string title, NSImage icon, ClickedDelegate clicked)
{
// Initialize
this._title = title;
this._icon = icon;
this.Clicked = clicked;
}
public SourceListItem (string title, NSImage icon, string tag)
{
// Initialize
this._title = title;
this._icon = icon;
this._tag = tag;
}
public SourceListItem (string title, NSImage icon, string tag, ClickedDelegate clicked)
{
// Initialize
this._title = title;
this._icon = icon;
this._tag = tag;
this.Clicked = clicked;
}
#endregion
#region Public Methods
public void AddItem(SourceListItem item) {
_items.Add (item);
}
public void AddItem(string title) {
_items.Add (new SourceListItem (title));
}
public void AddItem(string title, string icon) {
_items.Add (new SourceListItem (title, icon));
}
public void AddItem(string title, string icon, ClickedDelegate clicked) {
_items.Add (new SourceListItem (title, icon, clicked));
}
public void AddItem(string title, NSImage icon) {
_items.Add (new SourceListItem (title, icon));
}
public void AddItem(string title, NSImage icon, ClickedDelegate clicked) {
_items.Add (new SourceListItem (title, icon, clicked));
}
public void AddItem(string title, NSImage icon, string tag) {
_items.Add (new SourceListItem (title, icon, tag));
}
public void AddItem(string title, NSImage icon, string tag, ClickedDelegate clicked) {
_items.Add (new SourceListItem (title, icon, tag, clicked));
}
public void Insert(int n, SourceListItem item) {
_items.Insert (n, item);
}
public void RemoveItem(SourceListItem item) {
_items.Remove (item);
}
public void RemoveItem(int n) {
_items.RemoveAt (n);
}
public void Clear() {
_items.Clear ();
}
#endregion
#region Events
public delegate void ClickedDelegate();
public event ClickedDelegate Clicked;
internal void RaiseClickedEvent() {
// Inform caller
if (this.Clicked != null)
this.Clicked ();
}
#endregion
}
}
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie "Neue Datei hinzufügen>" aus... Wählen Sie "Allgemein>leere Klasse" aus, geben Sie SourceListDataSource
den Namen ein, und klicken Sie auf die Schaltfläche "Neu". Stellen Sie sicher, dass die SourceListDataSource.cs
Datei wie folgt aussieht:
using System;
using System.Collections;
using System.Collections.Generic;
using AppKit;
using Foundation;
namespace MacOutlines
{
public class SourceListDataSource : NSOutlineViewDataSource
{
#region Private Variables
private SourceListView _controller;
#endregion
#region Public Variables
public List<SourceListItem> Items = new List<SourceListItem>();
#endregion
#region Constructors
public SourceListDataSource (SourceListView controller)
{
// Initialize
this._controller = controller;
}
#endregion
#region Override Properties
public override nint GetChildrenCount (NSOutlineView outlineView, Foundation.NSObject item)
{
if (item == null) {
return Items.Count;
} else {
return ((SourceListItem)item).Count;
}
}
public override bool ItemExpandable (NSOutlineView outlineView, Foundation.NSObject item)
{
return ((SourceListItem)item).HasChildren;
}
public override NSObject GetChild (NSOutlineView outlineView, nint childIndex, Foundation.NSObject item)
{
if (item == null) {
return Items [(int)childIndex];
} else {
return ((SourceListItem)item) [(int)childIndex];
}
}
public override NSObject GetObjectValue (NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item)
{
return new NSString (((SourceListItem)item).Title);
}
#endregion
#region Internal Methods
internal SourceListItem ItemForRow(int row) {
int index = 0;
// Look at each group
foreach (SourceListItem item in Items) {
// Is the row inside this group?
if (row >= index && row <= (index + item.Count)) {
return item [row - index - 1];
}
// Move index
index += item.Count + 1;
}
// Not found
return null;
}
#endregion
}
}
Dadurch werden die Daten für unsere Quellliste bereitgestellt.
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie "Neue Datei hinzufügen>" aus... Wählen Sie "Allgemein>leere Klasse" aus, geben Sie SourceListDelegate
den Namen ein, und klicken Sie auf die Schaltfläche "Neu". Stellen Sie sicher, dass die SourceListDelegate.cs
Datei wie folgt aussieht:
using System;
using AppKit;
using Foundation;
namespace MacOutlines
{
public class SourceListDelegate : NSOutlineViewDelegate
{
#region Private variables
private SourceListView _controller;
#endregion
#region Constructors
public SourceListDelegate (SourceListView controller)
{
// Initialize
this._controller = controller;
}
#endregion
#region Override Methods
public override bool ShouldEditTableColumn (NSOutlineView outlineView, NSTableColumn tableColumn, Foundation.NSObject item)
{
return false;
}
public override NSCell GetCell (NSOutlineView outlineView, NSTableColumn tableColumn, Foundation.NSObject item)
{
nint row = outlineView.RowForItem (item);
return tableColumn.DataCellForRow (row);
}
public override bool IsGroupItem (NSOutlineView outlineView, Foundation.NSObject item)
{
return ((SourceListItem)item).HasChildren;
}
public override NSView GetView (NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item)
{
NSTableCellView view = null;
// Is this a group item?
if (((SourceListItem)item).HasChildren) {
view = (NSTableCellView)outlineView.MakeView ("HeaderCell", this);
} else {
view = (NSTableCellView)outlineView.MakeView ("DataCell", this);
view.ImageView.Image = ((SourceListItem)item).Icon;
}
// Initialize view
view.TextField.StringValue = ((SourceListItem)item).Title;
// Return new view
return view;
}
public override bool ShouldSelectItem (NSOutlineView outlineView, Foundation.NSObject item)
{
return (outlineView.GetParent (item) != null);
}
public override void SelectionDidChange (NSNotification notification)
{
NSIndexSet selectedIndexes = _controller.SelectedRows;
// More than one item selected?
if (selectedIndexes.Count > 1) {
// Not handling this case
} else {
// Grab the item
var item = _controller.Data.ItemForRow ((int)selectedIndexes.FirstIndex);
// Was an item found?
if (item != null) {
// Fire the clicked event for the item
item.RaiseClickedEvent ();
// Inform caller of selection
_controller.RaiseItemSelected (item);
}
}
}
#endregion
}
}
Dadurch wird das Verhalten unserer Quellliste bereitgestellt.
Klicken Sie abschließend im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt, und wählen Sie "Neue Datei hinzufügen>" aus... Wählen Sie "Allgemein>leere Klasse" aus, geben Sie SourceListView
den Namen ein, und klicken Sie auf die Schaltfläche "Neu". Stellen Sie sicher, dass die SourceListView.cs
Datei wie folgt aussieht:
using System;
using AppKit;
using Foundation;
namespace MacOutlines
{
[Register("SourceListView")]
public class SourceListView : NSOutlineView
{
#region Computed Properties
public SourceListDataSource Data {
get {return (SourceListDataSource)this.DataSource; }
}
#endregion
#region Constructors
public SourceListView ()
{
}
public SourceListView (IntPtr handle) : base(handle)
{
}
public SourceListView (NSCoder coder) : base(coder)
{
}
public SourceListView (NSObjectFlag t) : base(t)
{
}
#endregion
#region Override Methods
public override void AwakeFromNib ()
{
base.AwakeFromNib ();
}
#endregion
#region Public Methods
public void Initialize() {
// Initialize this instance
this.DataSource = new SourceListDataSource (this);
this.Delegate = new SourceListDelegate (this);
}
public void AddItem(SourceListItem item) {
if (Data != null) {
Data.Items.Add (item);
}
}
#endregion
#region Events
public delegate void ItemSelectedDelegate(SourceListItem item);
public event ItemSelectedDelegate ItemSelected;
internal void RaiseItemSelected(SourceListItem item) {
// Inform caller
if (this.ItemSelected != null) {
this.ItemSelected (item);
}
}
#endregion
}
}
Dadurch wird eine benutzerdefinierte, wiederverwendbare Unterklasse von NSOutlineView
(SourceListView
) erstellt, die wir verwenden können, um die Quellliste in einer beliebigen Xamarin.Mac-Anwendung zu steuern, die wir erstellen.
Erstellen und Verwalten von Quelllisten in Xcode
Als Nächstes entwerfen wir unsere Quellliste im Schnittstellen-Generator. Doppelklicken Sie auf die Main.storyboard
Datei, um sie zum Bearbeiten im Schnittstellen-Generator zu öffnen, und ziehen Sie eine geteilte Ansicht aus dem Bibliotheksinspektor, fügen Sie sie dem Ansichtscontroller hinzu, und legen Sie sie so fest, dass sie mit der Ansicht im Einschränkungs-Editor geändert wird:
Ziehen Sie als Nächstes eine Quellliste aus dem Bibliotheksinspektor, fügen Sie sie zur linken Seite der geteilten Ansicht hinzu, und legen Sie sie so fest, dass sie mit der Ansicht im Einschränkungs-Editor geändert wird:
Wechseln Sie als Nächstes zur Identitätsansicht, wählen Sie die Quellliste aus, und ändern Sie die Klasse in SourceListView
:
Erstellen Sie schließlich ein Outlet für unsere Quellliste, die in der ViewController.h
Datei aufgerufen wirdSourceList
:
Speichern Sie Ihre Änderungen, und kehren Sie zu Visual Studio für Mac zurück, um mit Xcode zu synchronisieren.
Auffüllen der Quellliste
Lassen Sie uns die RotationWindow.cs
Datei in Visual Studio für Mac bearbeiten und die AwakeFromNib
Methode wie folgt aussehen:
public override void AwakeFromNib ()
{
base.AwakeFromNib ();
// Populate source list
SourceList.Initialize ();
var library = new SourceListItem ("Library");
library.AddItem ("Venues", "house.png", () => {
Console.WriteLine("Venue Selected");
});
library.AddItem ("Singers", "group.png");
library.AddItem ("Genre", "cards.png");
library.AddItem ("Publishers", "box.png");
library.AddItem ("Artist", "person.png");
library.AddItem ("Music", "album.png");
SourceList.AddItem (library);
// Add Rotation
var rotation = new SourceListItem ("Rotation");
rotation.AddItem ("View Rotation", "redo.png");
SourceList.AddItem (rotation);
// Add Kiosks
var kiosks = new SourceListItem ("Kiosks");
kiosks.AddItem ("Sign-in Station 1", "imac");
kiosks.AddItem ("Sign-in Station 2", "ipad");
SourceList.AddItem (kiosks);
// Display side list
SourceList.ReloadData ();
SourceList.ExpandItem (null, true);
}
Die Initialize ()
Methode muss für den Ausgang der Quellliste aufgerufen werden, bevor elemente hinzugefügt werden. Für jede Gruppe von Elementen erstellen wir ein übergeordnetes Element und fügen dann die Unterelemente zu diesem Gruppenelement hinzu. Jede Gruppe wird dann der Sammlung SourceList.AddItem (...)
der Quellliste hinzugefügt. Die letzten beiden Zeilen laden die Daten für die Quellliste und erweitern alle Gruppen:
// Display side list
SourceList.ReloadData ();
SourceList.ExpandItem (null, true);
Bearbeiten Sie schließlich die AppDelegate.cs
Datei, und stellen Sie sicher, dass die DidFinishLaunching
Methode wie folgt aussieht:
public override void DidFinishLaunching (NSNotification notification)
{
mainWindowController = new MainWindowController ();
mainWindowController.Window.MakeKeyAndOrderFront (this);
var rotation = new RotationWindowController ();
rotation.Window.MakeKeyAndOrderFront (this);
}
Wenn wir unsere Anwendung ausführen, wird Folgendes angezeigt:
Zusammenfassung
Dieser Artikel hat einen detaillierten Blick auf die Arbeit mit Quelllisten in einer Xamarin.Mac-Anwendung gemacht. Wir haben erfahren, wie Sie Quelllisten im Schnittstellen-Generator von Xcode erstellen und verwalten und wie Sie mit Quelllisten im C#-Code arbeiten.