繁体   English   中英

当控件处于模式对话框上时,WinForms控件的子窗体不响应鼠标事件

[英]WinForms control's child form doesn't respond to mouse events when control is on modal dialog

我需要标准ComboBox中不存在的功能,因此我从TextBox和表单中编写了自己的功能。 当用户在TextBox中键入内容时,它会以单独的形式显示下拉列表。

以下是一些相关代码:

internal class FilteredDropDown : Form
{
    public Control OwnerControl { get; set; }
    public bool CloseOnLostFocus { get; set; }
    protected override OnLostFocus(EventArgs e)
    {
        if (CloseOnLostFocus && !OwnerControl.IsFocused)
            this.Close();
    }
    protected override OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e)
         // highlight the moused over item in the list
    }

    ...
}
public class FilteredCombo : TextBox
{
    private FilteredDropDown dropDown;
    public FilteredCombo()
    {
        dropDown = new FilteredDropDown();
        dropDown.OwnerControl = this;
    }
    public void ShowDropDown()
    {
        if (dropDown.Visible)
            return;
        dropDown.RefreshFilter();
        var loc = PointToScreen(new Point(0, this.Height));
        dropDown.Location = loc;
        dropDown.CloseOnLostFocus = false;
        int selectionStart = this.SelectionStart;
        int selectionLength = this.SelectionLength;
        dropDown.Show(this);
        this.Focus();
        this.SelectionStart = selectionStart;
        this.SelectionLength = selectionLength;
        dropDown.CloseOnLostFocus = false;
    }
    protected override OnLostFocus(EventArgs e)
    {
        if (dropDown.Visible && !dropDown.ContainsFocus())
            dropDown.Close();
    }
    protected override OnTextChanged(EventArgs e)
    {
        base.OnTextChanged(e);
        ShowDropDown();
    }
    ...
}

显然有比这更多的代码来处理与我的问题无关的各种事情。

问题是当我将FilteredCombo放在模式对话框上时。 当以模式对话框为父级时,以某种方式,FilteredDropDown表单根本不会收到鼠标事件。

我已经读过一些有关WinForms过滤掉除当前模式对话框之外的所有事件的信息,我怀疑这是怎么回事,但是我不知道如何解决它。 有什么方法可以使鼠标向上/向下/移动/单击/等。 由模型对话框作为父项时起作用的事件?

我必须仔细研究ShowDialog源代码,发现它在除所示窗口之外的所有窗口上都调用user32.dll EnableWindow(Handle,false)。 问题在于,到ShowDialog()方法被调用时,FilteredDropDown已经存在。 我发现了两种不同的解决方法:

  1. 在显示父表单之前,不允许显示DropDown。 要保证这有点棘手,所以我也实现了第二种方法。

  2. 将其变为可见后,重新启用DropDown窗口:

     [DllImport("user32.dll")] private static extern bool EnableWindow(IntPtr hWnd, bool enable); protected override void OnVisibleChanged(EventArg e) { base.OnVisibleChanged(e); if (this.Visible) { EnableWindow(this.Handle, true); } } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM