单击按钮后如何在 C# 中启用部分代码,特别是另一个事件处理程序

How to enable part of a code, specifically another event handler, in C# after clicking a button

提问人:JCB 提问时间:11/8/2022 更新时间:11/8/2022 访问量:66

问:

我有一个场景,我通过 TCP/IP 协议连接到服务器。这需要在我单击 Windows 窗体上的“连接到 TCP/IP 服务器”按钮后完成。单击此按钮后,将显示连接状态(成功或失败)。这部分我很容易管理。我需要的是,当连接成功时,程序/代码才需要开始侦听来自服务器的传入消息并进一步处理。我测试了我是否可以在没有按钮的情况下获取服务器消息(即,当表单初始化时,它会自动连接到服务器),并且它工作正常。您将在下面的代码中看到,我正在使用同一台 PC 上的第三方软件的参考命令,该软件处理来自服务器的传入消息。使用第三方软件的原因仅仅是因为我使用 VisualStudio 和 C# 来扩展该软件在其文档中允许的软件功能。我确实会把一些变量写到这个第三方软件中。这个我也很好。因此,我唯一的问题是仅在按下连接按钮且连接成功时启用对来自服务器的传入测量的侦听。

任何帮助将不胜感激。

这是我到目前为止的代码,但它不起作用: `

namespace Form1
{
    public partial class Main_Form: Form
    {
        private CogJob Job;
        private CogJobManager Job_manager;
        private CogJobIndependent Job_independent;

        String Received_string;
        bool State_of_connection = false;
        ICogIOTCPIP TCP_IP_server_device;
        
        public Main_HMI()
        {
            InitializeComponent();

            //Load application
            Job_manager = (CogJobManager)(CogSerializer.LoadObjectFromFile(@"Project"));

            // Initialize job variables
            Job = Job_manager.Job("Application");
            Job_independent = Job.OwnedIndependent;

            // Flush all job queues
            Job.ImageQueueFlush();
            Job_manager.UserQueueFlush();
            Job_manager.FailureQueueFlush();
            Job_independent.RealTimeQueueFlush();

            if (State_of_connection == true)
            {
                TCP_IP_server_device.MessageReceived += new     CogIOStreamMessageEventHandler(TCP_IP_server_device_MessageReceived);
            }
            
        }
        
        // Decode the message received from the TCP/IP server device
        private void TCP_IP_server_device_MessageReceived(object sender, CogIOStreamMessageEventArgs eventArgs)
        {
            Received_string = eventArgs.DecodedMessage.Substring(2, 9);
        }

        // Savely shutdown application job manager when the form is closed;
        private void Main_HMI_FormClosing(object sender, FormClosingEventArgs e)
        {
            Job_manager.Shutdown();
        }

        private void Connect_to_TCP_IP_server_button_Click(object sender, EventArgs e)
        {
            Job_manager.IOEnable = true;
            TCP_IP_server_device = Job_manager.StreamInput("PLC", 2000, true);

            if (TCP_IP_server_device == null)
            {
                MessageBox.Show("Connection failed", "TCP/IP server device connection status");
            }

            else
            {
                MessageBox.Show("Connection successful", "TCP/IP server device connection status");
                State_of_connection = true;
            }
        }
    }
}

`

C# WinForms 按钮 事件 TCPArecher

评论

0赞 frankM_DN 11/8/2022
究竟什么“不起作用”。你试过调试吗?发生了什么与你预期/想要的不同?
0赞 JCB 11/8/2022
好吧,在我上面的原始代码中,我从未收到来自服务器的消息。换句话说,“State _of_connection”bool 变量永远不会更改为 true,因此每次我从服务器端发送消息时,它都会对其进行解码。我想要的是我单击一次连接按钮,然后程序应该连续等待传入的消息,而无需再次单击连接按钮。
0赞 Sven Bardos 11/8/2022
为什么不独立于 State_of_connection 添加事件处理程序呢?这不可能吗?
0赞 JCB 11/8/2022
问题在于,当使用 null 的 TCP/IP 服务器设备初始化时,传入消息的事件处理程序“CogIOStreamMessageEventHandler”(即其在表单启动时的原始值)会抛出错误。不幸的是,这就是第三部分软件中的事件处理程序的工作方式。
0赞 JCB 11/8/2022
在第三方软件示例中,它们在启动表单时自动连接到服务器。因此,当实际连接到服务器时,将为 null 的 TCP/IP 服务器设备提供除 null 以外的值,并且事件处理程序“CogIOStreamMessageEventHandler”正常工作。如果 TCP/IP 服务器设备仍然为 null(即没有连接到服务器),则只需关闭表单即可。我只想要一个按钮,而不是自动连接到服务器。

答:

1赞 rotabor 11/8/2022 #1

解决方案非常简单:

namespace Form1;

public partial class Main_Form: Form
{
    private CogJob Job;
    private CogJobManager Job_manager;
    private CogJobIndependent Job_independent;

    String Received_string;
    ICogIOTCPIP TCP_IP_server_device;
    
    public Main_HMI()
    {
        InitializeComponent();

        //Load application
        Job_manager = (CogJobManager)(CogSerializer.LoadObjectFromFile(@"Project"));

        // Initialize job variables
        Job = Job_manager.Job("Application");
        Job_independent = Job.OwnedIndependent;

        // Flush all job queues
        Job.ImageQueueFlush();
        Job_manager.UserQueueFlush();
        Job_manager.FailureQueueFlush();
        Job_independent.RealTimeQueueFlush();
    }
    
    // Decode the message received from the TCP/IP server device
    private void TCP_IP_server_device_MessageReceived(object sender, CogIOStreamMessageEventArgs eventArgs)
    {
        Received_string = eventArgs.DecodedMessage.Substring(2, 9);
    }

    // Savely shutdown application job manager when the form is closed;
    private void Main_HMI_FormClosing(object sender, FormClosingEventArgs e)
    {
        Job_manager.Shutdown();
    }

    private void Connect_to_TCP_IP_server_button_Click(object sender, EventArgs e)
    {
        Job_manager.IOEnable = true;
        TCP_IP_server_device = Job_manager.StreamInput("PLC", 2000, true);

        if (TCP_IP_server_device == null)
        {
            MessageBox.Show("Connection failed", "TCP/IP server device connection status");
        }
        else
        {
            MessageBox.Show("Connection successful", "TCP/IP server device connection status");
            TCP_IP_server_device.MessageReceived += new     CogIOStreamMessageEventHandler(TCP_IP_server_device_MessageReceived);
        }
    }
}

只需在成功连接时启用事件处理即可。

评论

0赞 JCB 11/8/2022
我认为它不会起作用,因为据我从上述解决方案中了解,每次从服务器端发送消息时,我都必须单击“连接到 TCP/IP 服务器按钮”,以便我的代码对其进行解码。我想要的是只单击一次“连接到 TCP/IP 服务器按钮”,从那时起它应该开始连续收听来自服务器端的消息,直到我断开与服务器的连接(断开连接我仍然需要编码)。
0赞 frankM_DN 11/8/2022
不,当您单击“连接”按钮时,在语句(成功连接)中,该行表示您正在订阅对象的事件。因此,当触发事件时,无需按任何按钮即可调用该函数。elseTCP_IP_server_device.MessageReceived += ...MessageReceivedTCP_IP_server_deviceMessageReceivedTCP_IP_server_device_MessageReceived