【问题标题】:Where do I find event declarations in Visual Studio在 Visual Studio 中哪里可以找到事件声明
【发布时间】:2015-07-21 09:06:08
【问题描述】:

我知道 VS 会通过双击一个事件来打开一个事件处理程序存根。 我在按钮所在表单的 InitializeComponent 中找到了底层事件声明。

this.buttonWorkOn.Click += new System.EventHandler(this.buttonWorkOn_Click);

我可以使用这个(Visual Studio 的)事件声明并用它注册另一个事件处理方法吗?

在实例化该其他表单时,其事件处理方法需要使用主表单上按钮的单击事件进行注册。
我不知道如何做到这一点,即使我已经阅读了很多关于代表和事件的内容,并且原则上我确实了解它是如何工作的。

谢谢

【问题讨论】:

  • 您只是想从另一种表单中触发一个事件,对吗?
  • 是的。第二个表单仅在用户输入后创建。但是,我想确保在主窗体上单击某个按钮时它已关闭。我看不出如何使用从 Visual Studio 自动创建的事件声明,然后用它注册这个其他表单的事件处理方法。
  • 对我来说这个问题还不清楚,也许你试图实现的(不工作的)代码示例会有所帮助。此外,您似乎没有完全理解委托、事件和调用它们之间的关系。对于后者,您可能应该查看C# 5.0 Unleashed 第 18 章事件。

标签: c# visual-studio events delegates


【解决方案1】:

如果您在代码编辑器中右键单击事件处理程序并浏览定义,您将找到它的声明方式,然后您可以在自己的代码中使用它。

例如,ButtonClick 事件的声明是:

    public event EventHandler Click;

您可以自己添加这些并从其他地方使用它们来响应您创建的任何类中的事件。

这是一个带有单个按钮(通过设计器添加)的示例表单,单击该按钮将引发其自己的事件:

public partial class Form1 : Form
{
    public event EventHandler ButtonClicked;

    private void RaiseButtonClicked()
    {
        if (ButtonClicked != null)
            ButtonClicked(this, EventArgs.Empty);
    }

    public Form1()
    {
        InitializeComponent();
    }

    private void Button1_Click(object sender, EventArgs e)
    {
        RaiseButtonClicked();
    }
}

然后你可以在另一个类中添加一个处理程序:

public class Responder
{
    public Responder(Form1 form)
    {
        form.ButtonClicked += OnButtonClicked;
    }

    private void OnButtonClicked(object sender, EventArgs args)
    {
        MessageBox.Show("Button was clicked");
    }
}

现在 Responder 类的每个实例都会告诉您何时单击表单上的按钮。

【讨论】:

    【解决方案2】:

    通过“双击一个事件”,Visual Studio 将为您生成一个事件处理程序。您没有看到的是,Visual Studio 还通过在您的设计器文件中添加一行代码来订阅生成的事件处理程序。

    如果是这样的:

    • 双击“点击”事件
    • Visual Studio 打开您的代码文件,您有一个新的button1_clicked 方法,它是您的事件处理程序。
    • 您的设计器已更新为 button1.Clicked += button1_clicked 之类的行

    如果您想要手动订阅事件,您可以在您的代码文件中添加类似<formelement>.<event> += <eventhandler> 的内容。如果您在智能感知中看不到可用事件,您可以随时查看在线文档。 MSDN

    (你不应该改变你的设计文件,因为这是一个生成的文件)

    【讨论】:

      【解决方案3】:

      如果您希望在事件发生时执行多个方法,您可以简单地将它们全部添加到您的代码中(或者您甚至可以多次添加相同的方法):

      private void DoSomething(object source, EventArgs eventArgs)
      {
          Console.WriteLine("Something happened.");
      }
      
      private void DoSomethingElse(object source, EventArgs eventArgs)
      {
          Console.WriteLine("Something else happened.");
      }
      
      private void AttachToEvent()
      {
          button1.Clicked += DoSomething;
          button1.Clicked += DoSomethingElse;
          button1.Clicked += DoSomething;
      }
      

      这会打印出来:

      发生了什么事。

      发生了其他事情。

      发生了什么事。

      【讨论】:

        【解决方案4】:

        好的——这不是我的应用程序,我只是想改进它。
        无论如何,问题是谁拥有谁,谁在哪里可见。

        主窗体上有用于用户输入的控件。
        在 MainForm 上声明了一个“类预览”类型的变量:

        Preview pv
        

        对于 Preview 类,我添加了一个名为 WorkOn 的事件声明:

           public class Preview
            {
                #region "Variables"
                #region "PublicEvent"
        
                public event EventHandler WorkOn;
            }
        

        然后在 MainForm 中,变量 pv(声明为类字段)在方法中被实例化。

        pv = new Preview()
        

        之后检查主窗体控件中的用户输入,并在确定时保存在预览类的变量中。

        然后,PreviewFormpreview 类 中被实例化,拥有类的实例(preview --> as instance pv)作为变量传递给PreviewForm 的实例化。
        我必须创建这个重载的构造函数,因为从 PreviewForm 必须向预览类注册一个事件处理程序才能使其工作 - 正如我意识到的那样。

        formPreview formPreview = new formPreview(this);  
        

        // this --> 是类预览,实例pv

        //FormPreview的实例化

          public formPreview(Preview preview)
            {
              InitializeComponent();
        
              this.preview = preview;
        // now for the event in the preview class an eventhandling method 
        // of the preview form is registered:  
              preview.WorkOn += formPreview_Close;
            }
        

        这是FormPreview的注册方法:

           private void formPreview_Close(object sender, EventArgs e)
            {
                this.Close();
            }
        

        再次提醒我,事件只能从发布事件的类中引发。所以我不得不在类预览中创建一个公共事件引发方法——这里命名为 OnWorkOn

          public void OnWorkOn()
            {
                if (WorkOn != null)
                    WorkOn(this, EventArgs.Empty);
            }
        

        最后我可以从按钮内的 MainForm 触发事件,我计划首先注册 PreviewForm 的事件处理方法。
        只是现在我不得不使用 MainForm 的类变量 pv,因为它是 MainForm 和 PreviewForm 之间的媒介:

        public void buttonWorkOn_Click(object sender, EventArgs e)
        {
            pv.OnWorkOn();  
        // raising the event, informing whoever is registered to it
        //...
        }
        

        所以应用程序的设计不允许直接在 MainForm 上注册预览表单的任何事件处理方法。这就是问题所在,我还没有完全看透整个设计。
        嗯——这是德语 C# 教程的成果——我所知道的唯一一个德语教程。
        你会在这里找到它:
        [https://www.youtube.com/watch?v=-zCiwcgxMHw&list=PLvvL1HRuCBItyw45XnCqEXzuegKQd3MfL][1]
        该代码不再可供下载,但我可以提供它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-03
          • 1970-01-01
          • 2018-05-06
          • 2015-07-20
          • 2014-12-16
          • 1970-01-01
          相关资源
          最近更新 更多