XAML でのイベント処理
- 5 分
XAML UI を作成した後は、ユーザーがページにアクセスしたときに発生する操作に応答するコードを追加できます。 .NET MAUI は、標準の .NET イベントを通じてユーザーの入力と対話をアプリケーションに通知します。
このユニットでは、これらのイベントを処理し、ユーザーが期待する操作を実行する方法について学習します。
XAML ページ内の要素の名前付け
イベント処理コードでは、ページ上の特定のコントロールとそのプロパティを参照しなければならないことがよくあります。 各コントロールに一意の名前を割り当てることができます。 これを行うには、XAML 属性 x:Name を使います。 x:Name 属性は 2 つのことを実行します。
生成されたコードビハインドファイルに、この要素にマップされたプライベートフィールドを追加します。 コードでこのフィールドを使って、ビジュアル要素を操作し、ランタイム プロパティを設定したり、イベントを処理したりします。
その要素が、この名前によって XAML に認識されるようにします。 これらの要素は、同じ XAML ファイルで定義された他の要素から参照できます。
要素に名前を付けるとき、任意の文字列は使用できません。 x:Name 属性に割り当てられた値は、コードでフィールドを作成するために使われます。 代わりに、変数の名前付け規則に準拠する必要があります。 また、名前は、コードビハインド定義にコンパイルされるため、一意である必要があります。
要素の名前を指定した後は、分離コード ファイルでその要素を操作できます。 次の XAML フラグメントでは、Label コントロールを定義しています。 その名前は CounterLabel です (この例は、.NET MAUI テンプレートによって生成される既定のアプリのものです)。
<Label Text="Current count: 0"
...
x:Name="CounterLabel"
... />
このページのコードビハインドでは、CounterLabel フィールドを通じてこのコントロールを参照し、そのプロパティを変更できます。
count++;
CounterLabel.Text = $"Current count: {count}";
重要
ページの InitializeComponent メソッドが実行されるまで、フィールドは初期化されません。 このメソッドは、XAML の解析とオブジェクトのインスタンス化のプロセスの一部です。 この呼び出しの後に、XAML で定義されている要素を操作するコードを配置します。 このルールの例外は、ContentPage クラス自体です。 InitializeComponent メソッドを実行する前に、クラスのすべてのプロパティにアクセスできます。 ただし、XAML でこのクラスの任意のプロパティを設定すると、これらのプロパティ値によって、InitializeComponent を実行する前に設定した値が上書きされます。
属性を使用してイベントを関連付ける
多くのコントロールでは、それらのコントロールが応答できるイベントに対応するプロパティが公開されています (ボタンの Clicked イベントなど)。 さまざまなコントロールで、さまざまなイベントのセットがサポートされています。 たとえば、Button コントロールは Clicked、Pressed、Released イベントに応答できるのに対し、Entry コントロールには TextChanged といったイベントが含まれます。 ページの XAML マークアップでイベント プロパティを初期化し、イベントがトリガーされたときに実行するメソッドの名前を指定できます。 イベント メソッドのシグネチャは、次の要件を満たしている必要があります。
- 値を返すことはできません。メソッドは
voidでなければなりません。 - 2 つのパラメーターを受け取る必要があります。1 つはイベントをトリガーしたオブジェクトを示す
object参照で ("センダー" と呼ばれます)、もう 1 つはセンダーによってイベント ハンドラーに渡された引数を含む パラメーターです。EventArgs - イベント ハンドラーは
privateにするべきです。 これは強制ではありませんが、イベント ハンドラーをパブリックにすると、外界からアクセスできるようになり、トリガーされることが意図されているイベント以外のアクションによって呼び出される可能性があります。 - イベント ハンドラーは、非同期操作を実行する必要がある場合は
asyncにすることができます。
次の例では、.NET MAUI テンプレートのサンプル アプリのボタンに対する Clicked イベント ハンドラーの定義を示します。 メソッドの名前は標準規則に従います。つまり、On の後にコントロールの名前 (このボタンは Counter という名前です)、その後にイベントの名前 (Clicked) です。 この規則は強制ではありませんが、このようにすることをお勧めします。
private void OnCounterClicked(object sender, EventArgs e)
{
...
}
懸念事項の分離
XAML でイベントを関連付けると便利ですが、コントロールの動作と UI の定義が混在するようになります。 多くの開発者は、それらの要素を別々のままにし、名前付き要素に対してコード ビハインド内のすべてのイベント ハンドラー サブスクリプションを実行することを好みます。 この方が接続されているものと動作がマップされている場所を確認しやすくなります。 また、この方法では、気付かずに XAML のハンドラーを削除することによって、コードが意図せずに破壊される状況が発生しにくくなります。 削除されたハンドラーはコンパイラによってキャッチされず、コードでその動作が適切に実行されない場合にのみ問題として表面化します。
XAML を使ってイベント ハンドラーを結び付けるか、それともコードを使うかは、個人的な選択の問題です。
コードでイベント ハンドラーを結び付けるには、+= 演算子を使ってイベントにサブスクライブします。 通常、この操作は、ページのコンストラクターで、InitializeComponent を呼び出した後に行います。
public partial class MainPage : ContentPage, IPage
{
public MainPage()
{
InitializeComponent();
Counter.Clicked += OnCounterClicked;
}
...
private void OnCounterClicked(object sender, EventArgs e)
{
...
}
}
注
この方法を使って、同じイベントに対して複数のイベント処理メソッドをサブスクライブできます。 イベントが発生すると各イベント処理メソッドが実行されますが、それらが特定の順序で実行されるとは想定しないでください。そのため、それらの間に依存関係を作らないでください。
同様に、アプリケーションで後から、-= 演算子を使ってイベントのサブスクライブを解除することで、イベント ハンドラーを削除できます。
Counter.Clicked -= OnCounterClicked;