我遇到了一个问题,这周一直让我陷入困境。总而言之,问题是当我左键单击另一个控件时,我无法从代码中将键盘焦点赋予 ComboBox。
具体来说,我有一个 CustomControll,它有一个 Scrollview,其中有另一个 CustomControll,另一个 CustomControll 有一个 ComboBox 作为子项。我将对此进行说明以使其清楚:
- 滚动视图
- 日视图(自定义控件)
- 滚动视图
- 一些无关紧要的控制
- 时间线事件(自定义控件)
- 一些无关紧要的控制
- 滚动视图
- 事件编辑器(自定义控件)
- 组合框
- 日视图(自定义控件)
我想要做的是当用户左键单击或以其他方式选择 TimelineEvent(例如创建它)时,通过调用 Keyboard.Focus(myComboBox) 将键盘焦点赋予 ComboBox。我的第一次 LMB 单击会发生什么,TimelineEvent 获得键盘焦点。通过第二次单击,DayView 的父级获得焦点(它是一个滚动视图)
我无法解释这种行为。我在代码中设置了断点并确保它被执行。我还向 TImelineEvent、包含它的 ScollView 和组合框添加了 OnLostKeyboardFocus、OnGotKeyboardFocus 和它们的预览的侦听器。我已经让它打印了一些日志到控制台,这就是我得到的:
[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 的 Timeline Event 的 Scrollview 父级,因此我无法跟随调用。
我已经被这个问题困扰了两天了,没有获得任何见识,任何帮助都会非常感激。