C#ComboBox GotFocus

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

如果在列表中进行选择,或者事件处理程序中是否有标志或其他内容可用于确定是否由于用户选择而触发了GotFocus事件处理程序,是否可以阻止此事件触发列表中的项目?

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

 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事件与某些field-flag一起使用。

所以最终的代码只有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; } } 

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

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

另一方面,如果你真的想知道控件何时聚焦,你可以通过说出类似的东西来过滤它吗?

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

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

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

在下面的代码片段中,我在自定义combobox类中添加了function

 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... */ } } }