知っているとすぐ出来るけど、知らないとちょっと時間がかかるシリーズ。
TL;DR
Xamarin.MacでC#側で文字入力のイベントを検出する- その1。
NSTextField.valueへのstringのプロパティをデータバインドする - その2。
NSTextFieldDelegateを実装したクラスをNSTextField.Delegateに紐付けておく
NStextFieldやNSSecureTextFieldの変更を検知したい。
Xamarin.MacでNSTextFieldやNSSecureTextFieldなどに対する文字列入力イベントを検知し、処理を行う。その1のほうが直感的だしシンプル。
その1。NSTextField.valueへのstringのプロパティをデータバインドする
普通に NSTextFieldのvalueにstringのプロパティをデータバインドするだけでOKだった。データバインドのやり方は公式ページを参照のこと。
Data Binding and Key-Value Coding|Simple Data Binding
ViewControllerにstringのプロパティを作る。
// ViewController.cs
string _password = "";
[Export("Password")]
public string Password
{
get { return _password; }
set
{
WillChangeValue(nameof(Password));
Console.WriteLine("Changed.");
_password = value;
DidChangeValue(nameof(Password));
}
}
XCodeで対象のNSTextFieldのBindings Inspectorでプロパティを紐付ける。

文字が一文字編集されるたびにプロパティのSetterが呼ばれる。
その2。NSTextFieldDelegateを実装したクラスをNSTextField.Delegateに紐付けておく
基本的には通常のCocoa Appプログラミングと同様のことをC#で実施するだけ。
事前準備として、文字入力を検出したいNSTextFieldなどのプロパティをXCodeからC#のクラスへ自動生成しておく。
方法はXamarin公式ページの以下のセクションから「Synchronizing Changes with Xcode」までを行うことで作成できる。
Hello, Mac|Outlets and Actions
日本語で読みたい方はこちら
Xamarin.Macを初めて触る人に贈る、Xamarin公式 Hello, Mac の日本語訳記事
// ViewController.designer.cs
[Register("ViewController")]
partial class ViewController
{
[Outlet]
AppKit.NSTextField TextField { get; set; }
}
検出時に行いたい処理をNSTextFieldDelegate継承クラスに実装する。
https://developer.xamarin.com/api/type/MonoMac.AppKit.NSTextFieldDelegate/
public class MyDeleGate : AppKit.NSTextFieldDelegate{
public override void Changed(NSNotification notification)
{
// base.Changed(notification); は呼んではいけない。
Console.WriteLine("Changed.");
}
}
あとはこのDelegateインスタンスを`NSTextFieldなどに紐付けて終わり。
// ViewController.cs
public partial class ViewController : AppKit.NSViewController
{
public override void ViewDidAppear()
{
TextField.Delegate = new MyDeleGate();
}
}
そこそこ調べてまずその2の方法を見つけた。そのあとその1でも出来ることに気づいたのでかなり遠回りしてしまった。
普通のCocoaでもその1の方法できると思うのだけど、Delegate使ったほうがいいシーンってどんなときなんだろう?