问题
I'm having a problem that has been driving me up the wall this week. Summarized, the issue is that i am unable to give keyboard focus to a ComboBox from code when i left click on another control.
To be specific, i have a CustomControll which has a Scrollview with another CustomControll in it and a another CustomControll with a ComboBox as children. I'll illustrate this to make it clear:
- ScrollView
- DayView (CustomControl)
- ScrollView
- Some irrelevvant controls
- TimelineEvent (CustomControl)
- Some irrelevvant controls
- ScrollView
- EventEditor (CustomControl)
- ComboBox
- DayView (CustomControl)
What i am trying to do is to give keyboard focus to the ComboBox by calling Keyboard.Focus(myComboBox) when a user left clicks or otherwise selects a TimelineEvent (by for example creating it). What happens is with my first LMB click, the TimelineEvent gets keyboard focus. With the second click, the parent of DayView receives focus (it's a scroll view)
I can't explain this behavior. I've made breakpoints in the code and made sure that it gets executed. I've also added listeners to OnLostKeyboardFocus, OnGotKeyboardFocus and their Previews to the TImelineEvent, the ScollView that contains it, and the combo box. I've made it print some logs to the console, and this is what i get:
[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
At the last two rows you can see that it seems the ComboBox got keyboard focus, but when i press the keys, it becomes obvious that it is the topmost scrollview that gets keyboard focus, i have also confirmed it using Snoop.
Here is the code that executes on 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();
}
}
}
One thing you might notice is that i have a call to TimelineEvent.Focus() first and then call Keyboard.Focus(EventEditor.EventType). I thought this might be the cause to my problem, so i commented the call to Focus out, it's legacy code and not really needed. The application started to behave very erratically - most of the code which still executed in the SelectEvent function stopped working! The EventEditor didn't become visible, the TimelineEvent didn't get a size 2 border, and focus was given to the Scrollview parent of the Timeline Event originating from ExternalCode, so i could not follow the call.
I've been stuck with this problem for two days now with no insight gained, any help will be greatly appriciated.
来源:https://stackoverflow.com/questions/19248464/wpf-cant-control-keyboard-focus