C# Windows窗体:检测聚焦控件的更改

C# Windows窗体:检测聚焦控件的更改,c#,.net,winforms,C#,.net,Winforms,我正在Windows窗体应用程序中实现复制粘贴。 当用户更改应用程序中的焦点元素时,我需要启用/禁用这两个操作的条形按钮 我可以使用如下内容找到当前的焦点控件:,但是如何检测焦点控件已更改?我认为应该向控件添加事件处理程序(或者如果有许多相同类型的事件处理程序,则将其子类化,并重写相应的OnChange处理程序)。这样,您就不必“查找”焦点控件(它将作为发送方参数提供),事件只会在实际发生更改时出现。我的建议是使用Application.Idle事件 在Application.Idle事件中启

我正在Windows窗体应用程序中实现复制粘贴。 当用户更改应用程序中的焦点元素时,我需要启用/禁用这两个操作的条形按钮


我可以使用如下内容找到当前的焦点控件:,但是如何检测焦点控件已更改?

我认为应该向控件添加事件处理程序(或者如果有许多相同类型的事件处理程序,则将其子类化,并重写相应的
OnChange
处理程序)。这样,您就不必“查找”焦点控件(它将作为发送方参数提供),事件只会在实际发生更改时出现。

我的建议是使用Application.Idle事件

  • 在Application.Idle事件中启用/禁用按钮的写入逻辑
  • 订阅应用程序。表单上的空闲事件显示事件
  • 在按钮点击时检查按钮可用性(这样您就不会在重载情况下通过意外点击)
  • 不要忘记在表单处理(或关闭)时删除空闲处理程序,因为这是静态事件

使用这种技术,您将始终拥有正确的按钮状态,并且您不必担心订阅许多控件事件来检测焦点更改。这也是一种轻量级方法,因为只有当应用程序不忙时才会引发Idle事件。

在表单加载事件处理程序中,您还可以循环遍历表单中包含的所有控件,并为每个可聚焦控件为Enter事件添加一个事件处理程序:

    private void Form1_Load(object sender, EventArgs e)
    {
        foreach (Control control in Controls)
        {
            control.Enter += ControlReceivedFocus;
        }
    }

    void ControlReceivedFocus(object sender, EventArgs e)
    {
        Debug.WriteLine(sender + " received focus.");
    }

要检测控件上的焦点,可以创建此事件:

void MyGotFocus(object sender, EventArgs e)
{
    if (sender is TextBox)
    {
        //TODO YOUR OPERATION
        //FOR EXAMPLE
        (sender as TextBox).SelectAll();
    }
}
下一步是通过代码关联控件和事件:

myText1.GotFocus += MyGotFocus;
myText2.GotFocus += MyGotFocus;

我已经做了很多次了(虽然这与sztomi的答案基本相同,我喜欢你提供了一个代码示例),这是最好的解决方案。尽管如此,您还需要ControlostFocus(或ControlValidating,具体取决于您正在执行的操作)来禁用菜单项。您可能还需要迭代子控件。。。
if(control.haschilds)
…要递归并将事件处理程序附加到所有子控件,请签出