C# 串口编程 — MVVM MVVM Light 实例
最近在学习WPF的MVVM模式,在公司用的串口调试工具太大(主要功能太强大,有很多其他功能,但是我用不到),所以闲着没事,自己写了一个串口调试工具,还是使用的WPF的MVVM模式,发现自从对它有些了解后,我已经迷上了这种模式
主要:下拉框加载本地所有串口,绿色代表串口已经连接,输入信息后,点发送信息,就会按发送频率对串口循环发送
<Grid> <Grid.RowDefinitions> <RowDefinition Height="212*" /> <RowDefinition Height="32*" /> <RowDefinition Height="37*" /> </Grid.RowDefinitions> <Label Content="本地串口" Grid.Row="2" Height="28" HorizontalAlignment="Left" Margin="7,6,0,0" Name="label1" VerticalAlignment="Top" /> <ComboBox ItemsSource="{Binding Coms}" SelectedValue="{Binding CurrentPortName}" DisplayMemberPath="" Height="23" HorizontalAlignment="Left" Margin="71,6,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" Grid.Row="2" /> <Button Content="打开串口" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="261,6,0,0" Name="button1" VerticalAlignment="Top" Width="75" Command="{Binding OpenPort}" /> <Rectangle Height="17" RadiusX="6" RadiusY="6" HorizontalAlignment="Left" Margin="220,9,0,0" Name="rectangle1" Stroke="Black" VerticalAlignment="Top" Width="17" Grid.Row="2" Fill="{Binding ValueColor}" /> <Label Content="信息" Height="28" HorizontalAlignment="Left" Margin="25,14,0,0" Name="label2" VerticalAlignment="Top" /> <TextBox Text="{Binding Msg1,Mode=TwoWay}" Height="23" HorizontalAlignment="Left" Margin="98,16,0,0" Name="textBox1" VerticalAlignment="Top" Width="290" /> <Button Content="{Binding BtnName}" Height="23" Command="{Binding SendMsg}" HorizontalAlignment="Left" Margin="362,6,0,0" Name="button2" VerticalAlignment="Top" Width="84" Grid.Row="2" /> <Label Content="信息" Height="28" HorizontalAlignment="Left" Margin="25,51,0,0" Name="label3" VerticalAlignment="Top" /> <TextBox Text="{Binding Msg2,Mode=TwoWay}" Height="23" HorizontalAlignment="Left" Margin="98,53,0,0" Name="textBox2" VerticalAlignment="Top" Width="290" /> <Label Content="信息" Height="28" HorizontalAlignment="Left" Margin="25,93,0,0" Name="label4" VerticalAlignment="Top" /> <TextBox Text="{Binding Msg3,Mode=TwoWay}" Height="23" HorizontalAlignment="Left" Margin="98,95,0,0" Name="textBox3" VerticalAlignment="Top" Width="290" /> <Label Content="信息" Height="28" HorizontalAlignment="Left" Margin="25,133,0,0" Name="label5" VerticalAlignment="Top" /> <TextBox Text="{Binding Msg4,Mode=TwoWay}" Height="23" HorizontalAlignment="Left" Margin="98,135,0,0" Name="textBox4" VerticalAlignment="Top" Width="290" /> <Label Content="信息" Height="28" HorizontalAlignment="Left" Margin="25,167,0,0" Name="label6" VerticalAlignment="Top" /> <TextBox Text="{Binding Msg5,Mode=TwoWay}" Height="23" HorizontalAlignment="Left" Margin="98,169,0,0" Name="textBox5" VerticalAlignment="Top" Width="290" /> <CheckBox Content="重复发送" IsChecked="{Binding IsFor}" Grid.Row="1" Height="16" HorizontalAlignment="Left" Margin="373,7,0,0" Name="checkBox1" VerticalAlignment="Top" /> <Label Content="发送频率" Height="28" HorizontalAlignment="Left" Margin="220,4,0,0" Name="label7" VerticalAlignment="Top" Grid.Row="1" /> <TextBox Text="{Binding PL, Mode=TwoWay}" Height="23" HorizontalAlignment="Left" Margin="284,4,0,0" Name="textBox6" VerticalAlignment="Top" Width="67" Grid.Row="1" /> </Grid>
public partial class MainWindow : Window { MainViewModel viewmodel; public MainWindow() { InitializeComponent(); viewmodel = new MainViewModel(); this.DataContext = viewmodel; } }
public class MainViewModel : ViewModelBase { /// <summary> /// Initializes a new instance of the MainViewModel class. /// </summary> public MainViewModel() { Cominit();//初始化端口 this.OpenPort = new RelayCommand(OpenportAction); SendMsg = new RelayCommand(Sendmessage); } #region 属性 private string currentPortName; /// <summary> /// 当前端口名称 /// </summary> public string CurrentPortName { get { return currentPortName; } set { if (this.CurrenPort != null) { if (this.CurrenPort.IsOpen) { this.CurrenPort.Close(); } } currentPortName = value; RaisePropertyChanged("CurrentPortName"); this.CurrenPort = new SerialPort(); this.ValueColor = "Red"; } } private string valueColor = "Red"; /// <summary> /// 状态显示颜色 /// </summary> public string ValueColor { get { return valueColor; } set { valueColor = value; RaisePropertyChanged("ValueColor"); } } private ObservableCollection<string> coms; /// <summary> /// com端口集合 /// </summary> public ObservableCollection<string> Coms { get { return coms; } set { coms = value; RaisePropertyChanged("Coms"); } } private SerialPort port; /// <summary> /// 当前操作端口 /// </summary> public SerialPort CurrenPort { get { return port; } set { port = value; } } private string msg1; /// <summary> /// 消息1 /// </summary> public string Msg1 { get { return msg1; } set { msg1 = value; RaisePropertyChanged("Msg1"); } } private string msg2; /// <summary> /// 消息2 /// </summary> public string Msg2 { get { return msg2; } set { msg2 = value; RaisePropertyChanged("Msg2"); } } private string msg3; /// <summary> /// 消息3 /// </summary> public string Msg3 { get { return msg3; } set { msg3 = value; RaisePropertyChanged("Msg3"); } } private string msg4; /// <summary> /// 消息4 /// </summary> public string Msg4 { get { return msg4; } set { msg4 = value; RaisePropertyChanged("Msg4"); } } private string msg5; /// <summary> /// 消息5 /// </summary> public string Msg5 { get { return msg5; } set { msg5 = value; RaisePropertyChanged("Msg5"); } } private bool isFor = false; /// <summary> /// 是否循环发送 /// </summary> public bool IsFor { get { return isFor; } set { isFor = value; RaisePropertyChanged("IsFor"); } } private string btnName = "发送信息"; /// <summary> /// 按钮名称: 发送信息 : 停止发送 /// </summary> public string BtnName { get { return btnName; } set { btnName = value; RaisePropertyChanged("BtnName"); } } private int pl = 500; /// <summary> /// 发送频率 /// </summary> public int PL { get { return pl; } set { pl = value; RaisePropertyChanged("PL"); } } #endregion /// <summary> /// 打开端口命令 /// </summary> public RelayCommand OpenPort { get; set; } /// <summary> /// 发送信息命令 /// </summary> public RelayCommand SendMsg { get; set; } /// <summary> /// 打开端口 /// </summary> public void OpenportAction() { try { if (CurrenPort != null && CurrenPort.PortName == CurrentPortName && CurrenPort.IsOpen) { return; } this.CurrenPort = new SerialPort(); CurrenPort.PortName = CurrentPortName; this.CurrenPort.Open(); this.ValueColor = "Lime"; } catch (System.Exception ex) { this.ValueColor = "Red"; } } /// <summary> /// 初始化端口 /// </summary> public void Cominit() { Coms = new ObservableCollection<string>(); Microsoft.VisualBasic.Devices.Computer computer = new Microsoft.VisualBasic.Devices.Computer(); Coms.Add("虚拟端口"); foreach (string str in computer.Ports.SerialPortNames) { Coms.Add(str); } } List<string> msgs;// 消息列表 bool isopen = false;// 标记按钮当前状态 Thread thread; //线程实例 public void Sendmessage() { if (!isopen) { isopen = true; BtnName = "停止发送"; msgs = new List<string>(); if (!string.IsNullOrEmpty(Msg1)) { msgs.Add(Msg1); } if (!string.IsNullOrEmpty(Msg2)) { msgs.Add(Msg2); } if (!string.IsNullOrEmpty(Msg3)) { msgs.Add(Msg3); } if (!string.IsNullOrEmpty(Msg4)) { msgs.Add(Msg4); } if (!string.IsNullOrEmpty(Msg5)) { msgs.Add(Msg5); } thread = new Thread(new ThreadStart(ThreadSend)); thread.Start(); } else { thread.Abort(); isopen = false; BtnName = "发送信息"; } } public void ThreadSend() { bool value = true; while (value) { foreach (string str in msgs) { Thread.Sleep(PL); // 发送频率 线程挂起 CurrenPort.WriteLine(str); } if (!IsFor)//是否循环发送 { value = false; } } isopen = false; BtnName = "发送信息"; thread.Abort(); } }