Установка фокуса, когда родительское окно верхнего уровня элемента управления является активным окном? - PullRequest
0 голосов
/ 04 мая 2018

Я работаю над проектом на C #. Проблема заключается в том, что фоновые события, такие как указатель мыши, делают фоновое окно всплывающим в фокусе, когда оно не является активным окном. Стратегия решения состоит в том, чтобы добавить предупредительные шаги перед установкой этого фокуса.

Мои попытки включают следующую стратегию:

До вызова control.Focus() я хочу реализовать условие, включающее функцию GetActiveWindow() , чтобы соответствовать дескриптору окна, связанному с родительским элементом верхнего уровня элемента управления. Для последнего я использую Control.TopLevelControl(). Но каждый раз, когда я делаю это, я получаю null за это свойство. Причина, указанная в справочнике MSDN , заключается в том, что элемент управления не связан с формой.

Попытка фрагмента:

if (myControl.TopLevelControl.Handle == GetActiveWindow())
{
     this.myControl.Focus();
}

Фон для кода: Этот код не принадлежит мне. Итак, простите меня за то, что я абстрагирован. Я постараюсь быть максимально сложным. Соответствующим элементом управления является закрытая пользовательская панель макета, которая наследуется от System.Windows.Forms.Panel, где свойство DoubleBuffered имеет значение true. Этот элемент управления был добавлен во внутренний частичный класс, который наследуется от UserControl (Windows Forms). Последний элемент управления был добавлен через закрытый член SplitContainer (Windows Forms) в открытый частичный класс (также наследуется от пользовательского элемента управления).

В конструкторе пользовательского элемента управления для этой панели макета добавляется четное число:

myLayoutPanel.MouseEnter += this.myLayoutPanel_MouseEnter;

Событие без моего изменения выглядит так:

private void myLayoutPanel_MouseEnter(object sender, EventArgs e)
    {
        myLayoutPanel.SuspendLayout();
        myLayoutPanel.Focus();
        myLayoutPanel.ResumeLayout(false);
    }

Кроме того, я вручную наблюдал на дескрипторах родительскую иерархию элемента управления и никогда не мог найти соответствие с активным дескриптором окна. Интуитивно, я чувствую, что GetActiveWindow() использует взаимодействие для углубления в неуправляемый код, чтобы получить дескриптор, в то время как свойство верхнего уровня остается в управляемой зоне и, таким образом, имеет свои ограничения. Хотя я могу ошибаться.

У кого-нибудь есть мысли по этому поводу?

1 Ответ

0 голосов
/ 07 мая 2018

Есть два уровня «фокусировки». Одним из них является «фокус» Control внутри формы. И одним из них является «фокус» формы внутри всей композиции окон на рабочем столе.

Элемент управления использует следующие элементы:

Форма использует следующие члены:

Если вы установите фокус для управления внутри формы (через Focus () ), фокус будет ограничен только формой, и состояние формы не изменится. Если вы также хотите установить фокус на форму, вам нужно активировать (через Activate () ) форму.

Этот минимальный код для воспроизведения этого поведения:

public class MyControl : FlowLayoutPanel {
    private TextBox textBox1;
    private TextBox textBox2;

    public MyControl() {
        this.textBox1 = new TextBox();
        this.Controls.Add(this.textBox1);

        this.textBox2 = new TextBox();
        this.Controls.Add(this.textBox2);

        this.BackColor = Color.Blue; // not required

        this.MouseEnter += this.MyControl_MouseEnter;
    }

    private void MyControl_MouseEnter(object sender, EventArgs e) {
        this.textBox1?.Focus(); // sets focus to the control

        var parentForm = this.FindForm();
        parentForm?.Activate(); // activates the form
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...