Enterキーでフォーカス移動できるようだ。

第10回 WPFの「入力イベントとアニメーション」を学ぼうにある「ビヘイビアの自作」で、サンプルとして挙げられている「FocusMoveBehavior」が、Enterキーによるフォーカス移動を実現している。Expression Blend SDKにある、System.Windows.Inractivity.dllを参照すれば実装できるので、早速組み入れました。が、しかし、上のサンプルだけでは、困ったことになることも判明した。

問題1:ボタンなんかもEnterキーで移動してしまう。
 →いや、それは普通に実行してほしいよね。
問題2:OnDetachingメソッドで終了処理してるけど、画面終了しても、OnDetachingメソッドが実行されないんですけど…
 →いつ通るの?
Enterキーによる移動から除外したい時は結構ある。特にボタンとかDataGridCellとか。
問題1については、添付プロパティを実装することで解消できた。

/// <summary>
/// 移動対象から外すかどうかを取得します。
/// </summary>
/// <param name="obj">対象オブジェクト</param>
/// <returns>true:外す</returns>
public static bool GetExcluded(DependencyObject obj) {
return (bool)obj.GetValue(ExcludedProperty);
}

/// <summary>
/// 移動対象から外すかどうかを設定します。
/// </summary>
/// <param name="obj">対象オブジェクト</param>
/// <param name="value">true:外す</param>
public static void SetExcluded(DependencyObject obj, bool value) {
obj.SetValue(ExcludedProperty, value);
}

/// <summary>移動対象から外すかどうか</summary>
public static readonly DependencyProperty ExcludedProperty =
DependencyProperty.RegisterAttached("Excluded", typeof(bool),
typeof(FocusMoveBehavior), new UIPropertyMetadata(false));
Enterキーによる移動から除外したいコントロールに対して、上記の除外設定を設ける。
こんな感じ

<Window x:Class="TawamureDays.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:TawamureDays"
Title="MainWindow" Height="213" Width="385"
local:WindowBehavior.UseMessageCommand="True"
local:FrameworkElementBehavior.OnLoadedCommand="{Binding LoadedCommand}"
>
<Grid>
<i:Interaction.Behaviors>
<local:FocusMoveBehavior Key="Enter"/>
</i:Interaction.Behaviors>
<StackPanel>
<TextBox Text="Text1"/>
<TextBox Text="Text2"/>
<TextBox Text="Text3"/>
<TextBox Text="Text4"/>
<TextBox Text="Text5"/>
<Button local:FocusMoveBehavior.Excluded="True" Content="Button1"/>
</StackPanel>
</Grid>
</Window

問題2については、画面終了と共に、OnDetachingを呼び出せばいいかなと。


private bool hasBeenAttached_ = false;

private bool hasBeenDetached_ = false;

/// <summary>
/// アタッチされた時の処理
/// </summary>
protected override void OnAttached() {
this.AssociatedObject.PreviewKeyDown +=
new KeyEventHandler(AssociatedObject_PreviewKeyDown);
base.OnAttached();
hasBeenAttached_ = true;

var window = Window.GetWindow(AssociatedObject);
if (window != null) {
window.Closed += new EventHandler(Window_Closed);
}
return;
}

/// <summary>
/// デタッチされたときの処理
/// </summary>
protected override void OnDetaching() {
this.AssociatedObject.PreviewKeyDown -=
new KeyEventHandler(AssociatedObject_PreviewKeyDown);
base.OnDetaching();
hasBeenDetached_ = true;
}

/// <summary>
/// 画面終了時のイベントハンドラ
/// </summary>
/// <param name="sender">イベント発生元</param>
/// <param name="e">イベント引数</param>
private void Window_Closed(object sender, EventArgs e) {
var window = sender as Window;
window.Closed -= new EventHandler(Window_Closed);
window = null;

if (hasBeenAttached_ && !hasBeenDetached_) {
OnDetaching();
}

return;
}

まあ、こんなもんかな。
設定しだいでは、Enterキー以外でもいける感じだけど、大抵Enterキーだよなぁ。Tabはデフォだし。
スポンサーサイト
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0


この記事へのコメント

コメントの投稿

非公開コメント


サイドバー背後固定表示サンプル

当ブログに書かれたソースコードは流用自由です。

バグ、スペルミス等はありうる事です。

ご利用の際は自己責任でお願いしますm(_ _)m