Проблемы фокуса / выбора с ToolStripContainer - PullRequest
0 голосов
/ 03 марта 2019

У меня есть Form, который содержит:

  • не менее 2 Control с, которые реализуют интерфейс и доступны для выбора - при загрузке формы виден только первый элемент управления (каждый из них Control s имеет обработчик MouseDown, который Select s или фокусируется сам);
  • полоса инструментов, которая содержит пользовательский ToolStripItem, например, ползунок (панель треков) для масштабирования;
  • трекбар масштабирования работает на текущем фокусе Control, который реализует этот интерфейс (пользователь может щелкнуть по одному из элементов управления, а трекбар запоминает проценты масштабирования для каждого из двух элементов управления и обновляется сам, чтобы соответствовать проценту масштабирования текущего фокусируемого элемента управления);
  • все перечисленное выше находится внутри ToolStripContainer.

При загрузке формы первый Control фокусируется автоматически.Затем:

  1. Я делаю второй элемент управления видимым, и
  2. Я нажимаю на второй Control,
  3. . Он получает фокус.

Если затем I:

  1. Снова нажмите на первый элемент управления,
  2. Не фокусируется.

Если:

  1. Форма теряет фокус, а затем
  2. Форма получает фокус, нажимая на первую Control,
  3. Первая Control получает фокус;
  4. Второй элемент управления затем фокусируется на щелчке по нему без необходимости расфокусировать форму.

Проблема, похоже, заключается в том, что статический метод FindControlWithFocus не понимает элемент управления ToolStripContainer.Он ищет в нем сфокусированный элемент управления и не находит его (хотя ToolStripContainer - единственный прямой дочерний элемент управления в моем Form).

Код

У меня естьобработчик событий, связанный со всеми событиями Enter всех элементов управления в форме, включая форму.В этом обработчике я вызываю FindControlWithFocus с этим элементом управления в качестве параметра, чтобы найти наиболее близкий к поверхности (не глубокий) элемент управления, имеющий фокус.

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

public static Control FindControlWithFocus(Control parent)
{
    if (parent.Focused)
    {
        return parent;
    }

    foreach (Control ctl in parent.Controls)
    {
        if (ctl.Focused)
        {
            return ctl;
        }

        Control child = FindControlWithFocus(ctl);

        if (child != null)
        {
            return child;
        }
    }

    return null;
}

private void Ce_FocusedControlChanged(object sender,
    FocusMovedEventArgs e)
{
    Control c = Utils.FindControlWithFocus(e.FocusedControl);

    while (c != null && // (a)
        !Utils.TypeImplements(c.GetType(), typeof(IClocksView)))
    {
        c = c.Parent;
    }

    if (c != null) // (b)
    {
        LastFocusedTimersView = c as IClocksView;
    }
}

Точки

  1. В строке, отмеченной (a) выше: Control that got focus: {e.FocusedControl}; Surfacemost element with focus: {c};

  2. В строке, отмеченной (b) выше: surfacemost parent that is IClocksView: {c}

На выходеПанель У меня есть эти строки в начале программы (пока я не начну нажимать):

Control that got focus: {System.Windows.Forms.ToolStripContainer}; Surfacemost element with focus: null;
surfacemost parent that is IClocksView: null
Control that got focus: {System.Windows.Forms.ToolStripContentPanel, BorderStyle: System.Windows.Forms.BorderStyle.None}; Surfacemost element with focus: null;
surfacemost parent that is IClocksView: null
Control that got focus: {Text = "F&ull-screen" CheckState = Unchecked}; Surfacemost element with focus: null;
surfacemost parent that is IClocksView: null
Control that got focus: {cs_timed_silver.MainForm, Text: Timed Silver - new file}; Surfacemost element with focus: {Text = "F&ull-screen" CheckState = Unchecked};
Control that got focus: {cs_timed_silver.MainForm, Text: Timed Silver - new file}; Surfacemost element with focus: {System.Windows.Forms.ToolStripContentPanel, BorderStyle: System.Windows.Forms.BorderStyle.None};
Control that got focus: {cs_timed_silver.MainForm, Text: Timed Silver - new file}; Surfacemost element with focus: {System.Windows.Forms.ToolStripContainer};
Control that got focus: {cs_timed_silver.MainForm, Text: Timed Silver - new file}; Surfacemost element with focus: {cs_timed_silver.MainForm, Text: Timed Silver - new file};
Control that got focus: {cs_timed_silver.MainForm, Text: Timed Silver - new file}; Surfacemost element with focus: null;
surfacemost parent that is IClocksView: null

Когда я нажимаю на второй Control, вывод:

Control that got focus: {System.Windows.Forms.TableLayoutPanel, BorderStyle: System.Windows.Forms.BorderStyle.None}; Surfacemost element with focus: {ClockDataGridView ID = 1};
surfacemost parent that is IClocksView: {ClockDataGridView ID = 1}
Control that got focus: {SplitterView: TimerGroupListView & SplitterView}; Surfacemost element with focus: {ClockDataGridView ID = 1};
surfacemost parent that is IClocksView: {ClockDataGridView ID = 1}
Control that got focus: {System.Windows.Forms.SplitterPanel, BorderStyle: System.Windows.Forms.BorderStyle.None}; Surfacemost element with focus: {ClockDataGridView ID = 1};
surfacemost parent that is IClocksView: {ClockDataGridView ID = 1}
Control that got focus: {SplitterView: ClockListView & ClockDataGridView}; Surfacemost element with focus: {ClockDataGridView ID = 1};
surfacemost parent that is IClocksView: {ClockDataGridView ID = 1}
Control that got focus: {System.Windows.Forms.SplitterPanel, BorderStyle: System.Windows.Forms.BorderStyle.None}; Surfacemost element with focus: {ClockDataGridView ID = 1};
surfacemost parent that is IClocksView: {ClockDataGridView ID = 1}
Control that got focus: {ClockDataGridView ID = 1}; Surfacemost element with focus: {ClockDataGridView ID = 1};
surfacemost parent that is IClocksView: {ClockDataGridView ID = 1}
Control that got focus: {System.Windows.Forms.Panel, BorderStyle: System.Windows.Forms.BorderStyle.None}; Surfacemost element with focus: {System.Windows.Forms.DataGridViewComboBoxEditingControl, Items.Count: 2};
Control that got focus: {System.Windows.Forms.Panel, BorderStyle: System.Windows.Forms.BorderStyle.None}; Surfacemost element with focus: {System.Windows.Forms.Panel, BorderStyle: System.Windows.Forms.BorderStyle.None};
Control that got focus: {System.Windows.Forms.Panel, BorderStyle: System.Windows.Forms.BorderStyle.None}; Surfacemost element with focus: {ClockDataGridView ID = 1};
surfacemost parent that is IClocksView: {ClockDataGridView ID = 1}
Control that got focus: {System.Windows.Forms.DataGridViewComboBoxEditingControl, Items.Count: 2}; Surfacemost element with focus: {System.Windows.Forms.DataGridViewComboBoxEditingControl, Items.Count: 2};
Control that got focus: {System.Windows.Forms.DataGridViewComboBoxEditingControl, Items.Count: 2}; Surfacemost element with focus: {System.Windows.Forms.Panel, BorderStyle: System.Windows.Forms.BorderStyle.None};
Control that got focus: {System.Windows.Forms.DataGridViewComboBoxEditingControl, Items.Count: 2}; Surfacemost element with focus: {ClockDataGridView ID = 1};
surfacemost parent that is IClocksView: {ClockDataGridView ID = 1}
Control that got focus: {System.Windows.Forms.Panel, BorderStyle: System.Windows.Forms.BorderStyle.None}; Surfacemost element with focus: {System.Windows.Forms.DataGridViewComboBoxEditingControl, Items.Count: 2};
Control that got focus: {System.Windows.Forms.Panel, BorderStyle: System.Windows.Forms.BorderStyle.None}; Surfacemost element with focus: {System.Windows.Forms.Panel, BorderStyle: System.Windows.Forms.BorderStyle.None};
Control that got focus: {System.Windows.Forms.Panel, BorderStyle: System.Windows.Forms.BorderStyle.None}; Surfacemost element with focus: {ClockDataGridView ID = 1};
surfacemost parent that is IClocksView: {ClockDataGridView ID = 1}
Control that got focus: {System.Windows.Forms.DataGridViewComboBoxEditingControl, Items.Count: 2}; Surfacemost element with focus: {System.Windows.Forms.DataGridViewComboBoxEditingControl, Items.Count: 2};
Control that got focus: {System.Windows.Forms.DataGridViewComboBoxEditingControl, Items.Count: 2}; Surfacemost element with focus: {System.Windows.Forms.Panel, BorderStyle: System.Windows.Forms.BorderStyle.None};
Control that got focus: {System.Windows.Forms.DataGridViewComboBoxEditingControl, Items.Count: 2}; Surfacemost element with focus: {ClockDataGridView ID = 1};
surfacemost parent that is IClocksView: {ClockDataGridView ID = 1}

Когда я нажимаю на первую Control без предварительной расфокусировки формы, вывод:

Control that got focus: {System.Windows.Forms.TableLayoutPanel, BorderStyle: System.Windows.Forms.BorderStyle.None}; Surfacemost element with focus: null;
surfacemost parent that is IClocksView: null
Control that got focus: {SplitterView: ClockListView & ClockDataGridView}; Surfacemost element with focus: null;
surfacemost parent that is IClocksView: null
Control that got focus: {System.Windows.Forms.SplitterPanel, BorderStyle: System.Windows.Forms.BorderStyle.None}; Surfacemost element with focus: null;
surfacemost parent that is IClocksView: null
Control that got focus: {ClockListView ID = 1}; Surfacemost element with focus: null;
surfacemost parent that is IClocksView: null
Control that got focus: {cs_timed_silver.ClockFlowLayoutPanel, BorderStyle: System.Windows.Forms.BorderStyle.None}; Surfacemost element with focus: null;
surfacemost parent that is IClocksView: null

Проблема в том, что в последней строке выше значение равно null.Мне нужно, чтобы это было {ClockListView ID = 1}.

...