diff --git a/LoraGamepad/App.axaml b/LoraGamepad/App.axaml index 2f59bb0..dec14df 100644 --- a/LoraGamepad/App.axaml +++ b/LoraGamepad/App.axaml @@ -9,4 +9,15 @@ + + + #474445 + #3b393a + #3a3a3a + #222121 + #0865b1 + #0f88eb + #ef2244 + #c71e3a + diff --git a/LoraGamepad/LoraGamepad.csproj b/LoraGamepad/LoraGamepad.csproj index b2e9ef5..bbce3b1 100644 --- a/LoraGamepad/LoraGamepad.csproj +++ b/LoraGamepad/LoraGamepad.csproj @@ -25,6 +25,8 @@ + + diff --git a/LoraGamepad/Models/CBPortItem.cs b/LoraGamepad/Models/CBPortItem.cs new file mode 100644 index 0000000..b4f615b --- /dev/null +++ b/LoraGamepad/Models/CBPortItem.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Autolabor; + +namespace LoraGamepad.Models; + +public class CBPortItem +{ + public string PortName { get; set; } + + public CBPortItem(string name) + { + PortName = name; + } + public static ObservableCollection GetPortList() + { + ObservableCollection portList = new ObservableCollection(); + List infos = SerialPort.FindPorts(); + foreach (var portInfo in infos) + { + portList.Add(new CBPortItem(portInfo.port)); + } + + return portList; + } +} + +public class CBPortItemCompare : IEqualityComparer +{ + public bool Equals(CBPortItem? x, CBPortItem? y) + { + if (ReferenceEquals(x, y)) return true; + if (ReferenceEquals(x, null)) return false; + if (ReferenceEquals(y, null)) return false; + if (x.GetType() != y.GetType()) return false; + return x.PortName == y.PortName; + } + + public int GetHashCode(CBPortItem obj) + { + return obj.PortName.GetHashCode(); + } +} \ No newline at end of file diff --git a/LoraGamepad/Models/SerialPort.cs b/LoraGamepad/Models/SerialPort.cs new file mode 100644 index 0000000..e3dfbd6 --- /dev/null +++ b/LoraGamepad/Models/SerialPort.cs @@ -0,0 +1,143 @@ + +using System; +using System.Collections.Generic; +using System.Threading; +using Autolabor; + +namespace LoraGamepad.Models; + +/// +/// 串口驱动封装单例模式 +/// +public class SerialPort +{ + /// + /// 串口单例 + /// + public static readonly SerialPort Me = new(); + + /// + /// 串口驱动基类 + /// + private readonly SerialBase _serial = new(); + + private bool _isPortOpen = false; + + private Action? _onWriteError; + /// + /// 串口是否打开属性 + /// + public bool IsPortOpen => _isPortOpen; + + /// + /// 搜索串口列表 + /// + /// + public static List FindPorts() + { + return SerialBase.EnumeratePorts(); + } + + public void LisenningPort(Action? onWriteError) + { + _onWriteError = onWriteError; + } + + /// + /// 保护性构造函数 + /// + private SerialPort() { } + + /// + /// 打开串口 + /// + /// 串口名 + /// 波特率 + /// 超时时间 + public void Open(string port,int baudRate,int timeout) + { + _serial.Port = port; + _serial.Baudrate = baudRate; + _serial.ReadTimeout = timeout; + try + { + _serial.Open(); + _isPortOpen = true; + } + catch (SerialBaseException e) + { + Console.WriteLine(e); + } + } + + /// + /// 串口发送 + /// + /// Byte数据 + public void Write(byte[] data) + { + try + { + if (Me.IsPortOpen) + { + _serial.Write(data); + } + } + catch (SerialBaseException e) + { + _onWriteError?.Invoke(); + Console.WriteLine(e); + } + } + + /// + /// 读取串口 + /// + /// Byte数组 + public byte[] Read() + { + try + { + return _serial.Read(); + } + catch (SerialBaseException e) + { + Console.WriteLine("My Line:" + e); + return Array.Empty(); + } + } + + public bool TryRead(out byte[] data) + { + if (_isPortOpen) + { + try + { + data = _serial.Read(); + return true; + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + data = Array.Empty(); + return false; + } + + /// + /// 关闭串口 + /// + public void Close() + { + try + { + _isPortOpen = false; + _serial.Close(); + } + catch (SerialBaseException e) + { + Console.WriteLine(e); + } + } +} \ No newline at end of file diff --git a/LoraGamepad/ViewModels/TProViewModel.cs b/LoraGamepad/ViewModels/TProViewModel.cs index 6225350..0648a9f 100644 --- a/LoraGamepad/ViewModels/TProViewModel.cs +++ b/LoraGamepad/ViewModels/TProViewModel.cs @@ -1,9 +1,88 @@ +using System.Collections.ObjectModel; +using System.Linq; +using System.Reactive; +using LoraGamepad.Models; +using ReactiveUI; + namespace LoraGamepad.ViewModels; public class TProViewModel : ViewModelBase { + + private bool _isOpenPortButtonVisible = true; + private bool _isClosePortButtonVisible; + + private ObservableCollection _portList = new(); + public CBPortItem PortSelectItem { get; set; } + + public ReactiveCommand OpenPort { get; } + public ReactiveCommand ClosePort { get; } public TProViewModel() { + PortList = CBPortItem.GetPortList(); + + OpenPort = ReactiveCommand.Create(PortOpenButtonClick); + ClosePort = ReactiveCommand.Create(PortCloseButtonClick); + } + + /// + /// ComboBox串口列表绑定对象 + /// + public ObservableCollection PortList + { + get => _portList; + set => this.RaiseAndSetIfChanged(ref _portList, value); + } + + /// + /// 刷新串口列表事件处理函数 + /// + public void OnPortListComboBoxPressed() + { + var newList = CBPortItem.GetPortList(); + PortList.Except(newList,new CBPortItemCompare()).ToList().ForEach(a => { PortList.Remove(a); }); + newList.Except(PortList, new CBPortItemCompare()).ToList().ForEach(a => { PortList.Add(a); }); + newList.Except(PortList, new CBPortItemCompare()).ToList().ForEach(a => { PortList.Add(a); }); + } + + /// + /// 关闭串口按键可见性属性 + /// + public bool IsClosePortButtonVisible + { + get => _isClosePortButtonVisible; + set => this.RaiseAndSetIfChanged(ref _isClosePortButtonVisible, value); + } + + /// + /// 打开串口按键可见性属性 + /// + public bool IsOpenPortButtonVisible + { + get => _isOpenPortButtonVisible; + set => this.RaiseAndSetIfChanged(ref _isOpenPortButtonVisible, value); + } + + /// + /// 打开串口按键响应 + /// + private void PortOpenButtonClick() + { + if (PortSelectItem.PortName == "") return; + SerialPort.Me.Open(PortSelectItem.PortName,420000,1000); + IsOpenPortButtonVisible = false; + IsClosePortButtonVisible = true; } + + /// + /// 关闭串口按键响应 + /// + private void PortCloseButtonClick() + { + SerialPort.Me.Close(); + IsOpenPortButtonVisible = true; + IsClosePortButtonVisible = false; + } + } \ No newline at end of file diff --git a/LoraGamepad/Views/TProView.axaml b/LoraGamepad/Views/TProView.axaml index 724cdb9..802ccdc 100644 --- a/LoraGamepad/Views/TProView.axaml +++ b/LoraGamepad/Views/TProView.axaml @@ -2,18 +2,63 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:viewModels="clr-namespace:LoraGamepad.ViewModels" + xmlns:eventBinder="clr-namespace:EventBinder;assembly=EventBinder.Avalonia" mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="400" x:Class="LoraGamepad.Views.TProView"> + + + + + + + + + + + - - - + +