1

我有一个 Windows 窗体,其中包含用信息填写文本框,然后单击连接。如果任何文本框为空,我会弹出错误消息,但是当我点击确定时,程序会继续运行,但由于信息不足,我最终会收到运行时错误,并且程序崩溃。我想要的是让程序回到我点击“连接”之前的点,只要任何文本框没有正确填写。

这是代码:

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);
    }
4

2 回答 2

2

在每个消息框之后添加一个return语句可以解决问题并导致方法退出而不做最后的工作。

于 2012-04-19T08:35:29.930 回答
2

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

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

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();
}

发生了什么变化:

  • 当您验证按钮上的哪些文本时,它更具可读性,然后它没有
  • 方法 ShowErrorMessage 完全按照它所说的那样做
  • 验证文本,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);
}
于 2012-04-19T09:24:04.637 回答