atwiki-logo
  • 新規作成
    • 新規ページ作成
    • 新規ページ作成(その他)
      • このページをコピーして新規ページ作成
      • このウィキ内の別ページをコピーして新規ページ作成
      • このページの子ページを作成
    • 新規ウィキ作成
  • 編集
    • ページ編集
    • ページ編集(簡易版)
    • ページ名変更
    • メニュー非表示でページ編集
    • ページの閲覧/編集権限変更
    • ページの編集モード変更
    • このページにファイルをアップロード
    • メニューを編集
    • 右メニューを編集
  • バージョン管理
    • 最新版変更点(差分)
    • 編集履歴(バックアップ)
    • アップロードファイル履歴
    • ページ操作履歴
  • ページ一覧
    • ページ一覧
    • このウィキのタグ一覧
    • このウィキのタグ(更新順)
    • このページの全コメント一覧
    • このウィキの全コメント一覧
    • おまかせページ移動
  • RSS
    • このウィキの更新情報RSS
    • このウィキ新着ページRSS
  • ヘルプ
    • ご利用ガイド
    • Wiki初心者向けガイド(基本操作)
    • このウィキの管理者に連絡
    • 運営会社に連絡(不具合、障害など)
プログラミング図書館・本館
  • ウィキ募集バナー
  • 目安箱バナー
  • 操作ガイド
  • 新規作成
  • 編集する
  • 全ページ一覧
  • 登録/ログイン
ページ一覧
プログラミング図書館・本館
  • ウィキ募集バナー
  • 目安箱バナー
  • 操作ガイド
  • 新規作成
  • 編集する
  • 全ページ一覧
  • 登録/ログイン
ページ一覧
プログラミング図書館・本館
  • 新規作成
  • 編集する
  • 登録/ログイン
  • 管理メニュー
管理メニュー
  • 新規作成
    • 新規ページ作成
    • 新規ページ作成(その他)
      • このページをコピーして新規ページ作成
      • このウィキ内の別ページをコピーして新規ページ作成
      • このページの子ページを作成
    • 新規ウィキ作成
  • 編集
    • ページ編集
    • ページ編集(簡易版)
    • ページ名変更
    • メニュー非表示でページ編集
    • ページの閲覧/編集権限変更
    • ページの編集モード変更
    • このページにファイルをアップロード
    • メニューを編集
    • 右メニューを編集
  • バージョン管理
    • 最新版変更点(差分)
    • 編集履歴(バックアップ)
    • アップロードファイル履歴
    • ページ操作履歴
  • ページ一覧
    • このウィキの全ページ一覧
    • このウィキのタグ一覧
    • このウィキのタグ一覧(更新順)
    • このページの全コメント一覧
    • このウィキの全コメント一覧
    • おまかせページ移動
  • RSS
    • このwikiの更新情報RSS
    • このwikiの新着ページRSS
  • ヘルプ
    • ご利用ガイド
    • Wiki初心者向けガイド(基本操作)
    • このウィキの管理者に連絡
    • 運営会社に連絡する(不具合、障害など)
  • atwiki
  • プログラミング図書館・本館
  • WPF
  • イベント

イベント

最終更新:2011年01月25日 01:49

atachi

- view
管理者のみ編集可
  • イベントのアタッチ [#q1f4c985]
    • コードによるイベントのアタッチ [#h3e8df39]
  • イベントルーティング [#c831d229]
    • トンネル型イベント [#cb80da22]
    • バブル型イベント [#xc5fd69e]
    • ダイレクト型イベント [#facd7b59]
    • 処理済みフラグ(Handled) [#ccefc0a2]
  • 入力イベントのルーティング [#bc973d5e]

イベントのアタッチ

通常のUIではイベントソースとイベントリスナは同じオブジェクトとなります。
(イベントソースとはイベントの発生源)
(イベントリスナとはイベントをアタッチしたオブジェクト)

<Panel>
	<Button Click="onClickMyButton" Text="Button" />
</Panel>
/**
 * ButtonがClickイベントを受け取ったときの実行関数
 */
private void onClickMyButton(object sender,RoutedEventArgs e) {
	// ユーザーによってボタンがクリックしたときの処理
}

イベントはルーティングによって伝播されるので、次のサンプルのようにButton要素の親要素であるPanel要素でもButton要素が受け取るイベントを受け取ることができます。

<Panel Button.Click="onClickCommonButton">
	<Button Text="Button1" />
	<Button Text="Button2" />
</Panel>
private void onClickCommonButton(object sender,RoutedEventArgs e) {
	// ユーザーによってボタンがクリックしたときの処理
}

この場合、ユーザーがButton1をクリックしてもButton2をクリックしても、onClickCommonButtonハンドラが呼び出されます。

コードによるイベントのアタッチ

XAMLに「button1」という名前で定義してあるButton要素に、分離コードでClickイベントをアタッチします。

namespace My {
	public partial class MainWindow : Window {
		public MainWindow() {
			InitializeComponent();
 
			// XAMLで定義したbutton1へClickイベントをアタッチ
			this.button1.Click += new RoutedEventHandler( onClickButton1 ); // イベントへエンティティを追加
			// ↑または、次のようなサポートメソッドを使う
			// this.AddHandler( Button.ClickEvent, new RoutingEventHandler(onClickButton1) );
		}
 
 
		private void onClickButton1(object sender, RoutedEventArgs e) {
		}
	}
}

イベントのアタッチ方法が2種類あるが、どちらも中身は同じ。
「button1.Click」はButton.Clickイベントで、この定義は次のようになっている。

public event RoutedEventHandler Click {
	add {
		this.AddHandler( Button.ClickEvent, value);
	}
	remove {
		this.AddHandler( Button.ClickEvent, value);
	}
}

イベントルーティング

バブル型とはイベントを最初に発行したVisualObjectから親へ向かって伝播するイベントで、プログラマが実装するユーザーインターフェースに関するイベントの大半がバブル型イベントです。

トンネル型はバブル型の逆で、イベントを最初に発行したVisualObjectから子へ向かって伝わっていくイベントです。アプリケーションの内部ロジックによって発行される事が多く、VisualObjectにアプリケーションの状態を伝える目的で使用する。

直接型は、イベントはターゲットにのみ発行されるイベントで、バブル型やトンネル型のようなイベントのルーティングは行われません。


<Border Height="50" Width="300" BorderBrush="Gray" BorderThickness="1">
	<StackPanel Background="LightGray" Orientation="Horizontal" Button.Click="CommonClickHandler">
		<Button Name="YesButton" Width="Auto" >Yes</Button>
		<Button Name="NoButton" Width="Auto" >No</Button>
		<Button Name="CancelButton" Width="Auto" >Cancel</Button>
	</StackPanel>
</Border>

YesButtonのボタンがクリックされた場合、フレームワークはButtonに対してClickイベントを発行します。
しかし、サンプルのようにClickイベントに対するハンドラがアタッチされていない場合、処理されなかったイベントは親要素であるStackPanelに送られます。

トンネル型イベント

UIElementが次のようなツリー構造の場合に、イベントを発行した際にイベントが伝播していく様子を示したものです。

階層構造を構成
r0
└─r1
    └─r2 (← ここでイベントを発行する)
        └─r3

トンネル型のイベントは次の順番に伝播します。

r0 → r1 → r2

特筆すべきは、r2をイベントソースとしたにもかかわらず、トンネル型のイベントルーティングは上位階層のイベントから呼び出されているということです。

この動作を検証するためのソースコードです。

/// <summary>
/// ButtonBaseから実装をコピー
/// </summary>
class RoutedContent : ContentControl {
	/// <summary>
	/// AddHandler()で追加できるイベントの種類
	/// </summary>
	public static readonly RoutedEvent MyRoutingEvent;
 
	static RoutedContent() {
		MyRoutingEvent = EventManager.RegisterRoutedEvent("MyRouting",
			 RoutingStrategy.Tunnel, // トンネル型のイベントであることを設定
			 typeof(RoutedEventArgs),
			 typeof(RoutedContent));
	}
 
	/// <summary>
	/// CLIイベント
	/// </summary>
	public event RoutedEventHandler MyRouting {
		add {
			base.AddHandler(MyRoutingEvent, value);
		}
		remove {
			base.RemoveHandler(MyRoutingEvent, value);
		}
	}
 
	/// <summary>
	/// イベントの実行
	/// </summary>
	/// <param name="e"></param>
	protected void fire_MyRoutingEvent(RoutedEventArgs e) {
		base.RaiseEvent(e);
	}
 
	/// <summary>
	/// 外部からインスタンスを使ってイベントを発行するための関数
	/// </summary>
	public void fire() {
		RoutedEventArgs e = new RoutedEventArgs(MyRoutingEvent, this);
		fire_MyRoutingEvent(e);
	}
}
class Program {
	[STAThread] 
	static void Main(string[] args) {
		RoutedContent r0 = new RoutedContent();
		r0.Name = "r0";
		RoutedContent r1 = new RoutedContent();
		r1.Name = "r1";
		RoutedContent r2 = new RoutedContent();
		r2.Name = "r2";
		RoutedContent r3 = new RoutedContent();
		r3.Name = "r3";
 
		// 階層構造を構成
		// r0
		// └─r1
		//     └─r2
		//         └─r3
		r0.Content = r1;
		r1.Content = r2;
		r2.Content = r3;
 
		// イベントにアタッチ
		r0.MyRouting += new RoutedEventHandler(onMyRouting);
		r1.MyRouting += new RoutedEventHandler(onMyRouting);
		r2.MyRouting += new RoutedEventHandler(onMyRouting);
		r3.MyRouting += new RoutedEventHandler(onMyRouting);
 
		// ルート要素から2番目に位置する「r2」でイベントを発行する
		r2.fire();
 
		Console.ReadLine();
	}
 
	private static void onMyRouting(object sender, RoutedEventArgs e) {
		ContentControl obj = (ContentControl)sender;
 
		Console.WriteLine("イベント名={0}", e.RoutedEvent.Name);
		Console.WriteLine("リスナーのオブジェクト={0}", obj.Name);
		Console.WriteLine();
	}
}

バブル型イベント

UIElementが次のようなツリー構造の場合に、イベントを発行した際にイベントが伝播していく様子を示したものです。

階層構造を構成
r0
└─r1
    └─r2 (← ここでイベントを発行する)
        └─r3

バブル型のイベントは次の順番に伝播します。

r2 → r1 →r0
/// <summary>
/// ButtonBaseから実装をコピー
/// </summary>
class RoutedContent : ContentControl {
	/// <summary>
	/// AddHandler()で追加できるイベントの種類
	/// </summary>
	public static readonly RoutedEvent MyRoutingEvent;
 
	static RoutedContent() {
		MyRoutingEvent = EventManager.RegisterRoutedEvent("MyRouting",
			 RoutingStrategy.Bubble, // バブル型のイベントであることを設定
			 typeof(RoutedEventArgs),
			 typeof(RoutedContent));
	}
 
	/// <summary>
	/// CLIイベント
	/// </summary>
	public event RoutedEventHandler MyRouting {
		add {
			base.AddHandler(MyRoutingEvent, value);
		}
		remove {
			base.RemoveHandler(MyRoutingEvent, value);
		}
	}
 
	/// <summary>
	/// イベントの実行
	/// </summary>
	/// <param name="e"></param>
	protected void fire_MyRoutingEvent(RoutedEventArgs e) {
		base.RaiseEvent(e);
	}
 
	/// <summary>
	/// 外部からインスタンスを使ってイベントを発行するための関数
	/// </summary>
	public void fire() {
		RoutedEventArgs e = new RoutedEventArgs(MyRoutingEvent, this);
		fire_MyRoutingEvent(e);
	}
}
class Program {
	[STAThread] 
	static void Main(string[] args) {
		RoutedContent r0 = new RoutedContent();
		r0.Name = "r0";
		RoutedContent r1 = new RoutedContent();
		r1.Name = "r1";
		RoutedContent r2 = new RoutedContent();
		r2.Name = "r2";
		RoutedContent r3 = new RoutedContent();
		r3.Name = "r3";
 
		// 階層構造を構成
		// r0
		// └─r1
		//     └─r2
		//         └─r3
		r0.Content = r1;
		r1.Content = r2;
		r2.Content = r3;
 
		// イベントにアタッチ
		r0.MyRouting += new RoutedEventHandler(onMyRouting);
		r1.MyRouting += new RoutedEventHandler(onMyRouting);
		r2.MyRouting += new RoutedEventHandler(onMyRouting);
		r3.MyRouting += new RoutedEventHandler(onMyRouting);
 
		// ルート要素から2番目に位置する「r2」でイベントを発行する
		r2.fire();
 
		Console.ReadLine();
	}
 
	private static void onMyRouting(object sender, RoutedEventArgs e) {
		ContentControl obj = (ContentControl)sender;
 
		Console.WriteLine("イベント名={0}", e.RoutedEvent.Name);
		Console.WriteLine("リスナーのオブジェクト={0}", obj.Name);
		Console.WriteLine();
	}
}

ダイレクト型イベント

UIElementが次のようなツリー構造の場合に、イベントを発行した際にイベントが伝播していく様子を示したものです。

階層構造を構成
r0
└─r1
    └─r2 (← ここでイベントを発行する)
        └─r3

ダイレクト型イベントは伝播しないので、イベントを発行したイベントソースのみが対象になります。

r2

処理済みフラグ(Handled)

ハンドラの引数であるRoutedEventArgsに定義されているHandledプロパティを使用すると、イベントルーティングを制御できます。
ハンドラ内でHandledプロパティをtrueにセットした場合、それ以降のイベントルーティングは呼び出されません。

通常のインターフェース設計ではHostedフラグは明示的にtrueに設定しておく方がよいです。(
たとえば、ButtonコントロールのClickイベントをアタッチした場合、アタッチしたハンドラで目的としたロジックを実装するので、イベントハンドリングによって親がこのイベントを処理する必要はないはずです。

入力イベントのルーティング

入力系のイベントでは、トンネル型とバブル型の2つのイベントタイプが対になって動作しており、この仕組みはユーザーの入力を処理する上で非常に重要な仕組みです。

キーボードからの入力があった場合、イベントソースはトンネル型イベントであるPreviewKeyDownイベントを発行します。

トンネル型イベントのハンドラが呼び出される順はルート要素側から順番なので、イベントソースまでの経路でPreviewKeyDownイベントがHandledされた場合、それ以降の要素にイベントはルーティングされません。
つまり、キーボードからの入力を検証し処理すべきでない場合はHandledフラグをセットすれば、それ以降のイベントとバブル型イベント(KeyDownイベント)が実行されないことを意味します。

イベントルーティングによって各イベントタイプでロジックを棲み分けることができます。

  • トンネル型イベントでは、入力値の検証のためのロジックを実装
  • バブル型イベントでは、入力に対する応答のためのロジックを実装
「イベント」をウィキ内検索
LINE
シェア
Tweet

[Amazon商品]


プログラミング図書館・本館
記事メニュー

C#

  • 新機能
  • 言語文法
    • 型
    • 関数
    • クラス
    • 演算子
    • 構文
    • デリゲート
    • イベント
    • 例外処理
    • アトリビュート
    • 名前空間
    • ジェネリクス
  • リフレクション
  • LINQ

.NET Frameworks

  • 数値
  • 文字列
  • 日付時刻
  • オブジェクト
  • コレクション
  • ファイルシステム
  • スレッド
  • データテーブル
  • グラフィックス
  • デバッグ
    • ログ出力
    • ユニットテスト
  • ユーティリティ
  • ネットワーク
    • HTTP
  • デバイス
    • COMポート
  • EntityFrameworks
    • Code First Programming Model
  • デバイスドライバ
    • WinUSB

WPF

  • XAML
  • イベント
  • コマンド
  • スタイル
  • データバインディング
  • コンポーネント
  • グラフィックス
  • カスタムコンポーネント
    • 依存関係プロパティ

アプリケーション

  • 二重起動の防止
  • アンマネージドDLLの読み込み
  • 外部のアプリケーションを起動

VisualStudio

  • 拡張機能
  • カラー設定

ライブラリ

  • WPFToolkit
  • A Fast CSV Reader
  • AvalonDock

実装方法

  • ドラッグアンドドロップ
  • アプリケーション内のドラッグアンドドロップ
  • CSVからDataTable

minecraft

  • Bukkit
  • プラグイン
    • Permissions
    • SlowHealth
    • CookieMonster
    • iConomy
    • WorldGuard
    • Lockette
    • MyHome
    • BorderGuard

サイトについて

プロフィール/リンク/未分類

メモ/ゲーム/Stacks/Omoikane


更新履歴

取得中です。

ここを編集

記事メニュー2

読んでいる本


Effective C#

QLOOKアクセス解析

ここを編集

人気記事ランキング
  1. アプリケーション内のドラッグアンドドロップ
  2. A Fast CSV Reader
もっと見る
最近更新されたページ
  • 4958日前

    Bukkit
  • 4964日前

    トップページ
  • 4985日前

    メニュー
  • 4995日前

    WPF/グラフィックス
  • 4995日前

    .NET/グラフィックス
  • 4995日前

    .NET/グラフィックス/画像の書き込み
  • 4995日前

    .NET/グラフィックス/画像の読み込み
  • 5001日前

    .NET/コレクション
  • 5019日前

    .NET/WinUSB
  • 5054日前

    BorderGuardプラグイン
もっと見る
人気記事ランキング
  1. アプリケーション内のドラッグアンドドロップ
  2. A Fast CSV Reader
もっと見る
最近更新されたページ
  • 4958日前

    Bukkit
  • 4964日前

    トップページ
  • 4985日前

    メニュー
  • 4995日前

    WPF/グラフィックス
  • 4995日前

    .NET/グラフィックス
  • 4995日前

    .NET/グラフィックス/画像の書き込み
  • 4995日前

    .NET/グラフィックス/画像の読み込み
  • 5001日前

    .NET/コレクション
  • 5019日前

    .NET/WinUSB
  • 5054日前

    BorderGuardプラグイン
もっと見る
ウィキ募集バナー
新規Wikiランキング

最近作成されたWikiのアクセスランキングです。見るだけでなく加筆してみよう!

  1. R.E.P.O. 日本語解説Wiki
  2. VCR GTA3まとめウィキ
  3. ドタバタ王子くん攻略サイト
  4. 機動戦士ガンダム EXTREME VS.2 INFINITEBOOST wiki
  5. ありふれた職業で世界最強 リベリオンソウル @ ウィキ
  6. STAR WARS ジェダイ:サバイバー攻略 @ ウィキ
  7. アサシンクリードシャドウズ@ ウィキ
  8. パズル&コンクエスト(Puzzles&Conquest)攻略Wiki
  9. SYNDUALITY Echo of Ada 攻略 ウィキ
  10. ドラゴンボール Sparking! ZERO 攻略Wiki
もっと見る
人気Wikiランキング

atwikiでよく見られているWikiのランキングです。新しい情報を発見してみよう!

  1. アニヲタWiki(仮)
  2. ストグラ まとめ @ウィキ
  3. ゲームカタログ@Wiki ~名作からクソゲーまで~
  4. oblivion xbox360 Wiki
  5. 初音ミク Wiki
  6. 検索してはいけない言葉 @ ウィキ
  7. SDガンダム ジージェネレーションクロスレイズ 攻略Wiki
  8. Grand Theft Auto V(グランドセフトオート5)GTA5 & GTAオンライン 情報・攻略wiki
  9. 機動戦士ガンダム バトルオペレーション2攻略Wiki 3rd Season
  10. SDガンダム ジージェネレーションジェネシス 攻略Wiki
もっと見る
全体ページランキング

最近アクセスの多かったページランキングです。話題のページを見に行こう!

  1. 参加者一覧 - ストグラ まとめ @ウィキ
  2. 石川啄木 - アニヲタWiki(仮)
  3. バスク・オム - アニヲタWiki(仮)
  4. サイコガンダム - アニヲタWiki(仮)
  5. ムーチョ 文岡 - ストグラ まとめ @ウィキ
  6. ロスサントス警察 - ストグラ まとめ @ウィキ
  7. 魔獣トゲイラ - バトルロイヤルR+α ファンフィクション(二次創作など)総合wiki
  8. 鬼レンチャン(レベル順) - 鬼レンチャンWiki
  9. 柳田 ライアン - ストグラ まとめ @ウィキ
  10. 発車メロディー変更履歴 - 発車メロディーwiki
もっと見る

  • このWikiのTOPへ
  • 全ページ一覧
  • アットウィキTOP
  • 利用規約
  • プライバシーポリシー

2019 AtWiki, Inc.