I think I might have found a solution. Comboboxes do have a DropDownClosed event - the problem is it isn't a RoutedEvent, so you can't create a style for ComboBoxes and have them all inherit the event via an EventSetter. (You get the error 'DropDownClosed' must be a RoutedEvent registered with a name that ends with the keyword "Event"
)
However, the Loaded
event is a RoutedEvent, so we can hook into that in the style:
<Style x:Key="ComboBoxCellStyle" TargetType="ComboBox">
<EventSetter Event="Loaded" Handler="ComboBox_Loaded" />
</Style>
Now that we have an event that will always fire before anything else is done with the ComboBox, we can hook into the event we actually care about:
private void ComboBox_Loaded(object sender, RoutedEventArgs e)
{
((ComboBox)sender).DropDownClosed -= ComboBox_OnDropDownClosed;
((ComboBox)sender).DropDownClosed += new System.EventHandler(ComboBox_OnDropDownClosed);
}
Now that I finally have access to the event that fires when the DropDown is closing, I can perform whatever actions I need to make sure the focus is terminated on the bothersome ComboBox. In my case, the following:
void ComboBox_OnDropDownClosed(object sender, System.EventArgs e)
{
FrameworkElement visualElement = (FrameworkElement)sender;
while( visualElement != null && !(visualElement is DataCell) )
visualElement = (FrameworkElement)visualElement.TemplatedParent;
if( visualElement is DataCell )
{
DataCell dataCell = (DataCell)visualElement;
dataCell.EndEdit();
if( !(dataCell.ParentRow is InsertionRow) ) dataCell.ParentRow.EndEdit();
}
}
I had a ComboBox as the template of a DataCell in a GridView, and this particular problem was preventing the DataRow from ending edit when the user popped open a ComboBox then clicked outside of the grid.
That was my biggest problem with this bug. A secondary problem setting the focus in this event iff the user clicked. The combobox might also have just been closed because the user hit tab or escape though, so we can't just setfocus to the mouse position. We'd need more information on what caused the DropDownClosed event to fire. Probably means hooking into more unrouted events in the _Loaded event handler.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…