如何获得组合框设置适当的焦点后直接弹出关闭组合、弹出、如何获得、适当

2023-09-08 09:12:19 作者:被人遗忘

当用户从一个组合框中选择值,如果他们选择的值,则的SelectionChanged事件触发和新的值被设置,一切都很好。但是,如果他们决定不更改值,然后单击其他位置上的用户界面(像他们想编辑一个文本框),他们必须单击两次 - 第一次点击干脆关闭组合框弹出,接下来点击将专注于元素他们想激活第一次点击。

When the user is selecting values from a combobox, if they choose a value, the "SelectionChanged" event fires and the new value is set and everything's fine. If, however, they decide not to change the value and click elsewhere on the UI (like a text box they want to edit), they have to click twice - the first click simply closes the combobox popup, and the next click will focus the element they wanted to activate on the first click.

我怎样才能prevent劫持的聚焦目标上的第一个点击这样的组合框弹出?

How can I prevent the combobox popup from hijacking the focus target on the first click like that?

我已经试过监测ComboBox_LostFocus事件,但该大火在错误的时间。当用户点击下拉和弹出列表的显示方式,ComboBox_LostFocus事件触发 - 它失去焦点到它自己的下拉列表中。我不想做任何事情来改变这种状况。当用户再点击路程,弹出关闭,组合框永远不会重新获得焦点(对焦仅仅是丢失的一切)等本次活动是没有用的。

I've tried monitoring the ComboBox_LostFocus event, but this fires at the wrong time. When the user clicks the dropdown and the popup list is displayed, the ComboBox_LostFocus event fires - it's losing focus to it's own dropdown list. I don't want to do anything to change that. When the user then clicks away and the popup closes, the ComboBox never regains focus (focus is just 'lost' to everything) and so this event is useless.

推荐答案

我想我可能已经找到了解决办法。组合框也有一个DropDownClosed事件 - 问题是,它不是一个RoutedEvent,因此你不能创建组合框的样式,让他们都通过EventSetter继承的事件。 (你得到错误DropDownClosed必须与关键字事件结尾的名称注册的RoutedEvent)

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")

不过,加载活动的是的一个RoutedEvent,所以我们可以挂接到,在款式:

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

我有一个组合框作为DataCell在一个GridView的模板,这个特殊的问题是$ P $从结束编辑,当用户突然打开一个组合框,然后点击电网之外pventing DataRow中。

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.

这是我最大的问题,这个bug。一个次要问题,将焦点设置在此事件中的当且仅当的用户点击。该组合框也可能刚刚被关闭,因为用户按下tab键或逃避的,所以我们不能只SETFOCUS到鼠标位置。我们要的是什么导致了DropDownClosed事件触发的更多信息。大概意思挂钩到在_Loaded事件处理程序更未布线的事件。

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.