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;
            }
        }