Событие Control.Enter не срабатывает при переключении задач. Есть ли альтернатива, которая делает? - PullRequest
1 голос
/ 01 октября 2008

Реп шаги:

  1. создать пример приложения .NET form
  2. поместите TextBox в форму
  3. связывает функцию до события Enter TextBox

Когда вы запускаете это приложение, событие Control.Enter срабатывает, когда фокус сначала переходит к TextBox. Однако, если вы щелкнете в другое приложение, а затем снова вернетесь в тестовое приложение, событие не сработает снова.

То есть перемещение между приложениями не вызывает Enter / Leave .

Есть ли другое альтернативное Control-level событие, которое я могу использовать, которое сработает в этом сценарии?

Обычно я использовал бы Форма. Активировано . К сожалению, это неприятно, потому что мой компонент размещен в системе стыковки, которая может отсоединить мой компонент в новую форму, не уведомляя меня.

Ответы [ 10 ]

3 голосов
/ 01 октября 2008

Что вы пытаетесь сделать в событии Enter?

Я не могу найти другое событие уровня элемента управления, которое запускается в вашей примерной программе, но когда мое тестовое приложение восстанавливает фокус, элемент управления, который последний раз имел фокус, все еще имеет его.

Интересный вопрос, но нужно немного больше контекста.

1 голос
/ 03 октября 2008

Если я попробую ваш пример и щелкну за пределами элемента управления в другом окне, на рабочем столе и т. Д., Я могу запустить события Got и Lost Focus, но если вы только пытаетесь щелкнуть внутри формы или элемента управления только с 1 контроль, это событие не будет никогда , потому что это единственное, на чем нужно сосредоточиться. Не будет введен или оставлен, если вы не измените динамику или не перегрузите элементы управления, вы не сможете этого добиться

0 голосов
/ 24 августа 2015

в этом примере, если вы переключаетесь между щелчками по текстовым полям, ни ввод, ни получение фокуса не будут работать, как ожидалось, однако, если вы нажмете дочерние формы, вместо этого оба будут вести себя как ожидалось.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;

    namespace EnterBrokenExample
    {
        static class Program
        {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);

                Form Form1 = new Form();
                Form c1 = new Form();
                Form c2 = new Form();

                Form1.IsMdiContainer = true;

                c1.MdiParent = Form1;
                c2.MdiParent = Form1;

                c1.Show();
                c2.Show();

                TextBox tb1 = new TextBox();
                c1.Controls.Add(tb1);
                tb1.Enter += ontbenter;
                tb1.Text = "Some Text";
                tb1.GotFocus += ongotfocus;

                TextBox tb2 = new TextBox();
                c2.Controls.Add(tb2);
                tb2.Enter += ontbenter;
                tb2.Text = "some other text";
                tb2.GotFocus += ongotfocus;

                Application.Run(Form1);
            }
            static void ontbenter(object sender, EventArgs args)
            {
                if (!(sender is TextBox))
                    return;
                TextBox s = (TextBox)sender;
                s.SelectAll();
            }

            static void ongotfocus(object sender, EventArgs args)
            {
                if (!(sender is TextBox))
                    return;
                TextBox s = (TextBox)sender;
                s.SelectAll();
            }
        }
    }
0 голосов
/ 02 октября 2008

Вы пробовали просто простой Control.GotFocus?

0 голосов
/ 02 октября 2008

Думаю, мне было не ясно.

Мой элемент управления живет в контейнерном приложении. Так делают другие несвязанные элементы управления другими командами. Думайте об этом как о Visual Studio - мой элемент управления - это вкладка редактирования кода, но есть также список ожидающих изменений и окно свойств, которые сожительствуют с исходными файлами, но не имеют прямого отношения.

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

Поддержка этой ссылки "LastFocusedGrid" - это то, что я делаю в событии Enter.

Если вы хотите увидеть похожую функциональность на работе в visual studio, попробуйте следующее:

  1. открыть несколько исходных файлов
  2. перейдите на вкладку «Стартовая страница».
  3. Нажмите Ctrl-F и найдите в «текущем документе» строку
  4. Обратите внимание, что функция поиска автоматически выполняет переход к исходному файлу LAST FOCUSED для выполнения поиска.

Таким образом, даже если вы не сфокусировались на исходном файле, команда ctrl-F была обработана Visual Studio и перенаправлена ​​на последнюю выделенную вкладку исходного файла.

Теперь попробуйте то же самое с Ctrl-G. Он не работает, если вы не сфокусированы непосредственно на исходном файле.

Мои клавиатурные команды должны работать здесь как Ctrl-F, а не как Ctrl-G. Вот почему я не просто фиксирую события клавиатуры непосредственно в моем элементе управления.

Это проясняет или усугубляет ситуацию?

0 голосов
/ 01 октября 2008

Похоже, что проблема, с которой вы столкнулись, не связана напрямую с событием Enter, а более конкретно: если у вас есть элементы управления, «которые не имеют ничего общего с вашим кодом», то вы действительно не смотрите событие уровня управления.

0 голосов
/ 01 октября 2008

Фрай, проблема в том, что сочетания клавиш должны работать независимо от того, где находится пользователь в приложении. Это глобальные команды, которые обрабатываются на верхнем уровне, а затем направляются в «последнюю сфокусированную сетку».

Таким образом, обработка нажатий клавиш на уровне сетки не поможет.

Точнее, предположим, что пользователь запускает сетки A, B и C. Но он также запускает другие элементы управления X, Y и Z, которые не имеют ничего общего с моим кодом.

Пользователь нажимает на A, затем на C. Затем он нажимает на Y, затем на Z. Сосредоточившись на Z, он нажимает на мою комбинацию клавиш. В этом случае сетка C должна отвечать, поскольку это была последняя сетка, на которой фокусировался пользователь.

0 голосов
/ 01 октября 2008

Итак, при создании сетки вы не можете установить событие KeyPressed, KeyUp и т. Д.? Если это так, все сетки могут использовать один и тот же обработчик событий. Просто убедитесь, что когда вы попадаете в обработчик событий, вы делаете что-то вроде:

Grid currentGrid = (Grid)sender;

Тогда вы сможете применить этот блок кода к любой отправляемой сетке, не беспокоясь о том, чтобы отслеживать.

Поскольку все обработчики событий на самом деле таковы, его местоположение действительно является точкой отключения, пока все, что вам нужно для его выполнения, доступно.

0 голосов
/ 01 октября 2008

Спасибо, я дам немного фона.

Мой элемент управления - это UserControl, который содержит сетку и панель инструментов. Пользователь обычно запускает несколько из этих элементов управления для просмотра различных фрагментов системных данных.

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

Поэтому я связал функцию с событием Control.Enter моего UserControl, чтобы в основном сказать LastFocusedGrid = this.

И это сработало бы, кроме стыковки и расстыковки ...

Видите, эти элементы управления размещены внутри приложения с функциями стыковки, чем-то похожими на Visual Studio.

По умолчанию элемент управления запускается как вкладка в основной рабочей области приложения, аналогично тому, как исходный файл открывается в Visual Studio.

Однако пользователь может «вырвать» вкладку, взяв заголовок вкладки и вытащив его из основного приложения. На этом этапе приложение создает новую «форму с плавающей точкой» для размещения элемента управления. Переключение между основным приложением и этой плавающей формой такое же, как переключение между приложениями для целей событий Control.Enter и Form.Activation.

В этот момент у нас есть сценарий «один элемент управления в форме», смоделированный с помощью примера приложения, описанного в исходном посте.

Теперь, есть несколько способов обойти это. Я мог бы использовать событие Form.Activation, которое срабатывает при переключении между формами. Если вы добавите событие в тестовом приложении в событие Активированная форма, вы увидите, что оно отлично работает.

Проблема в том, что отношения моего UserControl с его родительской формой изменчивы, что делает решение несколько сложным. Я попытался подключиться к «this.ParentForm.Activation», который работал хорошо. Проблема в том, когда ты это называешь? Что происходит, когда вы расстыкованы? В итоге я получил неприятный код с такими вещами, как «previousParentForm», так что я мог отсоединиться от старой формы, а затем я все еще сталкивался с проблемой, что система стыковки не уведомляет меня, когда моя родительская форма изменяется, так что мне тоже нужно было сделать кучу изменений.

Эти проблемы не являются неразрешимыми, но если существует более простое событие «родительская форма активирована», то это будет намного элегантнее.

Это довольно долго, но я надеюсь, что это прояснит ситуацию.

0 голосов
/ 01 октября 2008

В вашем примере, я думаю, вам нужен другой элемент управления. Причина в том, что первый элемент управления (tabIndex 0) - это элемент с фокусом. Без какого-либо другого элемента управления, на который можно переключить фокус, этот элемент управления всегда будет фокусироваться, и поэтому никогда не будет введен. Переключение на другое приложение или форму не изменит фокус или активный элемент управления в этой форме, поэтому при возврате вы все равно не получите событие.

С добавленными элементами управления control.entered должна работать нормально. Если это ваш единственный элемент управления, почему бы не вызвать событие в formLoad или TextChanged, когда форма получает фокус?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...