How to get combobox for the corresponding focus set right after closing the popup

When a user selects values ​​from a combo box, if they select a value, the "SelectionChanged" event fires, and a new value is set and everything is fine. If, however, they decide not to change the value and click elsewhere in the user interface (for example, the text field they want to edit), they need to double-click - the first click simply closes the combobox popup window, and the next click focuses the element that they wanted to activate on the first click.

How can I prevent the combobox from popping the focus target on first click?

I tried to track the ComboBox_LostFocus event, but it fires at the wrong time. When the user clicks on the drop-down list and a pop-up window is displayed, the ComboBox_LostFocus event is triggered - it loses focus for its own drop-down list. I do not want to do anything to change this. When the user then squeezes and the popup closes, the ComboBox never regains focus (the focus is simply “lost” for everything), and therefore this event is useless.

+5
source share
2 answers

, . Comboboxes DropDownClosed - , RoutedEvent, ComboBoxes EventSetter. ( 'DropDownClosed' must be a RoutedEvent registered with a name that ends with the keyword "Event")

Loaded - RoutedEvent, :

<Style x:Key="ComboBoxCellStyle" TargetType="ComboBox">
    <EventSetter Event="Loaded" Handler="ComboBox_Loaded" />
</Style>

, , , - ComboBox, , :

private void ComboBox_Loaded(object sender, RoutedEventArgs e)
{
    ((ComboBox)sender).DropDownClosed -= ComboBox_OnDropDownClosed;
    ((ComboBox)sender).DropDownClosed += new System.EventHandler(ComboBox_OnDropDownClosed);
}

, , DropDown, , , , ComboBox. :

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();
    }
}

ComboBox DataCell GridView, DataRow , ComboBox, .

. , . , , . , DropDownClosed. , , _Loaded.

+5

DropDownClosed:

private void comboBox_DropDownClosed(object sender, EventArgs e)
{
    Point m = Control.MousePosition;
    Point p = this.PointToClient(m);
    Control c = this.GetChildAtPoint(p);
    c.Focus();
}

, . TextBox, , , , . ComboBox, , . , , , .

EDIT: , WPF! ; WinForms. , DropDownClosed WPF.

2: , . WPF, , , TextBox, . WPF MainWindow. DropDown comboBox, , MainWindow:

private void comboBox_DropDownClosed(object sender, EventArgs e)
{
    Point m = Mouse.GetPosition(this);
    VisualTreeHelper.HitTest(this, new HitTestFilterCallback(FilterCallback),
        new HitTestResultCallback(ResultCallback), new PointHitTestParameters(m));
}

private HitTestFilterBehavior FilterCallback(DependencyObject o)
{
    var c = o as Control;
    if ((c != null) && !(o is MainWindow))
    {
        if (c.Focusable)
        {
            c.Focus();
            return HitTestFilterBehavior.Stop;
        }
    }
    return HitTestFilterBehavior.Continue;
}

private HitTestResultBehavior ResultCallback(HitTestResult r)
{
    return HitTestResultBehavior.Continue;
}
+2

All Articles