这周我遇到了一个让我陷入困境的问题。总而言之,问题是当我左键单击另一个控件时,我无法从代码中将键盘焦点赋予 ComboBox。
具体来说,我有一个 CustomControll,它有一个 Scrollview,其中包含另一个 CustomControll,还有另一个带有 ComboBox 作为子项的 CustomControll。我将举例说明这一点以使其清楚:
- ScrollView
- DayView (CustomControl)
- ScrollView
- Some irrelevvant controls
- EventEditor (CustomControl)
我想做的是,当用户左键单击或以其他方式选择 TimelineEvent(例如通过创建它)时,通过调用 Keyboard.Focus(myComboBox) 将键盘焦点赋予 ComboBox。当我第一次点击 LMB 时,TimelineEvent 就获得了键盘焦点。第二次单击时,DayView 的父级获得焦点(它是滚动视图)
我无法解释这种行为。我在代码中设置了断点并确保它被执行。我还添加了 OnLostKeyboardFocus、OnGotKeyboardFocus 的侦听器及其对 TImelineEvent、包含它的 ScollView 和组合框的预览。我已经让它将一些日志打印到控制台,这就是我得到的:
[First LMB down on TimelineEvent]
System.Windows.Controls.ScrollViewer got focus
[LMB up]
EDP.EDPTid.CustomControlLibrary.TimelineColumn.TimelineEvent lost focus
EDP.EDPTid.CustomControlLibrary.TimelineColumn.TimelineEvent got focus
The thread '<No Name>' (0x19bc) has exited with code 0 (0x0).
[Second LMB down on the same element]
System.Windows.Controls.ScrollViewer lost focus
System.Windows.Controls.ScrollViewer got focus
[LMB Up]
EDP.EDPTid.CustomControlLibrary.TimelineColumn.TimelineEvent lost focus
EDP.EDPTid.CustomControlLibrary.TimelineColumn.TimelineEvent got focus
System.Windows.Controls.ComboBox Items.Count:29 lost focus
System.Windows.Controls.ComboBox Items.Count:29 got focus
在最后两行,您可以看到 ComboBox 似乎获得了键盘焦点,但是当我按下按键时,很明显它是最上面的滚动视图获得了键盘焦点,我也使用 Snoop 确认了这一点。
以下是在 TimelineEvent.MouseLeftButtonUp 上执行的代码:
public class DayView
{
...
public void SelectEvent(TimelineEvent sender, bool useSpecialFocus)
{
EventEditor.EditedEvent = null;
HideControl(EventEditor);
foreach (TimelineEvent evnt in Timeline.EventContainer.GetEvents())
{
if (sender != null && evnt.Data.Id == sender.Data.Id)
{
EventEditor.EditedEvent = sender;
ShowControl(EventEditor);
evnt.MarkAsSelected(true);
if (evnt.IsMouseOver)
{
evnt.ShowButtons();
}
Expand();
Keyboard.Focus(EventEditor.EventType);
}
else
{
evnt.MarkAsSelected(false);
evnt.HideButtons();
}
}
}
private void HideControl(FrameworkElement control)
{
animator.AnimateOpacity(control.Opacity, 0.0d, new TimeSpan(0, 0, 0, 0, 100), false, control, Visibility.Hidden);
}
private void ShowControl(FrameworkElement control)
{
animator.AnimateOpacity(control.Opacity, 1.0d, new TimeSpan(0, 0, 0, 0, 100), false, control,Visibility.Visible);
control.Visibility = Visibility.Visible;
}
}
public class TimelineEvent
{
...
public void MarkAsSelected(bool selected, bool useSpecialFocus)
{
if (SelectedBorder != null)
{
SelectedBorder.BorderThickness = new Thickness(selected ? 2 : 0);
IsSelected = selected;
Focus();
}
}
}
您可能会注意到的一件事是,我首先调用了 TimelineEvent.Focus(),然后调用 Keyboard.Focus(EventEditor.EventType)。我认为这可能是我的问题的原因,所以我评论了对 Focus out 的调用,它是遗留代码,并不是真正需要的。应用程序开始表现得非常不稳定——大多数仍在 SelectEvent 函数中执行的代码停止工作! EventEditor 没有变得可见,TimelineEvent 没有获得大小为 2 的边框,并且焦点被赋予了源自ExternalCode 的时间轴事件的 Scrollview 父级,因此我无法跟踪调用。
我已经被这个问题困扰了两天,没有获得任何见解,任何帮助将不胜感激。