【问题标题】:Trouble with raising custom event handling between 2 forms在 2 个表单之间引发自定义事件处理的问题
【发布时间】:2015-02-12 18:18:50
【问题描述】:

C# 新手。就像标题一样,我在尝试提出事件时遇到了困难。它最终会以另一种形式消费。

我想要做的是创建一个 tcp 客户端、连接然后关闭的自定义用户控件(我的事件引发表单)的许多实例。当此 tcp 客户端出现“错误”时,无论是捕获异常,我都希望引发一个事件。我现在通过关闭互联网进行测试来强制错误。我的第一个问题是我什至根本无法提出该事件。我将在自定义用户控件上显示我正在使用的事件代码:

public delegate void TaskCompleteEventHandler(object sender, TaskCompleteEventArgs e);
public event TaskCompleteEventHandler TaskComplete;



public class TaskCompleteEventArgs : System.EventArgs
{
    // add local member variables to hold text
    private string errorString;

    // class constructor
    public TaskCompleteEventArgs(string ErrorString)
    {
        this.errorString = ErrorString;
    }

    // Property
    public string ErrorString
    {
        get
        {
            return errorString;
        }
        set
        {
            errorString = value;
        }
    }
}

这是我处理异常的方法,理想情况下会引发事件并允许主机表单相应地打印字符串和异常。

private void ErrorLogging(string ex)
    {
        errorString = String.Format(/*...errorString formatting...*/);

        // instance the event args and pass it the errorString value  
        TaskCompleteEventArgs args = new TaskCompleteEventArgs(errorString);

        // raise the event with the updated arguments
        TaskComplete(this, args);  //----> THIS IS WHERE I GET AN ERROR!! <----
        this.Dispose();
    }

错误是Object reference not set to an instance of an object. 这是我的TaskComplete(this, args) 的手表屏幕

我似乎无法调试这个...我只是不够强大,还不知道我做错了什么。它是如何引起副作用的?

我确定当我开始执行此操作时,我的主窗体上会出现更多问题......有人知道是什么原因造成的吗?提前致谢。


编辑:在我的主要表单上:

    public Form1()
        {
            InitializeComponent();

            // Start control disabled and subscribe each control the event
            foreach (var control in controlList)
            {
                control.Enabled = false;
                control.TaskComplete += new dev_emu_project.dev_emu_widget.TaskCompleteEventHandler(OnTaskComplete);
            }
        }

   List<dev_emu_project.dev_emu_widget> controlList = new List<dev_emu_project.dev_emu_widget>();

   public void OnTaskComplete(object sender, dev_emu_project.TaskCompleteEventArgs e)
        {
        //.... work for processing
        }
    }

【问题讨论】:

    标签: c# .net winforms


    【解决方案1】:

    您收到NullReferenceException 是因为您正在调用一个空事件,这意味着尚未向它注册任何委托。在调用它之前,您需要确保 TaskComplete 不为空。

    在调用之前添加一个空检查以确保有人确实注册了您的活动:

    if (TaskComplete != null)
    { 
        TaskComplete(this, args);
    }
    

    来自 MSDN Event Tutorial:

    调用事件

    一旦一个类声明了一个事件,它就可以将该事件视为指定委托类型的字段。如果没有客户端将委托连接到事件,则该字段将为空,否则它引用应在调用事件时调用的委托。因此,调用事件通常是先检查是否为空,然后调用事件

    【讨论】:

    • 你是对的,它总是为空。我已经编辑了我的帖子,以包含我认为允许我的用户控件订阅事件的主表单中的一些代码。我猜这并没有发生......关于原因的进一步猜测?
    • @Shen 您确定您访问的控件实例与您注册代理的控件实例相同吗?
    • 我确定我现在不是。我设置了断点,应该为订阅添加控件并且它们从未到达过。从那以后,我将那行代码移到了主窗体的 Form1_Load 事件中,它在那里拾取了它。我不确定为什么在我的编辑中看到它是不可访问的代码。感谢您的所有帮助。
    • 这可能是因为您试图在构造 Form1 之前访问一个控制列表,它可能是空的,并且在您的控件被添加到它之前。在表单完成加载后,您可以在 Form.Loaded 事件中看到它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-29
    • 2020-02-17
    • 2020-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多