C# WinForm:重新打开窗体时保留ComboBox选中项及按钮文本
Hey there! The core issue here is that you're creating a new instance of the Connect form every time you open it, which resets all controls to their default state. To fix this, we'll leverage your existing CommPortManager singleton to persist the settings and connection state between form openings. Here's how to do it step by step:
1. Update CommPortManager to Track Connection State
First, add a property to your singleton to track whether the port is connected, and ensure it persists the selected settings:
public class CommPortManager { private static CommPortManager _instance; public static CommPortManager Instance { get { if (_instance == null) { _instance = new CommPortManager(); } return _instance; } } // Add this property to track connection state public bool IsConnected { get; set; } = false; // Keep your existing properties to persist settings public string PortName { get; set; } = ""; public string BaudRate { get; set; } = ""; public string Parity { get; set; } = ""; public string StopBits { get; set; } = ""; public string DataBits { get; set; } = ""; // Your existing methods (GetCommList(), COM_Open(), COM_Close(), etc.) }
2. Modify the Connect Form to Load Saved State
Update your form to load the saved settings from CommPortManager when it initializes, and set the button text based on the connection state:
public partial class Connect : Form { public Connect() { InitializeComponent(); } private void Connect_Load(object sender, EventArgs e) { // Populate COM port list first COM_List(); // Load saved settings into ComboBoxes (if they exist in the current list) LoadSavedSettings(); // Set button text based on current connection state btn_Connect.Text = CommPortManager.Instance.IsConnected ? "Disconnect" : "Connect"; } private void COM_List() { cb_CommPort.Items.Clear(); // Clear old items first foreach (var port in CommPortManager.Instance.GetCommList()) { cb_CommPort.Items.Add(port); } } private void LoadSavedSettings() { // Restore COM Port selection if (!string.IsNullOrEmpty(CommPortManager.Instance.PortName) && cb_CommPort.Items.Contains(CommPortManager.Instance.PortName)) { cb_CommPort.SelectedItem = CommPortManager.Instance.PortName; } // Restore Baud Rate if (!string.IsNullOrEmpty(CommPortManager.Instance.BaudRate) && cb_BaudRate.Items.Contains(CommPortManager.Instance.BaudRate)) { cb_BaudRate.SelectedItem = CommPortManager.Instance.BaudRate; } // Restore Parity if (!string.IsNullOrEmpty(CommPortManager.Instance.Parity) && cb_Parity.Items.Contains(CommPortManager.Instance.Parity)) { cb_Parity.SelectedItem = CommPortManager.Instance.Parity; } // Restore Stop Bits if (!string.IsNullOrEmpty(CommPortManager.Instance.StopBits) && cb_StopBits.Items.Contains(CommPortManager.Instance.StopBits)) { cb_StopBits.SelectedItem = CommPortManager.Instance.StopBits; } // Restore Data Bits if (!string.IsNullOrEmpty(CommPortManager.Instance.DataBits) && cb_DataBits.Items.Contains(CommPortManager.Instance.DataBits)) { cb_DataBits.SelectedItem = CommPortManager.Instance.DataBits; } } private void btn_Connect_Click(object sender, EventArgs e) { // Save current selections to the singleton first CommPortManager.Instance.PortName = cb_CommPort.Text; CommPortManager.Instance.BaudRate = cb_BaudRate.Text; CommPortManager.Instance.Parity = cb_Parity.Text; CommPortManager.Instance.StopBits = cb_StopBits.Text; CommPortManager.Instance.DataBits = cb_DataBits.Text; // Validate all fields are selected if (string.IsNullOrEmpty(cb_CommPort.Text) || string.IsNullOrEmpty(cb_BaudRate.Text) || string.IsNullOrEmpty(cb_Parity.Text) || string.IsNullOrEmpty(cb_DataBits.Text) || string.IsNullOrEmpty(cb_StopBits.Text)) { MessageBox.Show("Please select all communication settings first", "TestCertificate", MessageBoxButtons.OK, MessageBoxIcon.Information); CommPortManager.Instance.IsConnected = false; return; } // Toggle connection state if (!CommPortManager.Instance.IsConnected) { // Try to open the port if (!CommPortManager.Instance.COM_Open()) { MessageBox.Show("Could not open the COM port. Most likely it is already in use, has been removed, or is unavailable.", "TestCertificate", MessageBoxButtons.OK, MessageBoxIcon.Information); CommPortManager.Instance.IsConnected = false; } else { CommPortManager.Instance.IsConnected = true; btn_Connect.Text = "Disconnect"; } } else { // Close the port CommPortManager.Instance.COM_Close(); CommPortManager.Instance.IsConnected = false; btn_Connect.Text = "Connect"; } } private void btn_Close_Click(object sender, EventArgs e) { this.Close(); } }
3. Update the Main Form to Use the Singleton State
Modify your main form's code to rely on the CommPortManager singleton instead of the form's local state:
private void connectToolStripMenuItem_Click(object sender, EventArgs e) { Connect connect = new Connect(); connect.ShowDialog(); if (CommPortManager.Instance.IsConnected) { lb_Comm.Text = String.Format("Connected to '{0}'", CommPortManager.Instance.PortName); } else { CommPortManager.Instance.COM_Close(); // Ensure port is closed if disconnected lb_Comm.Text = "Not Connected"; } }
Key Changes Explained:
- Singleton State: We use
CommPortManagerto store both the selected settings and connection status, so these values persist even when the form is closed. - Form Initialization: The
Connect_Loadmethod loads saved settings into the ComboBoxes and sets the button text based on the current connection state. - Toggle Logic: The
btn_Connect_Clickhandler now toggles between connect/disconnect states, updating the singleton'sIsConnectedproperty accordingly.
This way, every time you reopen the Connect form, it will restore your previous selections and show the correct button text based on whether the port is connected.
内容的提问来源于stack exchange,提问作者User0804

