C# 如何在对焦时自动打开组合框?

C# 如何在对焦时自动打开组合框?,c#,winforms,combobox,dropdown,C#,Winforms,Combobox,Dropdown,我有一个Windows窗体,其中包含几个组合框 我想要一个组合框,当它从键盘和鼠标获得焦点时,打开元素列表 组合框类的下拉列表属性管理元素列表的可见性 最适合我需要的事件是Enterone,因此我编写的代码是: private void comboBox1_Enter(object sender, EventArgs e) { this.comboBox1.DroppedDown = true; } 它可以工作,但是当直接单击组合框右侧没有焦点的图标时,元素列表打开,打开后突然消失 我

我有一个Windows窗体,其中包含几个组合框

我想要一个组合框,当它从键盘和鼠标获得焦点时,打开元素列表

组合框
类的
下拉列表
属性管理元素列表的可见性

最适合我需要的事件是
Enter
one,因此我编写的代码是:

private void comboBox1_Enter(object sender, EventArgs e)
{
    this.comboBox1.DroppedDown = true;
}
它可以工作,但是当直接单击组合框右侧没有焦点的图标时,元素列表打开,打开后突然消失

我尝试了很多方法来修复这种奇怪的行为,检查
聚焦的
属性或使用其他事件,如
下拉列表
鼠标单击
,但没有得到任何可接受的结果


在表单构造函数上使用以下代码:


this.comboBox1.GotFocus+=(发送方,参数)=>comboBox1.DroppedDown=true

创建从组合框继承的新类:

public class Combo : ComboBox
{
     protected override void OnClick(EventArgs e)
     {
         if (!DroppedDown) base.OnClick(e);
     }           
}
并在其click调用中
base.OnClick(e)如果没有下拉。
用这个代替组合框。(基本上,如果下拉,单击事件将被忽略)

一种简单的方法(它不会强制您覆盖
组合框
派生控件的
WndProc
)是模拟HitTest,测试鼠标是否在
组合框
按钮区域发生;然后,设置
DroppedDown=true只有在它没有的情况下。

因此,当鼠标单击按钮时,不会产生双重效果,以意外的方式移动焦点(对于控件)

private void comboBox1\u输入(对象发送方,事件参数e)
{
ComboBox combo=发件人作为ComboBox;
如果(!combo.DroppedDown)
{
if(组合指针到客户端(光标位置).X<
combo.ClientRectangle.Width-SystemInformation.VerticalScrollBarWidth)
{
combo.DroppedDown=true;
游标=游标。箭头;
}
}
}

如果我错了,请纠正我,但是“组合框右侧的图标”是一个箭头,是吗?它应该在关闭时打开,在打开时关闭?是的,图标是一个三角形/箭头,它会随着此更改而失去其原始行为。正如@MaxB所说的,当它被下拉(箭头看起来被按下)时,单击它意味着你要关闭它,否则你为什么要单击它?如果你想要一些非常规的功能,你必须创建自己的自定义控件。@AshkanMobayenKhiabani我刚刚编辑了这个问题,因为我的解释不太准确。Sorry@alessaro我的解决方案对您有效吗?可能最好将其更改为:
this.comboBox1.Enter+=(snd,evt)=>{comboBox1.Cursor=Cursors.Arrow;comboBox1.DroppedDown=true;}<如果当前方法是事件处理程序(例如,
Form.Load
),则code>sender
可能会使您与当前方法发生冲突。将光标设置回
箭头
指针,因为在Enter/GotFocus事件中,编辑控件已将其更改为
光束
。但是,它不会解决报告的问题。我也尝试过此解决方案,但它没有解决我的问题。即使我在表单中的Combo对象实例的Click事件中为DroppedDown属性指定true而不是Enter属性,通过键盘(按tab键)聚焦combobox也不会触发该事件。我想你错了,所有代码保持不变,
private void comboBox1_Enter(object sender,EventArgs e){this.comboBox1.DroppedDown=true;}
例如,使用combo classI代替combobox我已经用combo-one替换了combobox对象实例,但是使用Enter事件保持与以前相同的beahviour。
private void comboBox1_Enter(object sender, EventArgs e)
{
    ComboBox combo = sender as ComboBox;
    if (!combo.DroppedDown)
    {
        if (combo.PointToClient(Cursor.Position).X < 
            combo.ClientRectangle.Width - SystemInformation.VerticalScrollBarWidth)
        {
            combo.DroppedDown = true;
            Cursor = Cursors.Arrow;
        }
    }
}