この記事では、Xamarin.Mac アプリケーションでのアウトライン ビューの使用について説明しています。 Xcode および Interface Builder でのアウトライン ビューの作成と保守、およびプログラムによる操作について説明します。
Xamarin.Mac アプリケーションで C# と .NET を使用している場合、Objective-C や Xcode で開発者が使用しているのと同じアウトライン ビューにアクセスできます。 Xamarin.Mac は直接 Xcode と統合できるため、Xcode の Interface Builder を使用して、アウトライン ビューを作成および管理できます (または、必要に応じて、C# コードで直接作成することもできます)。
アウトライン ビューとは、ユーザーが階層データの行を展開または折りたたむことができるテーブルの一種です。 テーブル ビューと同様に、アウトライン ビューには一連の関連項目のデータが表示されます。行は個々の項目を表し、列はそれらの項目の属性を表します。 テーブル ビューとは異なり、アウトライン ビュー内の項目はフラット リストに含まれていないため、ハード ドライブ上のファイルやフォルダーなどの階層に編成されます。
この記事では、Xamarin.Mac アプリケーションでのアウトライン ビューの使用の基本について説明します。 まずは、Hello Mac に関する記事を参照することを強くお勧めします。特に、この記事で使用する主要な概念と手法について説明している「Xcode と Interface Builder の概要」セクションと「Outlet と Action」セクションを参照してください。
Xamarin.Mac Internals ドキュメントの「C# クラス/メソッドの Objective-C への公開」セクションも参照することをお勧めします。C# クラスを Objective-C オブジェクトと UI 要素に結び付けるために使われる Register および Export コマンドについて説明されています。
アウトライン ビューの概要
アウトライン ビューとは、ユーザーが階層データの行を展開または折りたたむことができるテーブルの一種です。 テーブル ビューと同様に、アウトライン ビューには一連の関連項目のデータが表示されます。行は個々の項目を表し、列はそれらの項目の属性を表します。 テーブル ビューとは異なり、アウトライン ビュー内の項目はフラット リストに含まれていないため、ハード ドライブ上のファイルやフォルダーなどの階層に編成されます。
アウトライン ビュー内の項目に他の項目が含まれている場合は、ユーザーが展開または折りたたむことができます。 展開可能な項目には、開閉用の三角形が表示されます。これは、項目が折りたたまれている場合は右を指し、項目が展開されている場合は下を指すます。 開閉用の三角形をクリックすると、項目が展開または折りたたまれます。
アウトライン ビュー (NSOutlineView) は、テーブル ビュー (NSTableView) のサブクラスであるため、その動作の多くを親クラスから継承します。 その結果、行または列の選択、列ヘッダーのドラッグによる列の再配置など、テーブル ビューでサポートされる多くの操作がアウトライン ビューでもサポートされます。 Xamarin.Mac アプリケーションは、これらの機能を制御でき、アウトライン ビューのパラメータ (コードまたは Interface Builder) を構成して、特定の操作を許可または禁止できます。
アウトライン ビューは、独自のデータを格納するのではなく、必要に応じて必要な行と列の両方を提供するデータ ソース (NSOutlineViewDataSource) に依存しています。
アウトライン ビューの動作をカスタマイズするには、アウトライン列の管理、機能選択の種類、行の選択と編集、カスタム追跡、個々の列と行のカスタム ビューをサポートするアウトライン ビュー デリゲート (NSOutlineViewDelegate) のサブクラスを指定します。
アウトライン ビューは、多くの動作と機能をテーブル ビューと共有しているため、この記事を読み進める前に、テーブル ビューのドキュメントを参照することをお勧めします。
Xcode でのアウトライン ビューの作成と管理
新しい Xamarin.Mac Cocoa アプリケーションを作成すると、既定で標準の空白のウィンドウが表示されます。 このウィンドウは、プロジェクトに自動的に含まれる .storyboard ファイルで定義されます。 Windows デザインを編集するには、ソリューション エクスプローラーで、Main.storyboard ファイルをダブルクリックします:
これにより、Xcode の Interface Builder でウィンドウ デザインが開きます:
Library Inspector の検索ボックスに「outline」と入力すると、アウトライン ビュー コントロールを見つけやすくなります。
アウトライン ビューを Interface Editor の View Controller にドラッグし、View Controller のコンテンツ領域を塗りつぶし、それを Constraint Editor のウィンドウで縮小拡大する場所に設定します。
Interface Hierarchy でアウトライン ビューを選択すると、Attribute Inspector で次のプロパティを使用できます。
- Outline Column - 階層データが表示されるテーブル列。
- Autosave Outline Column -
trueの場合、アウトライン列は自動的に保存され、次回のアプリケーションの実行時にも維持されます。 - Indentation - 展開された項目の下の列をインデントする量。
- Indentation Follows Cells -
trueの場合、インデント マークはセルに合わせてインデントされます。 - Autosave Expanded Items -
trueの場合、項目の展開/折りたたみ状態は自動的に保存され、次回のアプリケーションの実行時にも維持されます。 - Content Mode - ビュー (
NSView) またはセル (NSCell) を使用して、行や列にデータを表示できます。 macOS 10.7 以降では、ビューを使用する必要があります。 - Floats Group Rows -
trueの場合、テーブル ビューでは、グループ化されたセルが浮かんでいるように描画されます。 - Columns - 表示する列の数を定義します。
- Headers -
trueの場合、列にはヘッダーが含まれます。 - Reordering -
trueの場合、ユーザーは、テーブル内の列をドラッグして並べ替えることができます。 - Resizing -
trueの場合、ユーザーは、列のヘッダーをドラッグして列のサイズを変更できます。 - Column Sizing - テーブルで列のサイズを自動的に設定する方法を制御します。
- Highlight - セルを選択したときにテーブルで使用する強調表示の種類を制御します。
- Alternate Rows -
trueの場合、他の行は別の背景色になります。 - Horizontal Grid - セルの間で横に引く罫線の種類を選択します。
- Vertical Grid - セルの間で縦に引く罫線の種類を選択します。
- Grid Color - セルの罫線の色を設定します。
- Background - セルの背景色を設定します。
- Selection - ユーザーによるテーブル内のセルの選択方法を制御できます。
- Multiple -
trueの場合、ユーザーは複数の行と列を選択できます。 - Column -
trueの場合、ユーザーは列を選択できます。 - Type Select -
trueの場合、ユーザーは文字を入力して行を選択できます。 - Empty -
trueの場合、ユーザーは、行や列を選択する必要はなく、テーブルでは選択を行うことができません。
- Multiple -
- Autosave - 自動保存されるときのテーブル形式の名前。
- Column Information -
trueの場合、列の順序と幅が自動保存されます。 - Line Breaks - セルでの改行の処理方法を選択します。
- Truncates Last Visible Line -
trueの場合、セルの境界内に収まらないデータは切り取られます。
重要
従来の Xamarin.Mac アプリケーションを管理している場合を除き、NSCell ベースのテーブル ビューではなく、NSView ベースのアウトライン ビューを使用する必要があります。 NSCell はレガシと見なされており、今後サポートされなくなる可能性があります。
Interface Hierarchy で Table Column を選択すると、Attribute Inspector で次のプロパティを使用できます。
- Title - 列のタイトルを設定します。
- Alignment - セル内のテキストの配置を設定します。
- Title Font - セルのヘッダー テキストのフォントを選択します。
- Sort Key - 列内のデータの並べ替えに使用するキーです。 ユーザーがこの列を並べ替えることができない場合は、空白のままにします。
- Selector - 並べ替えの実行に使用する Action です。 ユーザーがこの列を並べ替えることができない場合は、空白のままにします。
- Order - 列のデータの並べ替え順序です。
- Resizing - 列のサイズ変更の種類を選択します。
- Editable -
trueの場合、ユーザーはセル ベース テーブル内のセルを編集できます。 - Hidden -
trueの場合、列は非表示になります。
また、ハンドルを左または右 (列の右側の垂直方向の中心) にドラッグすると列のサイズを変更できます。
テーブル ビューで各列を選択して、最初の列のタイトルとして Product を指定し、2 番目の列に Details を指定します。
Interface Hierarchy で Table Cell View (NSTableViewCell) を選択すると、Attribute Inspector で次のプロパティを使用できます。
これらはすべて、標準ビューのプロパティです。 この列の行のサイズを変更することもできます。
Interface Hierarchy で Table Cell View (これは既定で NSTextField です) を選択すると、Attribute Inspector で次のプロパティを使用できます。
ここで設定する標準テキスト フィールドのプロパティはすべて用意されています。 既定では、標準のテキスト フィールドを使用して、列内のセルのデータが表示されます。
Interface Hierarchy で Table Cell View (NSTableFieldCell) を選択すると、Attribute Inspector で次のプロパティを使用できます。
ここで最も重要な設定は、次のとおりです。
- Layout - この列のセルのレイアウト方法を選択します。
- Uses Single Line Mode -
trueの場合、セルは 1 行に制限されます。 - First Runtime Layout Width -
trueの場合、アプリケーションの初回実行時に設定 (手動または自動的に) されているセルの幅を使用します。 - Action - セルに対して Edit Action を送信するタイミングを制御します。
- Behavior - セルが選択可能または編集可能かどうかを定義します。
- Rich Text -
trueの場合、セルには書式設定およびスタイル設定されたテキストが表示されます。 - Undo -
trueの場合、セルは元に戻す動作を担います。
Interface Hierarchy の Table Column の下部にある Table Cell View (NSTableFieldCell) を選択します。
この操作を行うと、特定の列に対して作成されたすべてのセルの基本 Pattern として使用されている Table Cell View を編集できます。
Action と Outlet の追加
他の Cocoa UI コントロールと同様に、Action と Outlet を使用して (必要な機能に基づく)、アウトライン ビューとその列とセルを C# コードに公開する必要があります。
このプロセスは、公開するアウトライン ビュー要素でも同じです。
Assistant Editor に切り替えて、
ViewController.hファイルが選択されていることを確認します。Interface Hierarchy からアウトライン ビューを選択し、Ctrl キーを押しながらクリックして
ViewController.hファイルにドラッグします。ProductOutlineという名前のアウトライン ビューの Outlet を作成します。ProductColumnとDetailsColumnという名前のテーブル列の Outlet を作成します。変更内容を保存し、Visual Studio for Mac に戻って Xcode と同期します。
次に、アプリケーションの実行時にアウトラインのデータの一部を表示するコードを記述します。
アウトライン ビューの設定
次に、Interface Builder で設計されており、Outlet 経由で公開されているアウトライン ビューで、それを設定するための C# コードを作成する必要があります。
まずは、個々の行とサブ製品のグループの情報を保持するために、新しい Product クラスを作成しましょう。 ソリューション エクスプローラーでプロジェクトを右クリックし、[Add]>[New File...] を選択します。[General]>[Empty Class] を選択し、[Name] で「Product」と入力して、[New] ボタンをクリックします。
Product.cs ファイルを次のようにします。
using System;
using Foundation;
using System.Collections.Generic;
namespace MacOutlines
{
public class Product : NSObject
{
#region Public Variables
public List<Product> Products = new List<Product>();
#endregion
#region Computed Properties
public string Title { get; set;} = "";
public string Description { get; set;} = "";
public bool IsProductGroup {
get { return (Products.Count > 0); }
}
#endregion
#region Constructors
public Product ()
{
}
public Product (string title, string description)
{
this.Title = title;
this.Description = description;
}
#endregion
}
}
次に、NSOutlineDataSource のサブクラスを作成して、アウトラインのデータを要求どおりに指定する必要があります。 ソリューション エクスプローラーでプロジェクトを右クリックし、[Add]>[New File...] を選択します。[General]>[Empty Class] を選択し、[Name] に「ProductOutlineDataSource」と入力して、[New] ボタンをクリックします。
ProductTableDataSource.cs ファイルを編集して、次のようにします。
using System;
using AppKit;
using CoreGraphics;
using Foundation;
using System.Collections;
using System.Collections.Generic;
namespace MacOutlines
{
public class ProductOutlineDataSource : NSOutlineViewDataSource
{
#region Public Variables
public List<Product> Products = new List<Product>();
#endregion
#region Constructors
public ProductOutlineDataSource ()
{
}
#endregion
#region Override Methods
public override nint GetChildrenCount (NSOutlineView outlineView, NSObject item)
{
if (item == null) {
return Products.Count;
} else {
return ((Product)item).Products.Count;
}
}
public override NSObject GetChild (NSOutlineView outlineView, nint childIndex, NSObject item)
{
if (item == null) {
return Products [childIndex];
} else {
return ((Product)item).Products [childIndex];
}
}
public override bool ItemExpandable (NSOutlineView outlineView, NSObject item)
{
if (item == null) {
return Products [0].IsProductGroup;
} else {
return ((Product)item).IsProductGroup;
}
}
#endregion
}
}
このクラスでは、アウトライン ビューの項目用のストレージがあり、テーブル内の行数を返すように GetChildrenCount がオーバーライドされます。 GetChild は、(アウトライン ビューによって要求された) 特定の親または子項目を返し、ItemExpandable は、指定された項目を親または子として定義します。
最後に、アウトラインの動作を指定する NSOutlineDelegate のサブクラスを作成する必要があります。 ソリューション エクスプローラーでプロジェクトを右クリックし、[Add]>[New File...] を選択します。[General]>[Empty Class] を選択し、[Name] に「ProductOutlineDelegate」と入力して、[New] ボタンをクリックします。
ProductOutlineDelegate.cs ファイルを編集して、次のようにします。
using System;
using AppKit;
using CoreGraphics;
using Foundation;
using System.Collections;
using System.Collections.Generic;
namespace MacOutlines
{
public class ProductOutlineDelegate : NSOutlineViewDelegate
{
#region Constants
private const string CellIdentifier = "ProdCell";
#endregion
#region Private Variables
private ProductOutlineDataSource DataSource;
#endregion
#region Constructors
public ProductOutlineDelegate (ProductOutlineDataSource datasource)
{
this.DataSource = datasource;
}
#endregion
#region Override Methods
public override NSView GetView (NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item) {
// This pattern allows you reuse existing views when they are no-longer in use.
// If the returned view is null, you instance up a new view
// If a non-null view is returned, you modify it enough to reflect the new data
NSTextField view = (NSTextField)outlineView.MakeView (CellIdentifier, this);
if (view == null) {
view = new NSTextField ();
view.Identifier = CellIdentifier;
view.BackgroundColor = NSColor.Clear;
view.Bordered = false;
view.Selectable = false;
view.Editable = false;
}
// Cast item
var product = item as Product;
// Setup view based on the column selected
switch (tableColumn.Title) {
case "Product":
view.StringValue = product.Title;
break;
case "Details":
view.StringValue = product.Description;
break;
}
return view;
}
#endregion
}
}
ProductOutlineDelegate のインスタンスを作成するときに、アウトラインにデータを提供する ProductOutlineDataSource のインスタンスも渡します。 GetView メソッドでは、ビュー (データ) を返して、give 列と行のセルを表示します。 可能であれば、新しいビューを作成する必要がない場合は、既存のビューを再利用してセルを表示します。
アウトラインを設定するには、MainWindow.cs ファイルを編集して、AwakeFromNib メソッドを次のようにします。
public override void AwakeFromNib ()
{
base.AwakeFromNib ();
// Create data source and populate
var DataSource = new ProductOutlineDataSource ();
var Vegetables = new Product ("Vegetables", "Greens and Other Produce");
Vegetables.Products.Add (new Product ("Cabbage", "Brassica oleracea - Leaves, axillary buds, stems, flowerheads"));
Vegetables.Products.Add (new Product ("Turnip", "Brassica rapa - Tubers, leaves"));
Vegetables.Products.Add (new Product ("Radish", "Raphanus sativus - Roots, leaves, seed pods, seed oil, sprouting"));
Vegetables.Products.Add (new Product ("Carrot", "Daucus carota - Root tubers"));
DataSource.Products.Add (Vegetables);
var Fruits = new Product ("Fruits", "Fruit is a part of a flowering plant that derives from specific tissues of the flower");
Fruits.Products.Add (new Product ("Grape", "True Berry"));
Fruits.Products.Add (new Product ("Cucumber", "Pepo"));
Fruits.Products.Add (new Product ("Orange", "Hesperidium"));
Fruits.Products.Add (new Product ("Blackberry", "Aggregate fruit"));
DataSource.Products.Add (Fruits);
var Meats = new Product ("Meats", "Lean Cuts");
Meats.Products.Add (new Product ("Beef", "Cow"));
Meats.Products.Add (new Product ("Pork", "Pig"));
Meats.Products.Add (new Product ("Veal", "Young Cow"));
DataSource.Products.Add (Meats);
// Populate the outline
ProductOutline.DataSource = DataSource;
ProductOutline.Delegate = new ProductOutlineDelegate (DataSource);
}
アプリケーションを実行すると、次が表示されます。
アウトライン ビューでノードを展開すると、次のようになります。
列による並べ替え
ユーザーが列ヘッダーをクリックしてテーブルを並べ替えられるようにしましょう。 まず、Main.storyboard ファイルをダブルクリックして、Interface Builder で編集用に開きます。 Product 列を選択し、[Sort Key] に「Title」、[Selector] に「compare:」と入力して、[Order] で Ascending を選択します。
変更内容を保存し、Visual Studio for Mac に戻って Xcode と同期します。
次に、ProductOutlineDataSource.cs ファイルを編集して、次のメソッドを追加します。
public void Sort(string key, bool ascending) {
// Take action based on key
switch (key) {
case "Title":
if (ascending) {
Products.Sort ((x, y) => x.Title.CompareTo (y.Title));
} else {
Products.Sort ((x, y) => -1 * x.Title.CompareTo (y.Title));
}
break;
}
}
public override void SortDescriptorsChanged (NSOutlineView outlineView, NSSortDescriptor[] oldDescriptors)
{
// Sort the data
Sort (oldDescriptors [0].Key, oldDescriptors [0].Ascending);
outlineView.ReloadData ();
}
Sort メソッドを使用すると、特定の Product クラス フィールドに基づいて、データ ソース内のデータを昇順または降順で並べ替えることができます。 オーバーライドされた SortDescriptorsChanged メソッドが、列見出しをクリックするたびに呼び出されます。 Interface Builder で設定したキー値と、その列の並べ替え順序が渡されます。
アプリケーションを実行して列ヘッダーをクリックすると、行がその列ごとに並べ替えられます。
行の選択
ユーザーが 1 つの行を選択できるようにする場合は、Main.storyboard ファイルをダブルクリックして、Interface Builder で編集用に開きます。 Interface Hierarchy でアウトライン ビューを選択し、Attribute Inspector の [Multiple] チェックボックスのチェックを外します。
変更内容を保存し、Visual Studio for Mac に戻って Xcode と同期します。
次に、ProductOutlineDelegate.cs ファイルを編集し、次のメソッドを追加します。
public override bool ShouldSelectItem (NSOutlineView outlineView, NSObject item)
{
// Don't select product groups
return !((Product)item).IsProductGroup;
}
これにより、ユーザーはアウトライン ビューのあらゆる行を選択できるようになります。 ユーザーに選択させたくない項目がある場合は、その項目の ShouldSelectItem に対して false を返します。ユーザーにどの項目も選択させたくない場合は、すべての項目に対して false を返します。
複数行の選択
ユーザーが複数の行を選択できるようにする場合は、Main.storyboard ファイルをダブルクリックして、Interface Builder で編集用に開きます。 Interface Hierarchy でアウトライン ビューを選択し、Attribute Inspector の [Multiple] チェックボックスをオンにします。
変更内容を保存し、Visual Studio for Mac に戻って Xcode と同期します。
次に、ProductOutlineDelegate.cs ファイルを編集し、次のメソッドを追加します。
public override bool ShouldSelectItem (NSOutlineView outlineView, NSObject item)
{
// Don't select product groups
return !((Product)item).IsProductGroup;
}
これにより、ユーザーはアウトライン ビューのあらゆる行を選択できるようになります。 ユーザーに選択させたくない項目がある場合は、その項目の ShouldSelectRow に対して false を返します。ユーザーにどの項目も選択させたくない場合は、すべての項目に対して false を返します。
入力による行の選択
選択したアウトライン ビューでユーザーが文字を入力して、その文字が含まれている最初の行を選択できるようにする場合は、Main.storyboard ファイルをダブルクリックして、Interface Builder で編集用に開きます。 Interface Hierarchy でアウトライン ビューを選択し、Attribute Inspector の [Type Select] チェックボックスをオンにします。
変更内容を保存し、Visual Studio for Mac に戻って Xcode と同期します。
ここで、ProductOutlineDelegate.cs ファイルを編集し、次のメソッドを追加しましょう。
public override NSObject GetNextTypeSelectMatch (NSOutlineView outlineView, NSObject startItem, NSObject endItem, string searchString)
{
foreach(Product product in DataSource.Products) {
if (product.Title.Contains (searchString)) {
return product;
}
}
// Not found
return null;
}
GetNextTypeSelectMatch メソッドでは、特定の searchString を受け取り、その Title にその文字列が含まれている最初の Product の項目を返します。
列の並べ替え
ユーザーがアウトライン ビューで並べ替える列をドラッグできるようにする場合は、Main.storyboard ファイルをダブルクリックして、Interface Builder で編集用に開きます。 Interface Hierarchy でアウトライン ビューを選択し、Attribute Inspector の [Reordering] チェックボックスをオンにします。
[Autosave] プロパティに値を指定して Column Information フィールドにチェックを入れている場合、テーブルのレイアウトに加えた変更は自動保存され、次回アプリケーションが実行されたときに復元されます。
変更内容を保存し、Visual Studio for Mac に戻って Xcode と同期します。
ここで、ProductOutlineDelegate.cs ファイルを編集し、次のメソッドを追加しましょう。
public override bool ShouldReorder (NSOutlineView outlineView, nint columnIndex, nint newColumnIndex)
{
return true;
}
ShouldReorder メソッドでは、newColumnIndex にドラッグして並べ替える必要がある列の true を返す必要があります。それ以外の場合は、false を返します。
アプリケーションを実行する場合は、列ヘッダーをドラッグして列を並べ替えることができます。
セルの編集
ユーザーが特定のセルの値を編集できるようにする場合は、ProductOutlineDelegate.cs ファイルを編集し、GetViewForItem メソッドを次のように変更します。
public override NSView GetView (NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item) {
// Cast item
var product = item as Product;
// This pattern allows you reuse existing views when they are no-longer in use.
// If the returned view is null, you instance up a new view
// If a non-null view is returned, you modify it enough to reflect the new data
NSTextField view = (NSTextField)outlineView.MakeView (tableColumn.Title, this);
if (view == null) {
view = new NSTextField ();
view.Identifier = tableColumn.Title;
view.BackgroundColor = NSColor.Clear;
view.Bordered = false;
view.Selectable = false;
view.Editable = !product.IsProductGroup;
}
// Tag view
view.Tag = outlineView.RowForItem (item);
// Allow for edit
view.EditingEnded += (sender, e) => {
// Grab product
var prod = outlineView.ItemAtRow(view.Tag) as Product;
// Take action based on type
switch(view.Identifier) {
case "Product":
prod.Title = view.StringValue;
break;
case "Details":
prod.Description = view.StringValue;
break;
}
};
// Setup view based on the column selected
switch (tableColumn.Title) {
case "Product":
view.StringValue = product.Title;
break;
case "Details":
view.StringValue = product.Description;
break;
}
return view;
}
アプリケーションを実行するとユーザーはテーブル ビューのセルを編集できます。
アウトライン ビューでの画像の使用
NSOutlineViewのセルの一部として画像を含めるには、アウトライン ビューの NSTableViewDelegate's GetView メソッドによってデータが返される方法を変更して、一般的なNSTextFieldの代わりにNSTableCellViewを使用する必要があります。 次に例を示します。
public override NSView GetView (NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item) {
// Cast item
var product = item as Product;
// This pattern allows you reuse existing views when they are no-longer in use.
// If the returned view is null, you instance up a new view
// If a non-null view is returned, you modify it enough to reflect the new data
NSTableCellView view = (NSTableCellView)outlineView.MakeView (tableColumn.Title, this);
if (view == null) {
view = new NSTableCellView ();
if (tableColumn.Title == "Product") {
view.ImageView = new NSImageView (new CGRect (0, 0, 16, 16));
view.AddSubview (view.ImageView);
view.TextField = new NSTextField (new CGRect (20, 0, 400, 16));
} else {
view.TextField = new NSTextField (new CGRect (0, 0, 400, 16));
}
view.TextField.AutoresizingMask = NSViewResizingMask.WidthSizable;
view.AddSubview (view.TextField);
view.Identifier = tableColumn.Title;
view.TextField.BackgroundColor = NSColor.Clear;
view.TextField.Bordered = false;
view.TextField.Selectable = false;
view.TextField.Editable = !product.IsProductGroup;
}
// Tag view
view.TextField.Tag = outlineView.RowForItem (item);
// Allow for edit
view.TextField.EditingEnded += (sender, e) => {
// Grab product
var prod = outlineView.ItemAtRow(view.Tag) as Product;
// Take action based on type
switch(view.Identifier) {
case "Product":
prod.Title = view.TextField.StringValue;
break;
case "Details":
prod.Description = view.TextField.StringValue;
break;
}
};
// Setup view based on the column selected
switch (tableColumn.Title) {
case "Product":
view.ImageView.Image = NSImage.ImageNamed (product.IsProductGroup ? "tags.png" : "tag.png");
view.TextField.StringValue = product.Title;
break;
case "Details":
view.TextField.StringValue = product.Description;
break;
}
return view;
}
詳細については、画像の使用に関するドキュメントの アウトライン ビューでの画像の使用に関するセクションを参照してください。
データ バインディング アウトライン ビュー
Xamarin.Mac アプリケーションで Key-Value Coding と Data Binding の手法を使用すると、UI 要素を設定して操作するために記述および管理が必要なコードの量を大幅に減らすことができます。 また、バッキング データ (データ モデル) をフロントエンド ユーザー インターフェイス (Model-View-Controller) からさらに切り離すことで、アプリケーション デザインを管理しやすくなるという利点もあります。
キーと値のコーディング (KVC) は、インスタンス変数やアクセサー メソッド (get/set) を介してアクセスするのではなく、キー (特別にフォーマットされた文字列) を使用してプロパティを識別し、オブジェクトのプロパティに間接的にアクセスするためのメカニズムです。 Xamarin.Mac アプリケーションで Key-Value Coding に準拠したアクセサーを実装すると、Key-Value Observing (KVO)、Data Binding、Core Data、Cocoa バインディング、スクリプト機能など、他の macOS 機能にアクセスできます。
詳細については、Data Binding と Key-Value Coding に関するドキュメントの「アウトライン ビューのデータ バインディング」セクションを参照してください。
まとめ
この記事では、Xamarin.Mac アプリケーションでのアウトライン ビューの使用について詳しく説明しました。 アウトライン ビューのさまざまな種類と使用方法、Xcode の Interface Builder でアウトライン ビューを作成および管理する方法、C# コードでアウトライン ビューを操作する方法について確認しました。

















![[複数] 設定を変更できる属性インスペクターを示すスクリーンショット。](outline-view-images/select01.png)
![属性インスペクターを示すスクリーンショット。[複数] を選択できます。](outline-view-images/select02.png)

![[並べ替え] を選択できる属性インスペクターを示すスクリーンショット。](outline-view-images/reorder01.png)

