2012-04-19 18 views
1

我有一個窗體窗體,可以填充信息的文本框,然後單擊連接。如果有任何文本框是空的,我會彈出錯誤消息,但是當我點擊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); 
    } 

回答

2

每個消息框會做的伎倆,並導致該方法無需做的工作在年底退出後添加return statment。

+0

謝謝你的回答快,我甚至不能接受它。這正是我一直在尋找的,我會盡快接受它:) – Charp 2012-04-19 08:40:24

2

最簡單的解決方案,正如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(); 
} 

是什麼改變:

  • 這是更具可讀性,當你覈實按鈕,它沒有
  • 方法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); 
} 
+0

這很好玩,它看起來比我的代碼更專業。謝謝,我希望我能給你一個投票,但我不是15代表。 – Charp 2012-04-19 11:17:27

+0

@Charp沒問題,也許以後:) – 2012-04-19 11:22:48