Xamarin.Mac の一般的なパターンとイディオム

C# から公開されている Apple API 全体で、特定のイディオムやパターンが繰り返し登場します。 Xamarin.iOS を使用したプログラミングの経験があるなら、見覚えがあるかもしれません。 これらのパターンやイディオムは、ドキュメントで繰り返し参照することが多いため、しっかり理解しておくと、見つけたドキュメントを理解するのに役立ちます。

MVC - Model-View-Controller

Model-View-Controller (略して MVC) は、Cocoa 全体で見られる非常に一般的なパターンです。 詳細な説明はこのドキュメントの範囲を超えていますが、簡単に言えば、アプリケーションをコンポーネントに構造化する方法です。

  • モデル オブジェクトは、表示および操作される基になるデータを表します (アドレス帳の住所など)
  • ビュー オブジェクトは、画面上の特定のオブジェクトの描画とユーザー操作を処理します (画面上のアドレスを示すテキスト フィールド)
  • コントローラー オブジェクトは、モデルとビューの間の相互作用を処理します。 モデルの変更を "上" にプッシュしてビューを更新し、ユーザーが UI で変更を加えたときにビューから変更を "下" にプッシュします。

WPF などの他のライブラリの MVVM (Model View ViewModel) に慣れている場合、コントローラーは ViewModel と同様に動作しますが、多くの場合、特定の UI 要素により密接にバインドされています。

詳細については、こちらで確認できます。

データ ソース/デリゲート/サブクラス化

Cocoa のもう 1 つの非常に一般的なパターンは、UI 要素にデータを提供し、ユーザー操作に対応します。 NSTableView を例にとると、各行のデータ、その行を表す UI 要素のセット、ユーザー操作に対応するビヘイビアーのセット、場合によってはある程度のカスタマイズを何らかの方法で提供する必要があります。 データ ソースとデリゲート パターンを使用すると、NSTableView を自分でサブクラス化することなく、ほとんどのケースを処理できます。

  • DataSource プロパティには、(GetRowCount および GetObjectValue を介して) テーブルにデータを設定するために呼び出される NSTableViewDataSource のカスタム サブクラスのインスタンスが割り当てられます。

  • Delegate プロパティには、(GetViewForItem を介して) 特定のモデル オブジェクトのビューを提供し、(DidClickTableColumnMouseDownInHeaderOfTableColumn などを介して) UI 操作を処理する NSTableViewDelegate のカスタム サブクラスのインスタンスが割り当てられます。

場合によっては、デリゲートまたはデータ ソースで指定されたフックを超える方法でコントロールをカスタマイズする必要があり、ビューを直接サブクラス化することができます。 ただし、多くの場合、既定の動作をオーバーライドするには、その動作をすべて自分で処理する必要があります (選択動作をカスタマイズするには、すべての選択動作を自分で実装する必要がある場合があります)。

Xamarin.iOS では、UITableView などの一部の API が、デリゲートとデータ ソース (UITableViewSource) の両方を実装するプロパティで拡張されています。 これは、1 つの C# クラスで持てる基底クラスは 1 つだけという一般的な制限を回避するためです。Microsoft のプロトコルの公開は複数の基底クラスを介して行われます。

Xamarin.Mac アプリケーションでのテーブル ビューの操作の詳細については、Microsoft のテーブル ビューのドキュメントを参照してください。

プロトコル

Objective-C のプロトコルは C# のインターフェイスと比較でき、多くの場合、同様の状況で使用されます。 たとえば、上記の NSTableView の例では、デリゲートとデータ ソースの両方が実際にはプロトコルです。 これらはオーバーライドできる仮想メソッドを備えた基底クラスとして、Xamarin.Mac によって公開されます。 C# インターフェイスと Objective-C プロトコルの主な違いは、プロトコル内の一部のメソッドは実装が任意である可能性があることです。 API のドキュメントや定義を調べて、省略可能なものを判断する必要があります。

詳細については、デリゲート、プロトコル、イベントに関するドキュメントを参照してください。