这一章我将继续上一章内容进一步完善我们的串口通信,并添加对话框的美观设计。
首先我们说一下双向通讯,上一章我们实现了单向接收功能,这里将说一下发射功能:
数据发送,总共有三种形式,发送字符串类,发送byte类,发送char类。要实现这三种,都必须调用串口写操作方法 SerialPort.Write() ,该方法对于不同类型的发送,通过方法重载的方式定义了相应的方法:
- public void Write (string str); 发送字符串
- public void Write (byte[] buffer, int offset, int count); 发送byte类型
- public void Write (char[] buffer, int offset, int count); 发送char类型
本例程发送的是加密后的序列号码,所以只需调用 myPort.Write(output,0,output.Length); 方法即可。此外我们添加一个清空按键:
private void Btn2_Click(object sender, RoutedEventArgs e) { m_textBox1.Text = ""; m_textBox2.Text = ""; }
<Button Content="Clear" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="51" Margin="0,0,22,80" Click="Btn2_Click" Height="58"/>
同时为了美观对话框,我们加入之前定义好的按键动态效果模板来实现按键的动态效果,和加入对label字体格式,textbox背景颜色,以及对话框背景修改:
1 <Window.Resources> 2 <!--define glass gradient stop resource--> 3 <GradientStopCollection x:Key="myGradientStopResource"> 4 <GradientStop Color="WhiteSmoke" Offset="0.2"/> 5 <GradientStop Color="Transparent" Offset="0.4"/> 6 <GradientStop Color="WhiteSmoke" Offset="0.5"/> 7 <GradientStop Color="Transparent" Offset=" 0.75"/> 8 <GradientStop Color="WhiteSmoke" Offset="0.9"/> 9 <GradientStop Color="Transparent" Offset=" 1.0"/> 10 </GradientStopCollection> 11 12 <!--define gradient brush resource--> 13 <LinearGradientBrush x:Key="myGlassBrushResource" StartPoint="0,0" EndPoint=" 1,1" Opacity="0.75" 14 GradientStops="{StaticResource myGradientStopResource }"/> 15 16 <!--background brush resource--> 17 <LinearGradientBrush x:Key="grayBlueGradientBrush" StartPoint=" 0,0" EndPoint="1,1"> 18 <GradientStop Color="Gray" Offset="0"/> 19 <GradientStop Color="Cyan" Offset="0.5"/> 20 <GradientStop Color="Gold" Offset="1.0"/> 21 </LinearGradientBrush> 22 23 <!--define button options--> 24 <Style TargetType="Button"> 25 <!--define button background--> 26 <Setter Property="Background" Value="{StaticResource grayBlueGradientBrush}"/> 27 <!--define button template--> 28 <Setter Property="Template"> 29 <Setter.Value> 30 <!--target type is button--> 31 <ControlTemplate TargetType="{x:Type Button}"> 32 <Grid Margin="-1,0,-10,1"> 33 <!--outline rectangle--> 34 <Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch" 35 VerticalAlignment="Stretch" Stroke="{TemplateBinding Background}" 36 RadiusX="10" RadiusY="10" StrokeThickness="5" Fill="Transparent"/> 37 <!--inner rectangle--> 38 <Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch" 39 VerticalAlignment="Stretch" Stroke="Transparent" 40 StrokeThickness="5" Fill="{TemplateBinding Background}" 41 RadiusX="10" RadiusY="10"/> 42 <!--glass rectangle--> 43 <Rectangle x:Name="glassCube" HorizontalAlignment="Stretch" 44 VerticalAlignment="Stretch" StrokeThickness="1" 45 RadiusX="5" RadiusY="5" Opacity="0" 46 Fill="{StaticResource myGlassBrushResource}" 47 RenderTransformOrigin="0.5,0.5"> 48 <!--rectangle stroke--> 49 <Rectangle.Stroke> 50 <LinearGradientBrush StartPoint=" 0.5,0" EndPoint="0.5,1"> 51 <LinearGradientBrush.GradientStops> 52 <GradientStop Color="LightBlue" Offset="0.0"/> 53 <GradientStop Color="Gray" Offset="1.0"/> 54 </LinearGradientBrush.GradientStops> 55 </LinearGradientBrush> 56 </Rectangle.Stroke> 57 <!--glass rectangle render transform--> 58 <Rectangle.RenderTransform> 59 <TransformGroup> 60 <!--To stretch or contact horizontally or vertially--> 61 <ScaleTransform/> 62 <!--rotate transform by angles--> 63 <RotateTransform/> 64 </TransformGroup> 65 </Rectangle.RenderTransform> 66 </Rectangle> 67 <!--dock panel--> 68 <DockPanel Name="myContentPresenterDockPanel"> 69 <ContentPresenter x:Name="myContentPresent" HorizontalAlignment="Center" Margin="0,20" 70 Content="{TemplateBinding Content}" TextBlock.Foreground="Black" TextBlock.FontWeight="Bold"/> 71 </DockPanel> 72 </Grid> 73 <!--control template--> 74 <ControlTemplate.Triggers> 75 <!--mouse over trigger--> 76 <Trigger Property="IsMouseOver" Value="True"> 77 <!--rectangle stroke--> 78 <Setter Property="Rectangle.Stroke" TargetName="outerRectangle" 79 Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> 80 <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube"/> 81 </Trigger> 82 <!--Mouse focused trigger--> 83 <Trigger Property="IsFocused" Value="True"> 84 <Setter Property="Rectangle.Stroke" TargetName="innerRectangle" 85 Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> 86 <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube"/> 87 </Trigger> 88 <!--Event trigger mouse enter--> 89 <EventTrigger RoutedEvent="Mouse.MouseEnter"> 90 <!--actions--> 91 <EventTrigger.Actions> 92 <!--begin story board--> 93 <BeginStoryboard Name="mouseEnterBeginStoryboard"> 94 <Storyboard> 95 <!--animation--> 96 <DoubleAnimation Storyboard.TargetName="glassCube" 97 Storyboard.TargetProperty= 98 "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" 99 By="-0.2" Duration="0:0:0.5" /> 100 <DoubleAnimation Storyboard.TargetName="glassCube" 101 Storyboard.TargetProperty= 102 "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" 103 By="-0.2" Duration="0:0:0.5" /> 104 </Storyboard> 105 </BeginStoryboard> 106 </EventTrigger.Actions> 107 </EventTrigger> 108 <!--event trigger mouse leave--> 109 <EventTrigger RoutedEvent="Mouse.MouseLeave"> 110 <EventTrigger.Actions> 111 <StopStoryboard BeginStoryboardName="mouseEnterBeginStoryboard"/> 112 </EventTrigger.Actions> 113 </EventTrigger> 114 <!--event trigger button click--> 115 <EventTrigger RoutedEvent="Button.Click"> 116 <EventTrigger.Actions> 117 <BeginStoryboard> 118 <Storyboard> 119 <DoubleAnimation Storyboard.TargetName="glassCube" 120 Storyboard.TargetProperty= 121 "(Rectangle.RenderTransform).(TransformGroup.Children)[1].(RotateTransform.Angle)" 122 By="360" Duration="0:0:0.5"/> 123 </Storyboard> 124 </BeginStoryboard> 125 </EventTrigger.Actions> 126 </EventTrigger> 127 </ControlTemplate.Triggers> 128 </ControlTemplate> 129 </Setter.Value> 130 </Setter> 131 </Style> 132 133 <Style TargetType="Label"> 134 <Setter Property="FontWeight" Value="Bold"/> 135 </Style> 136 <Style TargetType="TextBox"> 137 <Setter Property="Background" Value="LightCyan"/> 138 </Style> 139 </Window.Resources> 140
因为我们之前定义好的模板,我们直接调用即可,这些方法我们也可以运用到其他的设计中。这样做的目的是大大的缩短了我们设计的时间。
最后完整码如下:
XAML:
1 <Window x:Class="SearilPort.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525" Background="LightSkyBlue"> 5 <Window.Resources> 6 <!--define glass gradient stop resource--> 7 <GradientStopCollection x:Key="myGradientStopResource"> 8 <GradientStop Color="WhiteSmoke" Offset="0.2"/> 9 <GradientStop Color="Transparent" Offset="0.4"/> 10 <GradientStop Color="WhiteSmoke" Offset="0.5"/> 11 <GradientStop Color="Transparent" Offset=" 0.75"/> 12 <GradientStop Color="WhiteSmoke" Offset="0.9"/> 13 <GradientStop Color="Transparent" Offset=" 1.0"/> 14 </GradientStopCollection> 15 16 <!--define gradient brush resource--> 17 <LinearGradientBrush x:Key="myGlassBrushResource" StartPoint="0,0" EndPoint=" 1,1" Opacity="0.75" 18 GradientStops="{StaticResource myGradientStopResource }"/> 19 20 <!--background brush resource--> 21 <LinearGradientBrush x:Key="grayBlueGradientBrush" StartPoint=" 0,0" EndPoint="1,1"> 22 <GradientStop Color="Gray" Offset="0"/> 23 <GradientStop Color="Cyan" Offset="0.5"/> 24 <GradientStop Color="Gold" Offset="1.0"/> 25 </LinearGradientBrush> 26 27 <!--define button options--> 28 <Style TargetType="Button"> 29 <!--define button background--> 30 <Setter Property="Background" Value="{StaticResource grayBlueGradientBrush}"/> 31 <!--define button template--> 32 <Setter Property="Template"> 33 <Setter.Value> 34 <!--target type is button--> 35 <ControlTemplate TargetType="{x:Type Button}"> 36 <Grid Margin="-1,0,-10,1"> 37 <!--outline rectangle--> 38 <Rectangle x:Name="outerRectangle" HorizontalAlignment="Stretch" 39 VerticalAlignment="Stretch" Stroke="{TemplateBinding Background}" 40 RadiusX="10" RadiusY="10" StrokeThickness="5" Fill="Transparent"/> 41 <!--inner rectangle--> 42 <Rectangle x:Name="innerRectangle" HorizontalAlignment="Stretch" 43 VerticalAlignment="Stretch" Stroke="Transparent" 44 StrokeThickness="5" Fill="{TemplateBinding Background}" 45 RadiusX="10" RadiusY="10"/> 46 <!--glass rectangle--> 47 <Rectangle x:Name="glassCube" HorizontalAlignment="Stretch" 48 VerticalAlignment="Stretch" StrokeThickness="1" 49 RadiusX="5" RadiusY="5" Opacity="0" 50 Fill="{StaticResource myGlassBrushResource}" 51 RenderTransformOrigin="0.5,0.5"> 52 <!--rectangle stroke--> 53 <Rectangle.Stroke> 54 <LinearGradientBrush StartPoint=" 0.5,0" EndPoint="0.5,1"> 55 <LinearGradientBrush.GradientStops> 56 <GradientStop Color="LightBlue" Offset="0.0"/> 57 <GradientStop Color="Gray" Offset="1.0"/> 58 </LinearGradientBrush.GradientStops> 59 </LinearGradientBrush> 60 </Rectangle.Stroke> 61 <!--glass rectangle render transform--> 62 <Rectangle.RenderTransform> 63 <TransformGroup> 64 <!--To stretch or contact horizontally or vertially--> 65 <ScaleTransform/> 66 <!--rotate transform by angles--> 67 <RotateTransform/> 68 </TransformGroup> 69 </Rectangle.RenderTransform> 70 </Rectangle> 71 <!--dock panel--> 72 <DockPanel Name="myContentPresenterDockPanel"> 73 <ContentPresenter x:Name="myContentPresent" HorizontalAlignment="Center" Margin="0,20" 74 Content="{TemplateBinding Content}" TextBlock.Foreground="Black" TextBlock.FontWeight="Bold"/> 75 </DockPanel> 76 </Grid> 77 <!--control template--> 78 <ControlTemplate.Triggers> 79 <!--mouse over trigger--> 80 <Trigger Property="IsMouseOver" Value="True"> 81 <!--rectangle stroke--> 82 <Setter Property="Rectangle.Stroke" TargetName="outerRectangle" 83 Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> 84 <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube"/> 85 </Trigger> 86 <!--Mouse focused trigger--> 87 <Trigger Property="IsFocused" Value="True"> 88 <Setter Property="Rectangle.Stroke" TargetName="innerRectangle" 89 Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> 90 <Setter Property="Rectangle.Opacity" Value="1" TargetName="glassCube"/> 91 </Trigger> 92 <!--Event trigger mouse enter--> 93 <EventTrigger RoutedEvent="Mouse.MouseEnter"> 94 <!--actions--> 95 <EventTrigger.Actions> 96 <!--begin story board--> 97 <BeginStoryboard Name="mouseEnterBeginStoryboard"> 98 <Storyboard> 99 <!--animation--> 100 <DoubleAnimation Storyboard.TargetName="glassCube" 101 Storyboard.TargetProperty= 102 "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" 103 By="-0.2" Duration="0:0:0.5" /> 104 <DoubleAnimation Storyboard.TargetName="glassCube" 105 Storyboard.TargetProperty= 106 "(Rectangle.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" 107 By="-0.2" Duration="0:0:0.5" /> 108 </Storyboard> 109 </BeginStoryboard> 110 </EventTrigger.Actions> 111 </EventTrigger> 112 <!--event trigger mouse leave--> 113 <EventTrigger RoutedEvent="Mouse.MouseLeave"> 114 <EventTrigger.Actions> 115 <StopStoryboard BeginStoryboardName="mouseEnterBeginStoryboard"/> 116 </EventTrigger.Actions> 117 </EventTrigger> 118 <!--event trigger button click--> 119 <EventTrigger RoutedEvent="Button.Click"> 120 <EventTrigger.Actions> 121 <BeginStoryboard> 122 <Storyboard> 123 <DoubleAnimation Storyboard.TargetName="glassCube" 124 Storyboard.TargetProperty= 125 "(Rectangle.RenderTransform).(TransformGroup.Children)[1].(RotateTransform.Angle)" 126 By="360" Duration="0:0:0.5"/> 127 </Storyboard> 128 </BeginStoryboard> 129 </EventTrigger.Actions> 130 </EventTrigger> 131 </ControlTemplate.Triggers> 132 </ControlTemplate> 133 </Setter.Value> 134 </Setter> 135 </Style> 136 137 <Style TargetType="Label"> 138 <Setter Property="FontWeight" Value="Bold"/> 139 </Style> 140 <Style TargetType="TextBox"> 141 <Setter Property="Background" Value="LightCyan"/> 142 </Style> 143 </Window.Resources> 144 <Grid Margin="0,-2,0,2"> 145 <TextBox HorizontalAlignment="Left" VerticalAlignment="Top" VerticalScrollBarVisibility="Auto" 146 Width="324" Height="119" Name="m_textBox1" Margin="10,40,0,0"/> 147 <TextBox Name="m_textBox2" HorizontalAlignment="Left" VerticalScrollBarVisibility="Auto" 148 Height="106" Margin="10,195,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="324"/> 149 150 <ComboBox Name="myCOM" Margin="0,58,38,0" VerticalAlignment="Top" HorizontalAlignment="Right" Width="90" Height="22"/> 151 <ComboBox Name="myBaudRate" Margin="0,116,38,0" VerticalAlignment="Top" HorizontalAlignment="Right" Width="90" Height="22"/> 152 153 <Label Content="COM" HorizontalAlignment="Left" Margin="389,27,0,0" VerticalAlignment="Top" Width="62"/> 154 <Label Content="BaudRate" HorizontalAlignment="Left" Margin="389,85,0,0" VerticalAlignment="Top"/> 155 <Label Content="Received Data" HorizontalAlignment="Left" Margin="15,10,0,0" VerticalAlignment="Top" Width="97"/> 156 <Label Content="Transmit Data" HorizontalAlignment="Left" Margin="15,164,0,0" VerticalAlignment="Top" Width="97"/> 157 158 <Button Content="Clear" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="51" Margin="0,0,22,80" Click="Btn2_Click" Height="58"/> 159 <Button Content="Open" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="51" Margin="0,0,95,81" Click="Btn1_Click" 160 Name="myBtn" RenderTransformOrigin="0.5,0.5" Height="57"/> 161 162 </Grid> 163 </Window>
CS:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Windows; 7 using System.Windows.Controls; 8 using System.Windows.Data; 9 using System.Windows.Documents; 10 using System.Windows.Input; 11 using System.Windows.Media; 12 using System.Windows.Media.Imaging; 13 using System.Windows.Navigation; 14 using System.Windows.Shapes; 15 using System.IO.Ports; 16 using System.Security.Cryptography; 17 18 namespace SearilPort 19 { 20 /// <summary> 21 /// Interaction logic for MainWindow.xaml 22 /// </summary> 23 public partial class MainWindow : Window 24 { 25 SerialPort myPort = new SerialPort(); 26 bool serialState; 27 public MainWindow() 28 { 29 InitializeComponent(); 30 myComboxs(); 31 } 32 private void myComboxs() 33 { 34 myCOM.Items.Add("COM0"); 35 myCOM.Items.Add("COM1"); 36 myCOM.Items.Add("COM2"); 37 myCOM.Items.Add("COM3"); 38 myCOM.Items.Add("COM4"); 39 myCOM.SelectedIndex = myCOM.Items.IndexOf("COM1"); 40 myBaudRate.Items.Add("2400"); 41 myBaudRate.Items.Add("4800"); 42 myBaudRate.Items.Add("9600"); 43 myBaudRate.Items.Add("38400"); 44 myBaudRate.Items.Add("115200"); 45 myBaudRate.SelectedIndex = myBaudRate.Items.IndexOf("9600"); 46 serialState = false; 47 myPort.DataReceived += DataReceived; 48 } 49 private void Btn1_Click(object sender, RoutedEventArgs e) 50 { 51 try 52 { 53 if (serialState == false) 54 { 55 if(myPort.IsOpen) 56 { 57 myPort.Close(); 58 } 59 myPort.BaudRate = int.Parse(myBaudRate.Text); 60 myPort.DataBits = 8; 61 myPort.PortName = myCOM.Text; 62 myPort.Open(); 63 serialState = true; 64 m_textBox1.Text = "Serial Port is Opened...\r\n"; 65 myBtn.Content = "Closed"; 66 } 67 else 68 { 69 if (myPort.IsOpen) 70 { 71 myPort.Close(); 72 } 73 serialState = false; 74 m_textBox1.Text = "Serial Port is Closed...\r\n"; 75 m_textBox2.Text = ""; 76 myBtn.Content = "Open"; 77 } 78 } 79 catch(Exception ex) 80 { 81 MessageBox.Show(ex.Message); 82 } 83 } 84 private void Btn2_Click(object sender, RoutedEventArgs e) 85 { 86 m_textBox1.Text = ""; 87 m_textBox2.Text = ""; 88 } 89 private void DataReceived(object sender,SerialDataReceivedEventArgs e) 90 { 91 try 92 { 93 byte[] inbuf = new byte[8]; 94 byte[] output = new byte[16]; 95 myPort.Read(inbuf, 0, inbuf.Length); 96 string str = System.Text.Encoding.Default.GetString(inbuf); 97 this.Dispatcher.Invoke(new Action(() => 98 { 99 foreach (byte i in inbuf) 100 { 101 m_textBox1.Text += i.ToString("X2"); 102 } 103 m_textBox1.Text += "\r\n"; 104 using (var aes = new RijndaelManaged()) 105 { 106 aes.Key = new byte[] { 0x1F, 0x54, 0x52, 0x6A, 0x73, 0x93, 0x58, 0x9E, 0x4B, 0xCF, 0xFB, 0xAE, 0xFC, 0x97, 0x59, 0x3E }; 107 aes.IV = new byte[16]; 108 aes.Padding = PaddingMode.None; 109 for (int i = 0; i < 8; i++) 110 { 111 output[i] = inbuf[i]; 112 } 113 for (byte i = 8; i < 16; i++) 114 { 115 output[i] = (byte)(output[i - 8] ^ output[i - 4]); 116 } 117 m_textBox1.Text += "16 byte ids:\r\n"; 118 foreach (byte i in output) 119 m_textBox1.Text += i.ToString("X2"); 120 m_textBox1.Text += "\r\n"; 121 var cryptoTransform = aes.CreateEncryptor(); 122 byte[] resultBuffer = cryptoTransform.TransformFinalBlock(output, 0, output.Length); 123 m_textBox2.Text += "SerialNo.=\r\n"; 124 foreach (byte i in resultBuffer) 125 { 126 m_textBox2.Text += i.ToString("X2"); 127 } 128 m_textBox2.Text += "\r\n"; 129 } 130 myPort.Write(output,0,output.Length); 131 m_textBox1.ScrollToEnd(); 132 m_textBox2.ScrollToEnd(); 133 })); 134 } 135 catch(Exception ex) 136 { 137 MessageBox.Show(ex.Message); 138 } 139 } 140 } 141 }
编译运行:
End.
谢谢.