Потеря событий мыши над полем изображений в c#

#c# #winforms

Вопрос:

У меня есть две панели, одна из которых содержит панель потоков, содержащую миниатюры изображений, а другая (которую я буду называть «панель изображений») содержит поле изображений с полным набором док-станций. Изначально панель изображений скрыта. Когда я нажимаю на одну из миниатюр на панели управления потоком, она скрывает панель управления потоком и отображает панель изображений с полем изображения, в котором отображается полное изображение, связанное с миниатюрой.

В первый раз, когда я нажимаю на миниатюру, все события мыши для picturebox работают должным образом (перемещение мыши и т. Д.). Щелчок правой кнопкой мыши на поле изображения скрывает панель изображений и отображает панель потоков.

В следующий раз, когда я щелкну по миниатюре, ни одно из событий мыши для окна изображения не будет запущено. Когда я нажимаю на изображение, события моей мыши снова работают так, как ожидалось. Я не хочу, чтобы моим пользователям приходилось нажимать на поле с картинками.

Я попробовал использовать picturebox.Focus() и picturebox.Select() , но ни то, ни другое ничего не дало. Я также попытался имитировать щелчок левой кнопкой мыши по этой ссылке, но это тоже не сработало:

Как имитировать щелчок мыши пример кода

Что я должен сделать, чтобы установить «фокус» на picturebox, чтобы события picturebox были подобраны ?

= = = = = = = = РЕДАКТИРОВАТЬ ======= =

В моей форме есть разделительная панель сверху/вниз. Нижняя панель содержит левую/правую разделительную панель. Правая панель содержит панель потока и панель изображений, а проблемное поле изображений находится на панели изображений. В событиях Рисования и щелчка для окна изображения и в событии щелчка для миниатюр на панели потока я пишу this.ActiveControl.Name в консоль. Он всегда показывает название верхней/нижней панели разделителя. Тем не менее, когда я добавляю событие MouseMove на панель разделителя Сверху/вниз, оно никогда не срабатывает, хотя оно постоянно является активным элементом управления для формы.

= = = = = = = = ЕЩЕ ОДНО РЕДАКТИРОВАНИЕ ====== = =

Я собрал способы определения контроля из различных источников. Все они возвращают PictureBox в качестве элемента управления с фокусом, независимо от того, когда я вызываю метод ShowFocus() ниже. Так что, по-видимому, это не проблема «фокусировки».

     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;
    }
 

= = = = = = = = РЕДАКТИРОВАТЬ 3 ==== = === =

На изображении ниже показан вывод Spy , показывающий события мыши до и после щелчка левой кнопкой мыши на поле с изображением. Как ясно видно, дескриптор тот же, и события мыши те же.

События мыши из Spy

Комментарии:

1. Покажите код, не описывайте его.

2. Почему бы вам не подписаться на mouseevents должным образом?

3. Я не думал, что придется отображать изменение видимых свойств панелей и показывать консоль. Запись в событиях MouseMove внесла бы большой вклад в этот вопрос

4. Нам нужно увидеть код, который может воспроизвести проблему. Вы утверждаете, что у вас есть подписка на события, и вы только скрываете и показываете поле с картинками. Это не должно отключать события. Попробуйте воссоздать эту проблему в новом проекте с минимальным кодом. Показывать что.

5. Поверх моей коробки с картинками нарисованы аннотации (поля). Эти аннотации можно перемещать и изменять их размер, поэтому крайне важно, чтобы события мыши в поле изображения запускались. Как бы я подписался на MouseEvents для picturebox, если у него нет фокуса ?

Ответ №1:

Я упомянул в своем первоначальном посте, что имитировал щелчок левой кнопкой мыши, но это не сработало.

Когда я использую два последовательных левых клика, это работает!

Это код левого клика:

     [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);
    }
 

Комментарии:

1. Это не «два последовательных» клика. Это «вниз», за которым следует «вверх», то есть всего один щелчок, разделенный на две разные части. Это все еще не объясняет, почему вы должны «нажать» на поле с картинками; это просто наложение пластыря на проблему. Рад, что вы нашли «решение», хотя.