Xamarin.Mac'te kaynak listeleri

Bu makale bir Xamarin.Mac uygulamasında kaynak listelerle çalışmayı kapsar. Bu makalede Xcode'da kaynak listeleri oluşturma ve bunları koruma Interface Builder C# kodunda bu listelerle etkileşim kurma ve bu listelerle etkileşim kurma açıkları yer almaktadır.

Bir Xamarin.Mac uygulamasında C# ve .NET ile çalışırken, ve Xcode'da çalışan bir geliştiricinin sahip olduğu Kaynak Listelerine erişiminiz Objective-C vardır. Objective-C Xamarin.Mac doğrudan Xcode ile tümleşik olduğundan, Kaynak Listelerinizi oluşturmak ve korumak için Xcode'un Interface Builder'sini kullanabilirsiniz (veya isteğe bağlı olarak bunları doğrudan C# kodunda oluşturabilirsiniz).

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

Örnek bir kaynak listesi

Bu makalede, bir Xamarin.Mac uygulamasında Kaynak Listeleriyle çalışmayla ilgili temel bilgileri açıklayabilirsiniz. Öncelikle Hello, Mac makalesi, özellikle de Xcode'a giriş ve Interface Builder ve Çıkışlar ve Eylemler bölümlerine bakarak bu makalede kullanacaklarımız temel kavramları ve teknikleri gözden geçirin.

Exposing C# classes / methods to Objective-CExposing C# classes / methods to Objective-C belgesinin C# sınıflarınızı nesnelere ve KULLANıCı Arabirimi Öğelerine kablolamak için kullanılan ve komutlarını da açıklayan bölümüne göz RegisterExportObjective-C atabilirsiniz.

Kaynak Listelerine Giriş

Yukarıda belirtildiği gibi, Kaynak Listesi, Finder veya iTunes'daki kenar çubuğu gibi bir eylemin kaynağını göstermek için kullanılan özel bir Ana Hat Görünümü t t'tir. Kaynak Listesi, kullanıcının hiyerarşik veri satırlarını genişletmesini veya daraltması için bir Tablo tablonundandır. Tablo Görünümünden farklı olarak, Kaynak Listesi'nde yer alan öğeler düz bir listede değildir, sabit sürücüdeki dosyalar ve klasörler gibi bir hiyerarşide düzenlenir. Kaynak Listesinde yer alan bir öğe başka öğeler içeriyorsa, kullanıcı tarafından genişletilebilir veya daraltılmış olabilir.

Kaynak Listesi, tablo görünümünün ( ) bir alt sınıfı olan ve bu nedenle davranışının büyük birını üst sınıfından devralan, özel olarak stile sahip bir Ana Hat Görünümü ' tür ( NSOutlineViewNSTableView ). Sonuç olarak, Ana Hat Görünümü tarafından desteklenen birçok işlem bir Kaynak Listesi tarafından da de desteklemektedir. Xamarin.Mac uygulaması bu özellikler üzerinde denetime sahiptir ve Kaynak Listesinin parametrelerini (kodda veya Interface Builder) belirli işlemlere izin verecek veya izin vermayacak şekilde yapılandırabilir.

Kaynak Listesi kendi verilerini depolamaz, bunun yerine gereken satırları ve sütunları gereken şekilde sağlamak için bir Veri Kaynağı ( NSOutlineViewDataSource ) kullanılır.

Tek tek öğeler için işlevsellik, öğe seçimi ve düzenleme, özel izleme ve özel görünümler seçmek üzere Ana hat türünü desteklemek üzere Ana Hat Görünümü Temsilcisinin ( ) bir alt sınıfı sağlayarak Kaynak Listesinin davranışı NSOutlineViewDelegate özelleştirilebilir.

Kaynak Listesi, davranışların ve işlevlerin büyük bir bölümü bir Tablo Görünümü ve Ana Hat Görünümü ile paylaşıldıklarından, bu makaleye devam etmeden önce Tablo Görünümlerini ve Ana Hat Görünümlerini belgelerimize göz atabilirsiniz.

Kaynak Listeleriyle Çalışma

Kaynak Listesi, Finder veya iTunes'daki kenar çubuğu gibi bir eylemin kaynağını göstermek için kullanılan özel bir Ana Hat Görünümü t t'tir. Ana Hat Görünümleri'nin aksine, kaynak listemizi Interface Builder Xamarin.Mac'te destek sınıfları oluşturabilirsiniz.

İlk olarak, Kaynak Listemizin SourceListItem verilerini tutmak için yeni bir sınıf oluşturuz. Dosya Çözüm Gezginisağ tıklayın ve yeni Project Ekle... öğesiniseçin. Genel BoşSınıf'ıseçin, Ad alanına girin ve Yeni düğmesine tıklayın:

Boş bir sınıf ekleme

Dosyayı SourceListItem.cs aşağıdaki gibi yapı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
    }
}

Dosya Çözüm Gezginisağ tıklayın ve yeni Project Ekle... öğesiniseçin. Genel BoşSınıf'ıseçin, Ad alanına girin ve Yeni düğmesine tıklayın. Dosyayı SourceListDataSource.cs aşağıdaki gibi yapı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.

Dosya Çözüm Gezginisağ tıklayın ve yeni Project Ekle... öğesiniseçin. Genel BoşSınıf'ıseçin, Ad alanına girin ve Yeni düğmesine tıklayın. Dosyayı SourceListDelegate.cs aşağıdaki gibi yapı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 Gezginisağ tıklayın ve Project Ekle... öğesiniseçin. Genel BoşSınıf'ıseçin, Ad alanına girin ve Yeni düğmesine tıklayın. Dosyayı SourceListView.cs aşağıdaki gibi yapı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, oluşturduğumız herhangi bir NSOutlineView Xamarin.Mac uygulamasında Kaynak Listesini oluşturmak için kullanabileceğimiz özel, yeniden kullanılabilir bir alt sınıfı ( SourceListView ) oluşturur.

Xcode'da Kaynak Listeleri Oluşturma ve Koruma

Şimdi Kaynak Listemizi Interface Builder. Dosyada düzenlemek için dosyaya çift tıklayın Interface Builder Kitaplık Denetçisi'nde bir Bölünmüş Görünüm sürükleyin, Görünüm Denetleyicisi'ne ekleyin ve Kısıtlama Düzenleyicisi'nde Görünüm ile yeniden boyutlandırmak Main.storyboardiçin ayarlayın:Main.storyboard

Uygulamadaki kısıtlamaları Interface Builder.

Ardından, Kitaplık Denetçisi'nde bir Kaynak Listesi sürükleyin,Bölme Görünümünün sol tarafına ekleyin ve Kısıtlama Düzenleyicisi'nde Görünüm ile yeniden boyutlandırmak için ayarlayın:

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

Ardından Kimlik Görünümü'ne geçerekKaynak Listesini seçin ve Sınıf'ı olarak değiştirerek:

Sınıf adını ayarlama

Son olarak, kaynak listemiz için dosyasında adlı bir Çıkış ViewController.h oluşturun:

Çıkış Yapılandırma

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

Kaynak Listesini Doldurmak

Şimdi dosyayı RotationWindow.cs dosyanın Mac için Visual Studio yönteminin aşağıdaki AwakeFromNib gibi bir görünüme uygun hale gelebilirsiniz:

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 Initialize () listesinde çağrılmalıdır. Her öğe grubu için bir üst öğe oluşturun ve ardından alt öğeleri bu grup öğesine ekleyin. Her grup daha sonra Kaynak Listesinin koleksiyonuna SourceList.AddItem (...) eklenir. Son iki satır Kaynak Listesi verilerini yükleyecek ve tüm grupları genişletecek:

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

Son olarak, AppDelegate.cs dosyasını düzenleyin ve yöntemini aşağıdaki gibi DidFinishLaunching yapın:

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ıracak olursanız aşağıdakiler görüntülenir:

Örnek uygulama çalıştırması

Özet

Bu makale, Xamarin.Mac uygulamasında Kaynak Listeleri ile çalışmaya ayrıntılı bir bakış sağlar. Xcode'un belgelerinde Kaynak Listeleri oluşturma ve koruma Interface Builder C# kodunda Kaynak Listeleri ile nasıl çalışabilirsiniz?