C#ComboBox GotFocus

时间:2009-10-12 13:36:29

标签: c# wpf combobox focus

我有一个使用WPF的C#ComboBox。我有代码在ComboBox的{​​{1}}被激活时执行。问题是每次从GotFocus进行选择时都会执行GotFocus事件。例如,ComboBox在您第一次点击GotFocus时执行,然后在您进行选择时执行,即使您没有点击任何其他控件。

如果在列表中进行选择,或者事件处理程序中是否有标志或其他可用于确定是否已触发ComboBox事件处理程序的事件,是否可以阻止此事件触发用户选择列表中的项目的结果是什么?

3 个答案:

答案 0 :(得分:13)

您可以通过下一次验证解决此问题:

private void myComboBox_GotFocus(object sender, RoutedEventArgs e)
{
    if (e.OriginalSource.GetType() == typeof(ComboBoxItem))
        return;
    //Your code here
}

此代码将过滤项目中的所有焦点事件(因为它们使用气泡路由事件)。但是还有另一个问题 - WPF ComboBox焦点的特定行为:当您打开包含项目的下拉列表时,您的ComboBox将失去焦点并获得项目。当你选择一些项目 - 失去焦点的项目和ComboBox回来。下拉列表就像另一个控件。您可以通过简单的代码看到这一点:

private void myComboBox_GotFocus(object sender, RoutedEventArgs e)
{
    if (e.OriginalSource.GetType() != typeof(ComboBoxItem))
    {
        Trace.WriteLine("Got " + DateTime.Now);
    }
}

private void myComboBox_LostFocus(object sender, RoutedEventArgs e)
{
    if (e.OriginalSource.GetType() != typeof(ComboBoxItem))
    {
        Trace.WriteLine("Lost " + DateTime.Now);
    }
}

因此,无论如何你都会得到至少两个焦点事件:当你选择ComboBox时以及当你选择它时(焦点将返回ComboBox)。

要在选择项目后过滤返回的焦点,您可以尝试将DropDownOpened / DropDownClosed个事件与某些字段标记一起使用。

所以最终的代码只有1个获得焦点的事件:

private bool returnedFocus = false;

private void myComboBox_GotFocus(object sender, RoutedEventArgs e)
{
    if (e.OriginalSource.GetType() != typeof(ComboBoxItem) && !returnedFocus)
    {
        //Your code.
    }
}

private void myComboBox_LostFocus(object sender, RoutedEventArgs e)
{
    if (e.OriginalSource.GetType() != typeof(ComboBoxItem))
    {
        ComboBox cb = (ComboBox)sender;
        returnedFocus = cb.IsDropDownOpen;
    }
}

从这个示例中选择您的应用程序实际需要的内容。

答案 1 :(得分:0)

我对WPF不太热;但是,如果您尝试检测列表的更改(单击新值等),则可以使用SelectedIndexChanged事件..

另一方面,如果您确实想知道控件何时被聚焦,可以通过说出类似的内容来过滤它吗?

if (combo1.Focused && combo1.SelectedIndex == -1)
{
     ...
}

..?这实际上取决于你想要检测的内容。

答案 2 :(得分:0)

另一种解决方案是确定新的聚焦元素是否是组合框中的现有项目。如果为true,则不应执行LostFocus事件,因为组合框仍然具有焦点。否则,组合框外的元素会获得焦点。

在下面的代码片段中,我在自定义组合框类中添加了功能

public class MyComboBox : System.Windows.Controls.Combobox
{
    protected override void OnLostFocus(RoutedEventArgs e)
    {
        //Get the new focused element and in case this is not an existing item of the current combobox then perform a lost focus command.
        //Otherwise the drop down items have been opened and is still focused on the current combobox
        var focusedElement = FocusManager.GetFocusedElement(FocusManager.GetFocusScope(this));
        if (!(focusedElement is ComboBoxItem && ItemsControl.ItemsControlFromItemContainer(focusedElement as ComboBoxItem) == this))
        {
            base.OnLostFocus(e);
            /* Your code here... */
        }
    }
}