工具条(ToolStripDropDownButton)关闭并失去窗口焦点

时间:2012-12-17 18:10:39

标签: .net vb.net winforms windows-7

我有一个带有ToolStripDropDownButton的ToolStrip。这反过来会弹出一个带有DateTimePicker的UserControl。当我点击日历上的顶部数字(绿色)时,一切正常(用户控制保持打开状态)。当我单击其中一个较低的日期(红色)时,ToolStripDropDown关闭,应用程序失去焦点。这导致用户必须双击才能再次打开DropDown(一次用于关注应用程序,另一次用于打开下拉列表)。

当日历日期不在用户控件之上时,会发生这种情况。如您所见,用户控件在“绿色”日期停止。

我希望这很清楚。这似乎是一个Windows bug,因为这是一个非常简单的项目。谁有人解决这个问题?有没有解决这个问题?

enter image description here

[UPDATE]

下注时我注意到了同样的事情。

enter image description here

用户控件不会发生很大的事情。

enter image description here

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

    Dim uc As New UserControl1
    Dim cms As New ContextMenuStrip()
    cms.Items.Add(New ToolStripControlHost(uc))
    ToolStripButton1.DropDown = cms

End Sub

3 个答案:

答案 0 :(得分:2)

功能,而不是错误。控件需要知道用户在下拉列表外单击,以便它可以自动关闭下拉列表。这是通过Capture属性在Winforms中暴露的“鼠标捕获”完成的。捕获鼠标可确保将鼠标消息发送到控件,即使鼠标不再位于控件窗口内也是如此。

也许很明显现在发生的事情,你实际上并没有点击日历。显示下拉列表后,控件将捕获鼠标。单击将重定向到ToolStripDropDown。当您点击“红色区域”并因此关闭下拉窗口时,会看到鼠标不再位于下拉列表中。

这样的下拉列表实际上只适用于简单的项目,将任何控件放在其中创建一个顶层窗口,比如DateTimePicker或ComboBox就不是支持的场景。

答案 1 :(得分:1)

我无法更改应用程序的行为,所以我决定将窗体的AutoClose设置为False或True,具体取决于控件的事件。

答案 2 :(得分:1)

我通过切换AutoClose以类似的方式解决了这个问题。以为我发布了代码:

    public class ToolStripDropDownDateTimePicker : DateTimePicker
{
    private bool savedAutoClose;

    /// <summary>
    /// Creates a new ToolStripDropDownDateTimePicker.
    /// </summary>
    public ToolStripDropDownDateTimePicker()
    {

    }

    protected override void OnCloseUp(EventArgs e)
    {
        if (this.Parent != null)
        {
            var dropDownHost = this.Parent.Parent as ToolStripDropDown; // recursive instead?
            if (dropDownHost != null)
                dropDownHost.AutoClose = savedAutoClose; // restore the parent's AutoClose preference
        }

        base.OnCloseUp(e);
    }

    protected override void OnDropDown(EventArgs e)
    {
        if (this.Parent != null)
        {
            var dropDownHost = this.Parent.Parent as ToolStripDropDown; // recursive instead?
            if (dropDownHost != null)
            {
                savedAutoClose = dropDownHost.AutoClose;
                // ensure that our parent doesn't close while the calendar is open
                dropDownHost.AutoClose = false;
            }
        }
        base.OnDropDown(e);
    }
}