2012-04-19 60 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