【问题标题】:How can I prevent focus change when ShowDialog exits?ShowDialog 退出时如何防止焦点更改?
【发布时间】:2009-06-22 12:11:34
【问题描述】:

我正在尝试为我们的应用程序实现类似 alt-tab 的行为。当用户按下 ctrl-tab 时,会弹出一个表单(使用ShowDialog);当他们再次按下它时,它会将下一个控件集中在应用程序的主窗体中。当他们释放 ctrl 时,表单被隐藏。

不幸的是,当这种情况发生时,焦点会被发送到与被聚焦的控件不同的控件。 ShowDialog 退出时如何防止焦点更改?

【问题讨论】:

  • 您使用的是哪个图形库? WinForms 还是 WPF?
  • 我添加了 winforms 选项卡,因为多次引用 ctrl-tab 对话框和应用程序的主窗口作为“表单”。

标签: c# .net winforms focus


【解决方案1】:

您可以编写一个接受“to”焦点控件作为属性的自定义对话框......然后在退出时,您可以将焦点设置为“to”控件。

【讨论】:

    【解决方案2】:

    您可能需要考虑更改对话的工作方式。如果我理解您的意思,您可以改为在您的 CtrlTabDialog 上创建一个属性,以指示哪个控件应该获得焦点。然后,当ShowDialog() 退出时,在您处理CtrlTabDialog 表单之前,您可以读取该属性并从最初生成该表单的任何代码中适当地设置焦点。

    【讨论】:

      【解决方案3】:

      您不应将 ShowDialog() 用于此类目的。相反,您应该使用 Show() 和 Hide(),并在主窗体中使用控制逻辑。

      您也可以完全阻止表单激活,在这种情况下,将表单设置为后代并覆盖 ShowWithoutActivation 方法。

      您也可以阅读我的帖子here

      【讨论】:

        【解决方案4】:

        我编写了一个小应用程序,展示了我将如何处理您描述的行为。

        我用四个控件设置了我的主窗体(此示例中只是按钮,可以是您想要的任何控件)。然后我设置了另一个表单作为选择器。对于此示例,它仅包含一个 ListBox,其中包含控件名称。你可以做一些更花哨的东西。您还可以传入当前聚焦的控件,以使该控件已在列表中被选中。我默认为列表中的第一个控件。

        我在 MainForm 上设置了一个名为 NextControl 的公共属性来保存从选择器表单中选择的控件。我还设置了一个 List 属性来保存对您希望能够从中选择的所有控件的引用。使用此方法,ShowDialog 应该可以正常工作,因为焦点不会设置在 Next 控件上,直到该 Dialog 退出之后。

        主窗体:

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

        您可以修改它以满足您的需要。它为我正确地改变了焦点。

        【讨论】:

          猜你喜欢
          • 2011-02-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多