Как я могу предотвратить изменение фокуса при выходе из ShowDialog?

2

Я пытаюсь реализовать альт-tab как поведение для нашего приложения. Когда пользователь нажимает ctrl-tab, появляется всплывающая форма (используя ShowDialog); когда они снова нажимают его, он фокусирует следующий элемент управления в основной форме приложения. Когда они отпускают ctrl, форма скрыта.

К сожалению, когда это происходит, фокус отправляется на другой элемент управления в тот, который был сфокусирован. Как предотвратить изменение фокуса при выходе ShowDialog?

  • 0
    Какую графическую библиотеку вы используете? WinForms или WPF?
  • 1
    Я добавил вкладку winforms из-за многочисленных ссылок на диалог ctrl-tab и главное окно приложения как «формы».
Теги:
winforms
focus

4 ответа

1

Вы можете написать настраиваемое диалоговое окно, которое примет управление "to" focus в качестве свойства.... тогда, когда вы выходите, вы можете настроить фокус на "to".

0

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

Я установил свою основную форму с четырьмя элементами управления (просто кнопки для этого примера могут быть любыми элементами управления, которые вы хотите). Затем я устанавливаю другую форму, которая действует как выбор. В этом примере он просто содержит ListBox с именами элементов управления в нем. Вы могли бы сделать что-то более увлекательное. Вы также можете передать текущий сфокусированный элемент управления, чтобы тот, который уже выбран в списке. Я по умолчанию был первым элементом управления в списке.

Я установил публичное свойство MainForm под названием NextControl, чтобы удерживать выбранный элемент управления в форме Chooser. Я также создал свойство List для хранения ссылок на все элементы управления, которые вы хотите выбрать. Используя этот метод, ShowDialog должен работать нормально, потому что фокус не установлен в элементе управления Next до тех пор, пока не выйдет Dialog.

MainForm:

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

namespace Tabber
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            ControlList = new List<Control>(new Control[] {button1, button2, button3, button4});
        }

        private List<Control> ControlList { get; set; }

        public Control NextControl { get; set; }

        private void MainForm_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Modifiers == Keys.Control && e.KeyCode == Keys.Tab)
            {
                using (var chooseDialog = new Chooser(this, ControlList))
                {
                    if (chooseDialog.ShowDialog() == DialogResult.OK)
                    {
                        if (NextControl != null)
                        {
                            NextControl.Focus();
                        }
                    }
                }
            }
        }
    }
}

Chooser:

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

namespace Tabber
{
    public partial class Chooser : Form
    {
        public Chooser(MainForm sender, List<Control> controls)
        {
            Sender = sender;
            InitializeComponent();

            foreach (Control control  in controls)
            {
                listBox1.Items.Add(control);
            }
            listBox1.DisplayMember = "Name";
            listBox1.SetSelected(0, true);
        }

        private MainForm Sender { get; set; }

        private void Chooser_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Modifiers == Keys.Control && e.KeyCode == Keys.Tab)
            {
                if (listBox1.SelectedIndex == listBox1.Items.Count - 1)
                {
                    listBox1.SetSelected(0, true);
                }
                else
                {
                    listBox1.SetSelected(listBox1.SelectedIndex + 1, true);
                }
                e.Handled = true;
            }
        }

        private void listBox1_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.ControlKey)
            {
                Sender.NextControl = (Control) listBox1.SelectedItem;
                DialogResult = DialogResult.OK;
                Close();
            }
        }
    }
}

Вы можете изменить это в соответствии с вашими потребностями. Это изменило фокус для меня.

0

Вы не должны использовать ShowDialog() для таких целей. Вместо этого вы должны использовать Show() и Hide() с логикой управления внутри вашей основной формы.

Вы также можете захотеть предотвратить активацию формы вообще, в этом случае сделать потомка формы и переопределить метод ShowWithoutActivation.

Вы также можете прочитать мой пост здесь.

0

Возможно, вы захотите изменить способ работы вашего диалога. Если я понимаю, что вы говорите, вместо этого вы можете создать свойство на своем CtrlTabDialog, которое укажет, какой элемент управления должен получить фокус. Затем, когда ShowDialog() завершает работу, прежде чем вы удалите форму CtrlTabDialog, вы можете прочитать это свойство и соответствующим образом настроить фокус из любого кода, порожденного формой.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню