LoginSignup
9
11

More than 5 years have passed since last update.

MVVMでコレクション内のコントロールにフォーカスを当てるときにつまづいた件

Last updated at Posted at 2016-01-10

Livetを利用している場合、ViewModelからメッセージを投げることで任意のコントロールにフォーカスを当てることができる。例えば、ViewModelからMessenger.Raise(new InteractionMessage("FocusToTextBox"));という形でメッセージを投げて、Viewでは下記のように受け取る

           <TextBox>
                <i:Interaction.Triggers>
                    <l:InteractionMessageTrigger Messenger="{Binding Messenger}" MessageKey="FocusToTextBox" >
                        <l:SetFocusAction />
                    </l:InteractionMessageTrigger>
                </i:Interaction.Triggers>
            </TextBox>

ただ、この方法ではコレクションの任意のコントロールに対してフォーカスを当てたいときにうまくいかないパターンがあった。例えば、何らかのコレクションを表示していて、あるボタンを押下したときに「要素を末尾に追加+追加した要素内のコントロールにフォーカスを当てる」という動きを実現したいとき、上記の方法ではフォーカスを当てることができない(そもそもInteractionMessageTriggerがメッセージを受け取れてないっぽい)。

処理の流れとして
1. コレクションに要素が追加される
2. 追加した要素のViewModelからメッセージを投げる
3. View上のコントロールが追加される
となってしまっている気がする。ので、なんとかして2と3の処理の順番を入れ替えたい。
悩んで導き出した解決方法が、Dispatcherを利用して非同期にフォーカスを当てる方法。

DispatcherHelper.UIDispatcher.BeginInvoke(new Action(() => Messenger.Raise(new InteractionMessage("FocusToName"))), DispatcherPriority.Background);

DispatcherPriorityをBackgroundに指定することで、要素追加のバインド処理が完了してからメッセージを投げることができるようになった。

※検証用のソースはここのFocusタブにおいてます

9
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
11