2

我遇到了一个问题,这周一直让我陷入困境。总而言之,问题是当我左键单击另一个控件时,我无法从代码中将键盘焦点赋予 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 父级,因此我无法跟随调用。

我已经被这个问题困扰了两天了,没有获得任何见识,任何帮助都会非常感激。

4

0 回答 0