我的UserControl
包含TextBox
。当用户控件变为可见时,我会给出TextBox
焦点。有人可以澄清为什么我必须使用Dispatcher
吗?
public MyUserControl()
{
InitializeComponent();
this.IsVisibleChanged += VisibilityChanged;
}
案例1(有效):
private void VisibilityChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (this.Visibility == Visibility.Visible)
{
this.Dispatcher.BeginInvoke((Action)delegate
{
Keyboard.Focus(this.InputTextBox);
}, DispatcherPriority.Render);
}
}
案例2(不起作用):
private void VisibilityChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (this.Visibility == Visibility.Visible)
{
Keyboard.Focus(InputTextBox);
}
}
答案 0 :(得分:3)
您可以在Keyboard.Focus(InputTextBox);
而不是InputTextBox.IsVisibleChanged
的事件处理程序中调用this.IsVisibleChanged
吗?
如果这样可行,那么我怀疑在布局面板更新了子控件之前引发了this.IsVisibleChanged
事件,也就是说当你将注意力集中在InputTextBox
时,BeginInvoke
仍然不可见}。
答案 1 :(得分:2)
可能是因为IsVisibleChanged
事件是在另一个线程上引发的(而不是在UI线程上)。
答案 2 :(得分:1)
您正在操作的控件属于UI线程(因为它是创建它的位置)。所有控件都派生自DispatcherObject,因此control.Dispatcher
(或控件中的this.Dispatcher
)将为您提供对属于创建控件的线程的Dispatcher的引用。
然后,您将从运行事件处理程序的后台线程对该Dispatcher上的操作进行排队。你为什么要在后台线程上运行?它是一个控件,所以它受其主机的支配,猜测后台线程上有一些编程逻辑导致可见性发生变化(可能通过数据绑定),因此也会调用事件处理程序背景线程。
为了阻止你与Dispatcher狂野并试图用它来执行它不适合的神奇神秘功能,请确保你熟悉Dispatcher.CurrentDispatcher属性及其差异(由于开发人员没有意识到这一点,我看到了一些非常糟糕的代码。
有关与UI元素关联的Dispatcher的概述,请查看以下文章:MSDN Advanced WPF: Threading Model。请注意,在尝试操作控件的操作之前调用VerifyAccess()
的示例代码。