My External Storage

Nov 24, 2017 - 3 minute read - Comments - Xamarin.Mac

[Xamarin.Mac]NStextFieldにテキストが入力されるたびに変更を検出する

知っているとすぐ出来るけど、知らないとちょっと時間がかかるシリーズ。

TL;DR

  • Xamarin.MacC#側で文字入力のイベントを検出する
  • その1。NSTextField.valueへのstringのプロパティをデータバインドする
  • その2。NSTextFieldDelegateを実装したクラスをNSTextField.Delegateに紐付けておく

NStextFieldNSSecureTextFieldの変更を検知したい。

Xamarin.MacNSTextFieldNSSecureTextFieldなどに対する文字列入力イベントを検知し、処理を行う。その1のほうが直感的だしシンプル。

その1。NSTextField.valueへのstringのプロパティをデータバインドする

普通に NSTextFieldvaluestringのプロパティをデータバインドするだけでOKだった。データバインドのやり方は公式ページを参照のこと。

Data Binding and Key-Value Coding|Simple Data Binding

ViewControllerstringのプロパティを作る。

// 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で対象のNSTextFieldBindings Inspectorでプロパティを紐付ける。

XCode見たNSTextFieldのBindings Inspector

文字が一文字編集されるたびにプロパティのSetterが呼ばれる。

その2。NSTextFieldDelegateを実装したクラスをNSTextField.Delegateに紐付けておく

基本的には通常のCocoa Appプログラミングと同様のことをC#で実施するだけ。

NSTextFieldで入力を検出する

事前準備として、文字入力を検出したい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使ったほうがいいシーンってどんなときなんだろう?

関連記事