简体   繁体   English

在 c# 中的 PictureBox 上丢失鼠标事件

[英]Losing Mouse Events over PictureBox in c#

I have two panels, one contains a flowpanel containing image thumbnails and the other (which I will call the "imagepanel") contains a picturebox with Docking set to full.我有两个面板,一个包含一个包含图像缩略图的流程面板,另一个(我将其称为“图像面板”)包含一个带有 Docking 设置为完整的图片框。 Initially, the imagepanel is hidden.最初,图像面板是隐藏的。 When I click on one of the thumbnails on the flowpanel, it hides the flowpanel and displays the imagepanel with the picturebox showing the full image associated with the thumbnail.当我单击流程面板上的其中一个缩略图时,它会隐藏流程面板并显示带有图片框的图像面板,该图片框显示与缩略图关联的完整图像。

The first time I click on the thumbnail, all mouse events for the picturebox work as expected (MouseMove, etc).第一次单击缩略图时,图片框的所有鼠标事件都按预期工作(MouseMove 等)。 Right-clicking the picturebox hides the imagepanel and displays the flowpanel.右键单击图片框隐藏图像面板并显示流程面板。

The next time I click the thumbnail, none of the mousevents for the picturebox are being triggered.下次我单击缩略图时,不会触发图片框的任何鼠标事件。 When I click on the image, my mouse events once again operate work as expected.当我单击图像时,我的鼠标事件再次按预期运行。 I don't want my users to have to click on the picturebox.我不希望我的用户必须点击图片框。

I tried using picturebox.Focus() and picturebox.Select() , but neither of these did anything.我尝试使用picturebox.Focus()picturebox.Select() ,但这些都没有做任何事情。 I also tried to simulate a Left Mouse Click using this link, but it didn't work either:我还尝试使用此链接模拟鼠标左键单击,但它也不起作用:

How to simulate mouse click code example 如何模拟鼠标点击代码示例

What should I do to set "focus" on the picturebox, so that the picturebox events are picked up?我应该怎么做才能在图片框上设置“焦点”,以便拾取图片框事件?

======== EDIT ======== ========编辑========

My form has a Top/Down splitter panel.我的表单有一个上/下拆分面板。 The lower panel contains Left/Right splitter panel.下面板包含左/右拆分器面板。 The Right panel contains the Flow Panel and the ImagePanel, and the troublesome PictureBox is on the ImagePanel. Right panel 包含 Flow Panel 和 ImagePanel,麻烦的 PictureBox 在 ImagePanel 上。 In the Paint and Click events for the PictureBox, and on the Click event for the thumbnails on the flowpanel, I am writing this.ActiveControl.Name to the console.在 PictureBox 的 Paint 和 Click 事件以及流程面板上缩略图的 Click 事件中,我将this.ActiveControl.Name写入控制台。 It always shows the name of the Top/Down splitter panel.始终显示顶部/向下拆分器面板的名称。 Yet, when I add a MouseMove event to the Top/Down splitter panel, it never fires, even though it is consistently the Active Control for the form.然而,当我将 MouseMove 事件添加到 Top/Down 拆分器面板时,它永远不会触发,即使它始终是表单的 Active Control。

======== ANOTHER EDIT ======== ========另一个编辑========

I compiled ways of determining the control from a variety of sources.我编译了从各种来源确定控制的方法。 All of these return the PictureBox as the control with the focus, regardless of when I call the ShowFocus() method below.无论我何时调用下面的 ShowFocus() 方法,所有这些都将 PictureBox 作为具有焦点的控件返回。 So apparently it is not a "Focus" problem.所以显然这不是一个“焦点”问题。

    private void ShowFocus()
    {
        var _C_ = _get_all_controls(this);

        foreach (Control c in _C_)
        {
            if (c.Focused)
                Console.WriteLine(c.Name + " is focused now (ALL)");
        }

        foreach (Control c in this.Controls)
        {
            if (c.Focused)
                Console.WriteLine(c.Name + " is focused now (FORM)");
        }


        Control fc = GetFocusedControl();

        if (fc != null)
            Console.WriteLine("Focused Control: " + fc.Name);
    }

    private IEnumerable<Control> _get_all_controls(Control c)
    {
        return c.Controls.Cast<Control>().SelectMany(item =>
            _get_all_controls(item)).Concat(c.Controls.Cast<Control>()).Where(control =>
            control.Name != string.Empty);
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Winapi)]
    internal static extern IntPtr GetFocus();

    public static Control GetFocusedControl()
    {
        Control focusedControl = null;
        // To get hold of the focused control:
        IntPtr focusedHandle = GetFocus();
        if (focusedHandle != IntPtr.Zero)
            // Note that if the focused Control is not a .Net control, then this will return null.
            focusedControl = Control.FromHandle(focusedHandle);
        return focusedControl;
    }

======== EDIT 3 ======== ========编辑 3 ========

The image below shows the Spy++ output showing mouse events before and after left-clicking the picture box.下图显示了 Spy++ output 显示鼠标左键单击图片框前后的事件。 As is clearly seen, the handle is the same and the mouse events are the same.可以清楚地看到,句柄是一样的,鼠标事件也是一样的。

来自 Spy++ 的鼠标事件

I mentioned in my original post that I was simulating a Left Mouse Click, but that it hadn't worked.我在原始帖子中提到我正在模拟鼠标左键单击,但它没有奏效。

When I use two consecutive LeftMouseClicks, it works!当我使用两个连续的 LeftMouseClicks 时,它起作用了!

This is the LeftMouseClick code:这是 LeftMouseClick 代码:

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    static extern bool SetCursorPos(int x, int y);

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);

    public const int MOUSEEVENTF_LEFTDOWN = 0x02;
    public const int MOUSEEVENTF_LEFTUP = 0x04;

    public static void LeftMouseClick(int xpos, int ypos)
    {
        SetCursorPos(xpos, ypos);
        mouse_event(MOUSEEVENTF_LEFTDOWN, xpos, ypos, 0, 0);
        mouse_event(MOUSEEVENTF_LEFTUP, xpos, ypos, 0, 0);
    }

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

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