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

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

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


person Simon    schedule 22.06.2009    source источник
comment
Какую графическую библиотеку вы используете? WinForms или WPF?   -  person Josh G    schedule 22.06.2009
comment
Я добавил вкладку winforms из-за многочисленных ссылок на диалоговое окно ctrl-tab и главное окно приложения в виде форм.   -  person Greg D    schedule 22.06.2009


Ответы (4)


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

person JosephStyons    schedule 22.06.2009

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

person Greg D    schedule 22.06.2009

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

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

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

person arbiter    schedule 22.06.2009

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

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

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

Основная форма:

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

Выбор:

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

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

person Jon Comtois    schedule 28.11.2009