Xamarin.Mac'teki kaynak listeler

Bu makale, Xamarin.Mac uygulamasında kaynak listelerle çalışmayı kapsar. Xcode ve Interface Builder'da kaynak listeleri oluşturmayı ve korumayı ve C# kodunda bunlarla etkileşim kurmayı açıklar.

Xamarin.Mac uygulamasında C# ve .NET ile çalışırken, ve Xcode'da çalışan bir geliştiricinin sahip olduğu Kaynak Listelerine Objective-C erişebilirsiniz. Xamarin.Mac doğrudan Xcode ile tümleştirildiği için, Kaynak Listelerinizi oluşturmak ve korumak için Xcode'un Arabirim Oluşturucusu'nu kullanabilirsiniz (veya isteğe bağlı olarak bunları doğrudan C# kodunda oluşturabilirsiniz).

Kaynak Listesi, Finder veya iTunes'daki yan çubuk gibi bir eylemin kaynağını göstermek için kullanılan özel bir Ana Hat Görünümü türüdür.

Örnek kaynak listesi

Bu makalede, Xamarin.Mac uygulamasında Kaynak Listelerle çalışmanın temellerini ele alacağız. Bu makalede kullanacağımız temel kavramları ve teknikleri kapsarken öncelikle Hello, Mac makalesi, özellikle Xcode ve Interface Builder'a Giriş ve Çıkışlar ve Eylemler bölümleriyle çalışmanız önemle önerilir.

Xamarin.Mac Internals belgesinin C# sınıflarını / yöntemlerini kullanıma alma Objective-Cbölümüne de göz atmak isteyebilirsiniz. Bu belge, C# sınıflarınızı nesnelere ve UI Öğelerine Objective-C bağlamada kullanılan ve Export komutlarını açıklar.Register

Kaynak Listelere Giriş

Yukarıda belirtildiği gibi, Kaynak Listesi, Bulucu veya iTunes'daki yan çubuk gibi bir eylemin kaynağını göstermek için kullanılan özel bir Ana Hat Görünümü türüdür. Kaynak Listesi, kullanıcının hiyerarşik veri satırlarını genişletmesine veya daraltmasına olanak tanıyan bir Tablo türüdür. Tablo Görünümünden farklı olarak, Kaynak Listesindeki öğeler düz bir listede değildir, sabit sürücüdeki dosyalar ve klasörler gibi bir hiyerarşide düzenlenir. Kaynak Listesindeki bir öğe başka öğeler içeriyorsa, bu öğe kullanıcı tarafından genişletilebilir veya daraltılabilir.

Kaynak Listesi, tablo görünümünün (NSOutlineView) alt sınıfı olan ve bu nedenle davranışının büyük bir kısmını üst sınıfından devralan özel stile sahip bir Ana Hat Görünümüdür (NSTableView ). Sonuç olarak, Ana Hat Görünümü tarafından desteklenen birçok işlem bir Kaynak Listesi tarafından da desteklenir. Xamarin.Mac uygulaması bu özelliklerin denetimine sahiptir ve Kaynak Listesi'nin parametrelerini (kodda veya Arabirim Oluşturucusu'nda) belirli işlemlere izin verecek veya izin vermeyecek şekilde yapılandırabilir.

Kaynak Listesi kendi verilerini depolamaz, bunun yerine gerekli satırları ve sütunları gerektiği gibi sağlamak için bir Veri Kaynağına (NSOutlineViewDataSource) dayanır.

Kaynak Listesi'nin davranışı, tek tek öğeler için işlevleri, öğe seçimini ve düzenlemeyi, özel izlemeyi ve özel görünümleri seçmek üzere Anahat türünü desteklemek üzere Ana Hat Görünümü Temsilcisinin (NSOutlineViewDelegate) bir alt sınıfı sağlanarak özelleştirilebilir.

Kaynak Listesi, davranışının ve işlevlerinin çoğunu Tablo Görünümü ve Ana Hat Görünümü ile paylaştığından, bu makaleye devam etmeden önce Tablo Görünümleri ve Ana Hat Görünümleri belgelerimizi gözden geçirmek isteyebilirsiniz.

Kaynak Listelerle Çalışma

Kaynak Listesi, Finder veya iTunes'daki yan çubuk gibi bir eylemin kaynağını göstermek için kullanılan özel bir Ana Hat Görünümü türüdür. Ana Hat Görünümlerinin aksine, Arabirim Oluşturucusu'nda Kaynak Listemizi tanımlamadan önce Xamarin.Mac'te yedekleme sınıflarını oluşturalım.

İlk olarak, Kaynak Listemizin verilerini tutmak için yeni SourceListItem bir sınıf oluşturalım. Çözüm Gezgini Projeye sağ tıklayın ve Yeni Dosya Ekle>... seçeneğini belirleyin. Genel>Boş Sınıf'ı seçin, Ad için girin SourceListItem ve Yeni düğmesine tıklayın:

Boş sınıf ekleme

SourceListItem.cs Dosyanın aşağıdaki gibi görünmesini sağlayın:

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

Çözüm Gezgini Projeye sağ tıklayın ve Yeni Dosya Ekle>... seçeneğini belirleyin. Genel>Boş Sınıf'ı seçin, Ad için girin SourceListDataSource ve Yeni düğmesine tıklayın. SourceListDataSource.cs Dosyanın aşağıdaki gibi görünmesini sağlayın:

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

Bu, Kaynak Listemizin verilerini sağlar.

Çözüm Gezgini Projeye sağ tıklayın ve Yeni Dosya Ekle>... seçeneğini belirleyin. Genel>Boş Sınıf'ı seçin, Ad için girin SourceListDelegate ve Yeni düğmesine tıklayın. SourceListDelegate.cs Dosyanın aşağıdaki gibi görünmesini sağlayın:

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

Bu, Kaynak Listemizin davranışını sağlar.

Son olarak, Çözüm Gezgini Projeye sağ tıklayın ve Yeni Dosya Ekle>... öğesini seçin. Genel>Boş Sınıf'ı seçin, Ad için girin SourceListView ve Yeni düğmesine tıklayın. SourceListView.cs Dosyanın aşağıdaki gibi görünmesini sağlayın:

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

Bu, yaptığımız herhangi bir Xamarin.Mac uygulamasında Kaynak Listesi'ni kullanmak için kullanabileceğimiz () özel, yeniden kullanılabilir bir alt sınıfı NSOutlineViewSourceListViewoluşturur.

Xcode'da Kaynak Listeleri Oluşturma ve Koruma

Şimdi Interface Builder'da Kaynak Listemizi tasarlayalım. Arabirim Oluşturucusu'nda düzenlemek üzere açmak üzere dosyaya çift tıklayın Main.storyboard ve Kitaplık Denetçisi'nden Bölünmüş Görünüm'ü sürükleyin, Görünüm Denetleyicisi'ne ekleyin ve Kısıtlama Düzenleyicisi'ndeki Görünüm ile yeniden boyutlandıracak şekilde ayarlayın:

Arabirim Oluşturucusu'nda kısıtlamalar düzenleniyor.

Ardından, Kitaplık Denetçisi'nden bir Kaynak Listesi sürükleyin, Bölünmüş Görünümün sol tarafına ekleyin ve Kısıtlama Düzenleyicisi'ndeki Görünümle yeniden boyutlandıracak şekilde ayarlayın:

Kaynak Listeyi Bölünmüş Görünüme sürükleyerek kısıtlamaları düzenleme.

Ardından Kimlik Görünümü'ne geçin, Kaynak Liste'yi seçin ve Sınıfı SourceListViewolarak değiştirin:

Sınıf adını ayarlama

Son olarak, dosyada ViewController.h adlı SourceList Kaynak Listemiz için bir Çıkış oluşturun:

Çıkış Yapılandırma

Değişikliklerinizi kaydedin ve Xcode ile eşitlemek için Mac için Visual Studio dönün.

Kaynak Listeyi Doldurma

Şimdi dosyayı Mac için Visual Studio'de düzenleyelim RotationWindow.cs ve yönteminin aşağıdaki gibi görünmesini sağlayalımAwakeFromNib:

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

}

Herhangi Initialize () bir öğe eklenmeden önce yöntemin Kaynak Listemizin Çıkışında çağrılmış olması gerekir. Her öğe grubu için bir üst öğe oluşturur ve sonra alt öğeleri bu grup öğesine ekleriz. Ardından her grup Kaynak Listesi'nin koleksiyonuna SourceList.AddItem (...)eklenir. Son iki satır Kaynak Listesi için verileri yükler ve tüm grupları genişletir:

// Display side list
SourceList.ReloadData ();
SourceList.ExpandItem (null, true);

Son olarak, dosyayı düzenleyin AppDelegate.cs ve yönteminin aşağıdaki gibi görünmesini sağlayın DidFinishLaunching :

public override void DidFinishLaunching (NSNotification notification)
{
    mainWindowController = new MainWindowController ();
    mainWindowController.Window.MakeKeyAndOrderFront (this);

    var rotation = new RotationWindowController ();
    rotation.Window.MakeKeyAndOrderFront (this);
}

Uygulamamızı çalıştırırsak aşağıdakiler görüntülenir:

Örnek bir uygulama çalıştırması

Özet

Bu makalede, Xamarin.Mac uygulamasında Kaynak Listeleriyle çalışma konusuna ayrıntılı bir bakış verilmişti. Xcode'un Arabirim Oluşturucusu'nda Kaynak Listeleri oluşturmayı ve korumayı ve C# kodunda Kaynak Listelerle çalışmayı gördük.