ComboBox で IME を ON にする
ComboBox で IME を ON にするには、<ComboBox InputMethod.PreferredImeState="On" /> のように……書いても ON にはなりません!ムカッ。
半日掛かりで実現できました(´;ω;`) まあ、WPF の知識不足なんですが…。
前のエントリの XAML の最後にある、ComboBox の GotFocus イベントハンドラを下のようにするとできました。
private void Combo_GotFocus( object sender, RoutedEventArgs e ) { var textbox = FindVisualChild<TextBox>( this.Combo ); InputMethod.SetPreferredImeState( textbox, InputMethodState.On ); } private childItem FindVisualChild<childItem>( DependencyObject obj ) where childItem : DependencyObject { for ( int i = 0; i < VisualTreeHelper.GetChildrenCount( obj ); i++ ) { DependencyObject child = VisualTreeHelper.GetChild( obj, i ); if ( child == null ) continue; childItem target = child as childItem; if ( target != null ) return target; childItem childOfChild = FindVisualChild<childItem>( child ); if ( childOfChild != null ) return childOfChild; } return null; }
FindVisualChild メソッドは MSDN ライブラリのサンプルコード をちょっといじったもの。
コンボボックスのビジュアルツリーに一つしかテキストボックスがないことを期待したコードになってしまっています。本当は XAML でテキストボックスに Style BasedOn="{StaticResource ComboBoxEditableTextBox}" として InputMethod.PreferredImeState を追加したかったんだけど、どうしても見つからないと言われてあきらめました(追記)BasedOnを間違って理解していたので削除。←のようにしてもコンボボックスは変わらない(/追記)。せめて、コンボボックスクラスの TemplatePartAttribute で指定されているテキストボックスの名前である PART_EditableTextBox を使って検索したかったんだけど、FindName じゃ見つからないと言われました。どっちも今の自分には理由がさっぱりわからないけど、とりあえずの仮バージョンとしては上のコードでいいのかなぁと思ってます。
コンボボックスにテキストボックスが複数あったら期待通りに動かないのでそこのとこよろしく。もっと確実な方法があったら教えてくださいね!
ところで、テキストボックスでさえコントロールの合成でできてるんだね。びっくりした。