【问题标题】:ComboBox not losing focus组合框不会失去焦点
【发布时间】:2010-11-16 04:55:22
【问题描述】:

我在使用 ComboBox 控件时遇到了问题。我不是 GUI 专家,但我知道这个问题与控件的焦点有关。

由于某种原因,当我在 ComboBox 外部单击时,它不会失去焦点。比如说:

  1. 我单击 ComboBox 以列出其项目。
  2. 我选择了一项。这将关闭 ComboBox。
  3. 我单击第二个 ComboBox,第一个保持焦点。

  1. 单击组合框(包含点、实体和线框)。
  2. 点击表格。按 P、S 或 W。查看选择是否已更改。

请注意,ComboBox 仅将 DropDownStyle 设置为 ComboBoxStyle.DropDownList。这意味着它是默认的 ComboBox 行为。我认为默认行为是当您单击 ComboBox 或单击另一个控件(按钮或 ComboBox)时,它会失去焦点。这里不是这样,为什么?

更新: 我需要的是某种 ActiveComponent = null。如果您在标准工具栏中选择 Debug 或 Release (ComboBox),则该行为应类似于 Visual Studio 的行为。目前,如果我在 ComboBox 外部单击,它仍然是焦点。

【问题讨论】:

  • 我试过了,我看不到这种行为的痕迹。您使用的是哪个版本的框架?
  • 您是否设置了任何属性使其无法显示为焦点?允许选择?
  • 我建议您从头开始创建另一个表单,看看行为是否不同。然后在当前表格和新表格之间做一个差异来看看 - 是什么原因?

标签: c# .net winforms combobox


【解决方案1】:

我的做法如下。

第 1 步 - 创建一个返回表单上所有给定控件的方法

    public IEnumerable<Control> GetAllControls(Control control, Type type)
    {
        var controls = control.Controls.Cast<Control>();
        return controls.SelectMany(ctrl => GetAllControls(ctrl, type))
                                  .Concat(controls)
                                  .Where(c => c.GetType() == type);
    }

第 2 步 - 创建自定义事件

    private void ChangeComboFocus(object sender, EventArgs e)
    {
        SendKeys.Send("{TAB}");
    }

第 3 步 - 最终在表单加载时绑定事件

    private void ClientRegistrationForm_Load(object sender, EventArgs e)
    {
        var comboxes=_Helper.GetAllControls(this, typeof(ComboBox)).ToList();
        if (comboxes != null)
        {
            foreach (ComboBox item in comboxes)
            {
                item.SelectedIndexChanged +=new EventHandler(this.ChangeComboFocus) ;
            }
        }
    }

【讨论】:

    【解决方案2】:
     private void drp_KeyPress(object sender, KeyPressEventArgs e)
            {
                if (e.KeyChar == 13)
                {
                    SendKeys.Send("{TAB}");
                }
            }
    

    或使用

    控制离开功能的这段代码:

     private void drp_Leave(object sender, KeyPressEventArgs e)
                {
    
                        SendKeys.Send("{TAB}");
    
                }
    

    【讨论】:

    • 请详细说明这段代码是如何回答这个问题的。
    • 如果我们有两个控件,例如组合框和另一个网格...标记 tabindex 1 为组合框,2 为网格...然后从组合框中选择值并按回车...然后选项卡键用于在组合框的情况下起作用,因此组合框失去焦点和焦点上的网格。
    【解决方案3】:
    1. SendKeys.Send("{ESC}")之后; ComboBox 仍然重新获得焦点;

    2. 在组合框上将 CausesValidation 设置为 false 对我也没有帮助。

    我是这样解决这个问题的:

    假设您有另一个控件,例如System.Windows.Forms.PictureBox pbxChart,并且用户希望在更改combobox (selecting by Left Click or MouseWheel) 中的值后将焦点移到那里。 所以我补充说:

        private void pbxChart_Click(object sender, EventArgs e)
        {
            pbxChart.Focus();
        }
    

    MouseClick EventHandler,解决了这个问题。

    【讨论】:

      【解决方案4】:

      我知道这篇文章已经有一段时间了,但也许它会帮助将来遇到同样问题的人。我为此苦苦挣扎了几天,但终于弄明白了。

      如果您将 CauseViolation 设置为 false,那么您并没有解决问题并且数据绑定停止工作。

      当你介意 SelectedItem 到这样的属性时

      combobox.DataBindings.Add("SelectedItem", someObject, "MySelectedItemProperty", false, DataSourceUpdateMode.OnPropertyChanged)
      

      组合框调用您在分配给您的数据源的列表中使用的对象的 Equals 方法。在我的例子中,我需要在这个对象中覆盖 Equals 方法。无论出于何种愚蠢的原因,组合框都会调用此方法并在实际传递正确的对象类型进行比较之前传递 System.DBNull。这是我的案例中发生违规并导致违规失败的地方,因此不会从组合框中释放光标。另外奇怪的是,当我的 Equals 方法中出现异常时,程序并没有停止。

      一旦我添加了这段代码

       if (obj.GetType() != this.GetType())
             return false;
      

      对于我的 Equals 方法,一切正常。希望它可以帮助某人。

      【讨论】:

        【解决方案5】:

        组合框取值的字典,类型索引,类型值,类型索引必须与绑定在组合框上的类属性中的类型相同。如果类型不同,组合框永远不会失去焦点。

        【讨论】:

          【解决方案6】:

          ***form.Designer.vb 中,每个组合框都有一些代码,例如:

          'OrgDetailsIDComboBox
          '
          Me.OrgDetailsIDComboBox.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.MedicoLegalBindingSource, "OrgDetailsID", True))
          Me.OrgDetailsIDComboBox.DataBindings.Add(New System.Windows.Forms.Binding("SelectedValue", Me.MedicoLegalBindingSource, "OrgDetailsID", True))
          Me.OrgDetailsIDComboBox.DataSource = Me.OrgBindingSource
          Me.OrgDetailsIDComboBox.DisplayMember = "Place"
          

          我通过注释掉第一行代码解决了这个问题(包括字符串Forms.Binding("Text", )。所以似乎只需要SelectedValue 的语句。

          【讨论】:

            【解决方案7】:

            你所要做的就是:

            1. 进入组合框的属性窗口
            2. 并设置 Allow Drop="true"

            该属性用于其他目的,但也适用于这种情况。

            【讨论】:

            • 我遇到了同样的问题,TextBox 是 UserControl 上唯一可聚焦的控件。设置AllowDrop=true 神奇地解决了这个问题。
            【解决方案8】:

            我遇到了类似的问题,但是控件递归地失去和重新获得焦点; LostFocus 事件处理程序被调用,但控件立即重新获得焦点。将CausesValidation 属性设置为false 无效。

            在我的例子中,我绑定到自定义对象时绑定到了SelectedValue 属性而不是Text 属性。因为我手动指定了 ComboBox 项集合并且没有提供数据源,所以ValueMember 属性丢失或无效(所以SelectedValue 属性当然没有用。)

            将我的绑定更改为使用 Text 属性解决了这个问题。

            【讨论】:

            • 出于我的目的,我最终选择了 SelectedItem 而不是 Text,因为显然 TextChanged 事件仅在通过鼠标而不是键盘选择集合项时触发。无论输入设备如何,SelectedIndexChanged 似乎都会触发。
            【解决方案9】:

            尝试离开事件而不是 LostFocus。
            尝试输入事件而不是 GotFocus。

            【讨论】:

              【解决方案10】:

              我遇到了类似的问题,并尝试了你们建议的所有方法。不幸的是,它们都不起作用。这是我的“简单”解决方案:更改 SelectedIndex 后发送“ESC”键。

              ComboBox1_SelectedIndexChanged(object sender, System.EventArgs e)
              {
              # do whatever you were doing
              ...
              ...
                SendKeys.Send("{ESC}");
              }
              

              它对我有用。

              【讨论】:

              • 我的解决方案是设置 ActiveControl = null;而不是使用 SendKeys.Send("{ESC}");。它完成了这项工作,并且在代码方面更简洁,但对这种行为进行编码并不是我所期望的。
              【解决方案11】:

              您可能想看看This topic。尝试在组合框上将 CausesValidation 设置为 false,看看是否可以保留它。如果在 OnValidating 事件处理程序中抛出异常,它不会取消选中该框。

              【讨论】:

                【解决方案12】:

                您确定问题不是因为您的框架或其他组合框都无法获得焦点吗?

                【讨论】:

                  【解决方案13】:

                  那你到底在说什么?你是说你的 _LostFocus() 事件处理程序没有被调用吗?如果是这样,我首先要看的是您的设计器生成的事件处理程序映射代码。有时,通过在设计器中做某些事情来解除关联(不过现在很少见了……)

                  【讨论】:

                  • 我没有为 ComboBox 定义任何自定义 Leave 事件,但如果我这样做并设置断点,我可以看到它显然没有被调用。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-10-02
                  • 1970-01-01
                  • 2021-04-15
                  • 1970-01-01
                  相关资源
                  最近更新 更多