Why does setting keyboard focus from code behind require Dispatcher.BeginInvoke?

坚强是说给别人听的谎言 提交于 2019-12-02 05:37:20

could you call Keyboard.Focus(InputTextBox); in the event handler for InputTextBox.IsVisibleChanged instead of this.IsVisibleChanged?

If this works then I suspect the this.IsVisibleChanged event is raised before the layout panel has updated the children controls, i.e perhaps InputTextBox is still not visible when you put focus on it without BeginInvoke.

Probably because the IsVisibleChanged event is raised on another thread (not on the UI thread).

The control you are manipulating belongs to the UI thread (because that is where it was created). All controls derive from DispatcherObject, so control.Dispatcher (or this.Dispatcher from within the control) will give you the reference to the Dispatcher belonging to the thread the control was created on.

You are then queueing an action on that Dispatcher from the background thread that the event handler is running on. Why are you running on a background thread? It is a control so it is at the mercy of its host, at a guess there is some programmatic logic on a background thread that is causing the visibility to change (maybe via data binding), and consequently the event handler is also invoked on that background thread.

In the interests of stopping you from going wild with the Dispatcher and attempting to use it to perform magical mystical feats that it isn't intended for, make sure you familiarise yourself with the Dispatcher.CurrentDispatcher property and its difference (I've seen some truly awful code due to developers not realising this).

For a good overview of the Dispatcher associated with a UI element check this article: MSDN Advanced WPF: Threading Model. Note that sample code that calls VerifyAccess() before attempting the action that manipulates the control.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!