1

テキストボックスに情報を入力してから接続をクリックするWindowsフォームがあります。テキストボックスのいずれかが空の場合にポップアップするエラーメッセージがありますが、[OK] をクリックしてもプログラムは続行され、情報が不十分であるため実行時エラーが発生し、プログラムがクラッシュします。私が望むのは、テキストボックスが正しく入力されていないときはいつでも、プログラムが「接続」を押す前のポイントに戻ることです。

これはコードです:

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

Dervall が述べたように、最も簡単な解決策は、returnMessageBox.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 に答える
2

各メッセージ ボックスの後にステートメントを追加するreturnと、トリックが実行され、最後に作業を行わずにメソッドが終了します。

于 2012-04-19T08:35:29.930 に答える