public MainWindow() { _messageBytes = Array.Empty <byte>(); this.SelectedCOMPort = new(""); InitializeComponent(); RefreshCOMPorts(autoSetWhenUniquePort: true); cmdButtons = new[] { btn_clear, btn_ResetToBLE, btn_resetToUART, btn_setTime, btn_startRecording, btn_stopToUART, btn_viewAll, btn_Say012 }; txtblk.Text = ""; //suppress button toggle when erase in progress message received AcksThatSuppressButtonToggling.Add(ConcatToSingleIEnumearble(ackErase_Prefix, ackErase_InProgress_Payload, Suffix)); AcksThatSuppressButtonToggling.Add(ConcatToSingleIEnumearble(ackSay012_Whole)); }
private async void Connect_Button_Click(object sender, RoutedEventArgs e) { SelectedCOMPort = COMSelector?.SelectedItem?.ToString() ?? ""; if (SelectedCOMPort == "") { return; } btn_Connect.IsEnabled = false; toggleCommandButtons(false); // Connected and try to disconnect bool isConnectionSuccess = Connection != null && Connection.IsConnected; if (isConnectionSuccess) { Connection?.Dispose(); COMSelector !.IsEnabled = true; this.RefreshCOMPorts(); btn_Connect.Content = "Connect"; return; } // Not connected else { if (this.SelectedCOMPort == "") { MessageBox.Show(ConnectionEmpty + ", please choose one."); return; } try { Connection?.Dispose(); Connection = new(SelectedCOMPort); // Should I use local function instead of delegate? Will it break my code? //SerialDataReceivedEventHandler handler = delegate void handler(object sender, SerialDataReceivedEventArgs e) { int messageLength = Connection !.CurrentPort.BytesToRead; this._messageBytes = new byte[messageLength]; Connection !.CurrentPort.Read(this._messageBytes, 0, messageLength); string s = BitConverter.ToString(this._messageBytes, 0, messageLength); // Must use begin invoke bacause Event handler is not called in Main thread // Or InvalidOperationException will be thrown // Cannot directly pass local function to Invoke(...) Action actionToInvoke = delegate { if (!_isVerbose) { OutputWindowSimple(this._messageBytes, Source.Receive); } else { OutputWindowVerbose(s, Source.Receive); } // DO NOT toggle on button when receive "erasing in progress" message if (AcksThatSuppressButtonToggling.ContainsIEumerableObject(_messageBytes)) { toggleCommandButtons(false); Debug.WriteLine("Waiting for process"); MessageBox.Show("This would take about 3 mins, please wait."); } else { toggleCommandButtons(true); } }; // end actionToInvoke Dispatcher.BeginInvoke(actionToInvoke); // end event handle settings }// end local function handler Connection.SetEventHandler(handler); Connection.Connect(); btn_Connect.Content = "斷線"; byte[] bitarr = setSay012_Whole.ToArray(); Connection.WriteBytes(bitarr, 0, setSay012_Whole.Length); COMSelector !.IsEnabled = false; OutputWindowVerbose(BitConverter.ToString(bitarr), Source.Send); } // General connection problem catch (System.IO.IOException ex) { MessageBox.Show(ConnectionFailed + ". Please retry"); Debug.WriteLine("Exception thrown:" + ex.Message); Connection?.Dispose(); } // The COM port is occupiued by another process catch (UnauthorizedAccessException uex) { MessageBox.Show(ConnectionFailed + ". Is another process using this COM Port?", uex.Message, MessageBoxButton.OK, MessageBoxImage.Error); } finally { Connection?.Dispose(); Connection = null; } // Wait to avoid stuck of ACC await Task.Run(() => { Task.Delay(3000); }); toggleCommandButtons(Connection?.IsConnected ?? false); btn_Connect.IsEnabled = true; } }