winforms WinForm:使控件不可聚焦

yzxexxkh  于 2023-02-19  发布在  其他
关注(0)|答案(2)|浏览(381)

我的winform包含一个文本框,它是表单的主控件。当我使用CtrL + C时,经常会出现一个空剪贴板,因为出于某种原因,表单的ActiveControl被设置为另一个控件,例如TabControl、SplitContainer等。我尝试将这些控件设置为TabStop = fasle,但是没有用。有没有办法阻止所有控件获得焦点?不仅是关于鼠标点击,还有tab键。

1u4esq0p

1u4esq0p1#

我可以想象尝试一些原生windows消息,如WM_SetFocus,或一些原生windows样式,如WS_TABSTOP,或一些控件样式,如ControlStyles.Selectable,或ControlStyles.UserMouse,但我要说,你不能找到一个通用的解决方案,处理所有的控件。
我在这里建议的(根据你的评论,寻找一种更好的方法来处理焦点,而不是试图让事情变得可聚焦,这在UX的Angular 来看也更有意义)是处理TabControl和SplitterContainer焦点相关的事件:

  • 选项卡控件:处理SelectedIndexChanged,然后将焦点移动到选项卡的第一个可获得焦点的控件。
  • 拆分器容器:处理MouseDown以捕获拆分的开始,然后存储活动面板;稍后处理SplitterMoved并将焦点移动到活动面板的第一个可聚焦控件。

以下是对我起作用的方法:

SplitterPanel activePanel;
private void splitContainer1_SplitterMoved(object sender, SplitterEventArgs e)
{
    splitContainer1.SelectNextControl(activePanel, 
        forward: true, tabStopOnly: true, nested: true, wrap: true);
}
private void splitContainer1_MouseDown(object sender, MouseEventArgs e)
{
    activePanel = splitContainer1.Panel1.ContainsFocus ? splitContainer1.Panel1 :
        splitContainer1.Panel2.ContainsFocus ? splitContainer1.Panel2 : null;
}

private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
    var page = this.tabControl1.SelectedTab;
    page.SelectNextControl(null,
        forward: true, tabStopOnly: true, nested: true, wrap: true);

}
ijnw1ujt

ijnw1ujt2#

不要阻止聚焦,因为这可能会给那些试图只使用键盘导航应用的用户带来问题,而是实现IMessageFilter接口,并为整个应用设置Ctrl-C陷阱,然后您可以简单地手动将“主文本框”的内容放到剪贴板上:

public partial class Form1 : Form, IMessageFilter
{

    public Form1()
    {
        InitializeComponent();
        Application.AddMessageFilter(this);
    }

    bool IMessageFilter.PreFilterMessage(ref Message m)
    {
        if (m.Msg == 0x0100 && 
            (Keys)m.WParam.ToInt32() == Keys.C &&
            ModifierKeys == Keys.Control)
        {
            Console.WriteLine("Ctrl-C Trapped!");
            if (textBox1.SelectionLength > 0)
            {
                Clipboard.SetText(textBox1.SelectedText);
            }
            else
            {
                Clipboard.SetText(textBox1.Text);
            }
            return true;
        }
        return false;
    }

}

相关问题