在按钮内处理错误

本文关键字:错误 处理 按钮 | 更新日期: 2023-09-27 18:31:32

我有一个窗口表单,其中涉及填写带有信息的文本框,然后单击连接。如果任何文本框为空,我会弹出错误消息,但是当我点击确定时,程序会继续,我最终会收到运行时错误,因为信息不足,程序崩溃。我想要的是每当任何文本框未正确填写时,程序都能回到我点击"连接"之前的位置。

这是代码:

private void cmdConnect_Click(object sender, EventArgs e)
    {
        if (cmdConnect.Text == "Connect")
        {
            if (txtGroup.Text == "")
            {
                txtGroup.Text = "_Group01";
            }
            if (txtItemID.Text == "")
            {
                MessageBox.Show("Please enter ItemID.", "Connect Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
                switch (cboServer.Text)
                {
                    case "":
                        MessageBox.Show("Please select and OPC server", "Connect Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        break;

                    case "RSLinx Remote OPC Server":
                        if (txtMachine.Text == "")
                        {
                            MessageBox.Show("Please enter a machine name for remote connection", "Connect Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            break;
                        }
                        else
                        {
                            oOpcServer.Connect(cboServer.Text, txtMachine.Text);
                        }
                        break;
                    case "RSLinx OPC Server":
                        oOpcServer.Connect(cboServer.Text);
                        break;
                    default:
                        if (txtMachine.Text == "")
                        {
                            oOpcServer.Connect(cboServer.Text);
                        }
                        else
                        {
                            oOpcServer.Connect(cboServer.Text, txtMachine.Text);

                        }
                        break;
            }
            oOpcGroup = oOpcServer.OPCGroups.Add(txtGroup.Text);
            oOpcGroup.IsSubscribed = true;
            oOpcGroup.IsActive = false;
            oOpcGroup.UpdateRate = 1000;

            ClHandle = 1;
            oOpcGroup.OPCItems.DefaultAccessPath = txtAccessPath.Text;
            oOpcGroup.OPCItems.AddItem(txtItemID.Text, ClHandle);
            cmdItemWrite.Enabled = true;
            cmdItemRead.Enabled = true;
            cmdSyncWrite.Enabled = true;
            cmdSyncRead.Enabled = true;
            cmdAsyncWrite.Enabled = true;
            cmdAsyncRead.Enabled = true;
            cmdAdvise.Enabled = true;
            txtSubValue.Enabled = true;
            cboServer.Enabled = false;
            txtMachine.Enabled = false;
            txtGroup.Enabled = false;
            txtAccessPath.Enabled = false;
            txtItemID.Enabled = false;
            cmdConnect.Text = "Disconnect";
        }
        else
        {
            oOpcServer.OPCGroups.RemoveAll();
            oOpcGroup = null;
            oOpcServer.Disconnect();
            cmdConnect.Text = "Connect";
            cmdItemWrite.Enabled = false;
            cmdItemRead.Enabled = false;
            cmdSyncWrite.Enabled = false;
            cmdSyncRead.Enabled = false;
            cmdAsyncWrite.Enabled = false;
            cmdAsyncRead.Enabled = false;
            cmdAdvise.Enabled = false;
            txtSubValue.Enabled = false;
            cboServer.Enabled = true;
            txtMachine.Enabled = true;
            txtGroup.Enabled = true;
            txtAccessPath.Enabled = true;
            txtItemID.Enabled = true;
        }
        oOpcGroup.DataChange += new RsiOPCAuto.DIOPCGroupEvent_DataChangeEventHandler(oOpcGroup_DataChange);
    }

在按钮内处理错误

在每个消息框后添加一个 return 语句将完成技巧并导致方法退出而不在结束时执行工作。

正如 Dervall 所提到的,最简单的解决方案是在每次MessageBox.Show调用后添加return语句。但更优雅的解决方案是在执行连接逻辑之前使用验证和错误提供程序突出显示不正确的输入数据。

无论如何,这里有一些关于重构代码的想法。

private void cmdConnect_Click(object sender, EventArgs e)
{
    if (cmdConnect.Text == "Disconnect") 
    {
        Disconnect();
        SetControlsToDisconnectedState();
        return;
    }
    if (String.IsNullOrWhiteSpace(txtGroup.Text))
        txtGroup.Text = "_Group01";

    if (String.IsNullOrWhiteSpace(txtItemID.Text))
    {
        ShowErrorMessage("Connect Error", "Please enter ItemID.");
        return;
    }
    if (String.IsNullOrWhiteSpace(cboServer.Text))
    {
        ShowErrorMessage("Connect Error", "Please select and OPC server");
        return;
    }
    Connect(cboServer.Text, txtMachine.Text);
    DoSomethingWithGroup(txtGroup.Text, txtAccessPath.Text, txtItemID.Text);
    SetControlsToConnectedState();
}

更改内容:

    当您
  • 验证按钮上的哪些文本时,它更具可读性,然后它没有哪些文本
  • 方法显示错误消息完全按照它所说的去做
  • 使用IsNullOrWhiteSpace验证文本,因为它可能充满空格
  • 控件状态更改移至单独的代码
  • 连接/断开连接现在与 UI 分离

这里有其他方法:

private void ShowErrorMessage(string title, string message)
{
    MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
private void SetControlsToConnectedState()
{
    UpdateControls(true);
}
private void SetControlsToDisconnectedState()
{
    UpdateControls(false);
}
private void UpdateControls(bool isConnected)
{
    cmdConnect.Text = isConnected ? "Disconnect" : "Connect";
    cmdItemWrite.Enabled = isConnected;
    cmdItemRead.Enabled = isConnected;
    cmdSyncWrite.Enabled = isConnected;
    cmdSyncRead.Enabled = isConnected;
    cmdAsyncWrite.Enabled = isConnected;
    cmdAsyncRead.Enabled = isConnected;
    cmdAdvise.Enabled = isConnected;
    txtSubValue.Enabled = isConnected;
    cboServer.Enabled = !isConnected;
    txtMachine.Enabled = !isConnected;
    txtGroup.Enabled = !isConnected;
    txtAccessPath.Enabled = !isConnected;
    txtItemID.Enabled = !isConnected;      
}
private void Disconnect()
{
    oOpcServer.OPCGroups.RemoveAll();
    oOpcGroup = null;
    oOpcServer.Disconnect();            
}
private void Connect(string serverName, string machineName)
{
    switch (serverName)
    {
        case "RSLinx Remote OPC Server":
            if (String.IsNullOrWhiteSpace(machineName))
            {
                ShowErrorMessage("Connect Error", "Please enter a machine name for remote connection");
                return;
            }
            oOpcServer.Connect(serverName, machineName);                    
            break;
        case "RSLinx OPC Server":
            oOpcServer.Connect(serverName);
            break;
        default:
            if (String.IsNullOrWhiteSpace(machineName))            
                oOpcServer.Connect(serverName);            
            else            
                oOpcServer.Connect(serverName, machineName);            
            break;
    }           
}
private void DoSomethingWithGroup(string groupName, string accessPath, string itemID)
{
    oOpcGroup = oOpcServer.OPCGroups.Add(groupName);
    oOpcGroup.IsSubscribed = true;
    oOpcGroup.IsActive = false;
    oOpcGroup.UpdateRate = 1000;
    ClHandle = 1;
    oOpcGroup.OPCItems.DefaultAccessPath = accessPath;
    oOpcGroup.OPCItems.AddItem(itemID, ClHandle);
    oOpcGroup.DataChange += new RsiOPCAuto.DIOPCGroupEvent_DataChangeEventHandler(oOpcGroup_DataChange);
}