Xamarin.MacのNSTableViewでNSTableViewSourceを使う

提供: MonoBook
2015年3月23日 (月) 06:47時点における153.220.119.198 (トーク)による版 (→‎実装1)
ナビゲーションに移動 検索に移動

実装1

Xamarin.MacにはNSTableViewSourceというNSTableViewを簡単に扱うための便利クラスがあるようだ。

準備

まずはソースの元(テーブルの1行)となるクラスを用意する。

    public class Study
    {
        public string Id { get; set; }
        public string Name { get; set; }
    }

データソースの用意

次にデータソースを用意する。 NSTableViewSourceクラスを継承してGetRowCountメソッドとGetObjectValueメソッドをオーバーライドすることで利用可能な状態となる。

この例ではNSTableColumnクラスのIdentifierプロパティの値と、前述のStudyクラスの各プロパティ名でマッピングを行っている。 NSTableColumnクラスのIdentifierプロパティはInterface Builderで設定した。

また、別途IList<>インターフェースを実装しておくとLINQで操作できたり色々便利だった。無くてもよい。

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Reflection;

    using Foundation;
    using AppKit;

    public class StudyTableViewSource : NSTableViewSource, IList<Study>
    {
        IList<Study> _items = new List<Study>();

        public override int GetRowCount(NSTableView tableView)
        {
            return _items.Count;
        }

        public override NSObject GetObjectValue(NSTableView tableView, NSTableColumn tableColumn, int row)
        {
            if (tableColumn.Identifier == null)
            {
                return null;
            }

            var item = _items[row];
            var type = typeof(Study);
            var prop = type.GetProperty(tableColumn.Identifier, BindingFlags.Public | BindingFlags.Instance);
            if (prop == null)
            {// そんな名前のプロパティはない
                return null;
            }

            var val = prop.GetValue(item);
            if (val == null)
            {// 空っぽですわ
                return null;
            }

            var ret = new NSString(val.ToString());
            return ret;
        }

        //  〜以下略〜
    }

使ってみる

早速使ってみる。

この例では

  • Interface BuilderでMainWindow.xibファイルを開き、
  • NSTableViewを貼り付け、
  • Content Modeを「View Based」に設定し、
  • アウトレットは「_studyTableView」という名前にしておいた。
    public partial class MainWindowController : NSWindowController
    {
        // 〜前略〜

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

            var studies = new StudyTableViewSource();
            studies.Add(new Study { Id = "A1", Name = "B1" });
            studies.Add(new Study { Id = "A2", Name = "B2" });
            studies.Add(new Study { Id = "A3", Name = "B3" });
            studies.Add(new Study { Id = "A4", Name = "B4" });
            _studyTableView.Source = studies;
        }
    }

なんと、この状態で実行するとテーブルの表示はされるが、クリックしても行選択ができない。

行選択

これで良いのか知らんが以下で行選択が出来るようになった。

        public override void WindowDidLoad()
        {
            // 〜前略〜

            _studyTableView.Activated += (object sender, EventArgs e) => {
                var tableview = (NSTableView)sender;
                int clickedrow = (int)tableview.ClickedRow;
                tableview.SelectRow(clickedrow, false);
                tableview.ScrollRowToVisible(clickedrow);
            };
        }

関連項目

参考文献