У меня есть WPF UserControl, который содержит StackPanel, который становится видимым в результате изменения состояния. Когда StackPanel становится видимым, я хочу установить фокус клавиатуры на определенный дочерний TextBox. Я обнаружил (после многих проб и ошибок), что вызов TextBox.Focus () не сможет установить фокус (и вернет false), если я не оберну этот вызов в вызове BeginInvoke, как показано здесь:
private void CtlClientLookupPanel_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) {
LogThreadMsg(string.Format("CtlClientLookupPanel_IsVisibleChanged to {0}", CtlClientLookupPanel.Visibility));
if (CtlClientLookupPanel.Visibility == Visibility.Visible) {
Dispatcher.BeginInvoke((ThreadStart)delegate {
bool gotFocus = CtlClientSearchText.Focus();
LogThreadMsg(string.Format("CtlClientSearchText.Focus() returned {0}", gotFocus));
});
}
}
private void LogThreadMsg(string msg) {
string fullMsg = string.Format("Thread: {0} - {1}", Thread.CurrentThread.ManagedThreadId, msg);
System.Diagnostics.Trace.WriteLine(msg);
}
Оба вызова LogThreadMsg указывают, что они находятся в одном потоке (UI), как показано здесь:
[5232] Thread: 1 - CtlClientLookupPanel_IsVisibleChanged to Visible
[5232] Thread: 1 - CtlClientSearchText.Focus() returned True
Так зачем нужен этот "взлом"? Кажется, это какая-то временная проблема, и я искал последующее событие, которое, возможно, было бы лучшим местом для вызова Focus (), не прибегая к этому, но не нашло его. Кто-нибудь может объяснить, что здесь происходит?