コントロールをカスタマイズする

2018.02.26  投稿者: Muraoka
コントロールカスタマイズクラス

Xojo を使い始めると標準のコントロールを自分なりに拡張したものを便利に使いたくなります。Xojo の標準コントロールはクラスなので、クラスの拡張という形でコントロールを拡張(標準コントロールクラスを継承)して、ある目的に特化したサブクラスを作成することができます。ここでは標準コントロールのサブクラスを作成する方法を解説します。

1.コントロールの要件

今回はデスクトップアプリケーションで使用する TextField コントロールを拡張してみることにします。以下の要件を満たすカスタムコントロール TextFieldEx クラスを作成します。

  • TextField クラスのサブクラスとして作成する
  • 数字入力を目的とする。受け付ける文字は以下の通り…… 0 - 9、-(マイナス)、Backspace、Delete、Tab、左右カーソルキー
  • 最大入力桁数をプロパティ maxlength (初期値:8)に設定できるようにする
  • フォーカスがなくなると、入力されている値をカンマ編集して表示する
  • フォーカスを受けると、数字を入力するためにカンマを消去する

2.準備

今回はデスクトップアプリケーションを使用するので、Xojo を起動してデスクトップ・プロジェクトを新規作成します。アプリケーション名に TextFieldEx と入力し、OK ボタンをクリックします。

3.サブクラスの作成

Xojo IDE 画面で右上の「ライブラリ」をクリックすると、利用できるコントロールの一覧が IDE 画面の右端に表示されます。
その中の TextField コントロールをドラッグして、そのままプロジェクト欄にドロップすると、ドロップした TextField の名称が CustomTextField に変わります。
これでサブクラスが作成できました。簡単ですね。
インスペクタの Super 欄が TextField となっていることで、CustomTextField が TextField のサブクラスであることが確認できます。
また、今回は名前を TextFieldEx とするので、Name 欄のクラス名を TextFieldEx に変更しておきます。

4.プロパティを追加する

プロジェクト欄の TextFieldEx を右クリックし、「TextFieldEx」に追加→プロパティをクリックすると、プロパティ Untitled が作成されます。
この名前を Untitled から maxlength に変更します。データ型は Integer なのでそのままに、初期値は 8 にしたいので標準値の欄に 8 を入力します。
これでプロパティを追加作業が終わりました。

5.イベントを追加する(1)

まず入力されたキーへの対応を行なうイベントを実装しましょう。
プロジェクト欄の TextFieldEx を右クリックし、「TextFieldEx」に追加→イベントハンドラ... をクリックすると実装可能なイベント一覧が表示されます。
キー入力のイベントを実装しますので、KeyDown を選択して OK ボタンをクリックします。

KeyDown イベントでは入力されたキーは引数 Key として渡されます。このイベントの処理を終了する際に戻り値を返しますが、戻り値として True を返すと、処理した KeyDown イベント内で押されたキー入力の処理を完了したことになり、キーが押されたという情報そのものがシステム側に引き渡されず、キー入力に伴う数字/文字の入力が行われません。その為、入力があった事自体を無視したい場合には、ここで True を戻り値として戻します。

まず、入力された文字が入力を受け付ける文字であるかどうかを InStr メソッドを利用して判定し、入力を受け付けない文字であれば True を返して入力された文字を無視します。

// 入力を受け付ける文字列を設定する
Dim AcceptableKeys, AcceptableNumKeys, AcceptableSysKeys As String

AcceptableNumKeys = "0123456789-"
AcceptableSysKeys = Chr(8) + Chr(127) + Chr(9) + Chr(28) + Chr(29)
AcceptableKeys = AcceptableNumKeys + AcceptableSysKeys

// 入力されたキーが受け付けるキーでないなら...
If InStr(  AcceptableKeys, Key  ) = 0 Then
// キー入力を無視する
  Return True

// 受け付けるキーなら...
Else


End If

入力可能なキーが入力された場合、数字が入力されている場合には入力中の文字数が1文字増えます。すでに入力中の文字列の文字数が maxlength になっている場合、文字数が制限を超えないように、キー入力を無視することにします。
文字数がまだ最大に達していない場合、または Backspace やカーソルなどのキーが入力された場合はここで False を返すと、システムがキー入力を処理して、文字の入力などの処理が行なわれます。

// 入力されたら文字列の長さが増えるキーが入力された場合で、現在入力されている文字数が文字列の最大になっている場合...
If 0 < InStr(  AcceptableNumKeys, Key  ) And Me.maxlength <= Len(  Me.Text  ) Then

  // キー入力を無視する
  Return True

  Else

  // キー入力をシステムに任せる
  Return False

End If

6.イベントを追加する(2)

次に2つの機能を実装します。フォーカスを失った場合とフォーカスを受けた場合です。

フォーカスを失った場合

フォーカスを失った時に発生するイベントは LostFocus イベントです。KeyDown イベントと同様の方法で今度は LostFocus イベントを追加します。
フォーカスを失った時には TextField 内の文字列をコンマ編集して表示します。

// TextField 内の文字列を数値に変換してそれをコンマ編集された文字列に変換する
Me.Text = Format( Val( Me.Text), "###,##0"  )

フォーカスを受けた場合

フォーカスを受けた時に発生するイベントは GotFocus イベントです。KeyDown イベントと同様の方法で今度は GotFocus イベントを追加します。
フォーカスを受けたときには、単純にコンマ編集されている文字列からコンマを取り除きます。

// 文字列からコンマを空文字列に変換します(=文字列からコンマを取り除きます)
Me.Text = ReplaceAll( Me.Text, ",", ""  )

これでコントロールの要件を満たす TextField のカスタマイズを行なうことができました。

 

7.ウインドウに新しいコントロールを追加する

作成したコントロールを画面に貼り付ける

作成した TextFieldEx は、通常の TextField と同様にウインドウにコントロールを貼り付けるだけで、内蔵コントロールと同様に利用することができます。
Window1 をクリックして画面を作成する画面に移動します。プロジェクトから先ほど作成した TextFieldEx をドラッグドロップすると、TextFieldEx コントロールが Window1 に貼り付けられます。インスペクタ欄で貼り付けた TextFieldEx コントロールの親クラスが TextFieldEx であることを確認してください。
また、先ほど貼り付けたコントロールの下に同じ TextFieldEx コントロールをもう1つ貼り付けます。

プロジェクトの実行

ここでプロジェクトを実行してみましょう。コントロールが仕様通りの動きをすることをご確認ください。

8.まとめ

Xojo で標準で用意されているコントロールはクラスになっているので、上の例のように簡単に機能を拡張することができます。郵便番号の入力コントロールや日付の入力コントロールなどを簡単に作成することができますので、再利用を想定したコントロールを設計・作成して、工数をどんどん減らして行きましょう。まずは日付入力コントロールから挑戦してみてください。

プロジェクトファイルのダウンロード

今回の記事を元にしたサンプルとなるプロジェクトファイルは以下のリンクよりダウンロードすることができます。実際のコードに触れてみて自分なりの仕様に変更してみることからおすすめします。

ダウンロード