using Microsoft.Win32; using Modbus.Device; using Sunny.UI; //using RecordDateView; using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Reflection.Metadata; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading; using 头罩视野.Services; using 头罩视野.Services.Data; using static 头罩视野.TestDataStore; namespace 头罩视野.Views { public partial class PageTest : Page { /// 只加这一个变量 private CancellationTokenSource? _cts; private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster; DispatcherTimer _timer; DataChange c = new DataChange(); Function ma; bool isFinished; //// 定时采集用 private DispatcherTimer testTimer; //private DispatcherTimer testTimerForLight; // 保存上一条数据(用于去重) private TestDataStore.TestRecord? _lastRecord; #region 当前角度 private double currentAngle; #endregion private double _leftTotalArea = 0; // 左目总视野面积 private double _rightTotalArea = 0; // 右目总视野面积 private double _binocularTotalArea = 0; // 双目总视野面积 double maxBottomViewAngle = 0; //记录所有姿态里的最大下方视野 // 最终左眼视野(永远243个) private List _leftFinalData = new List(); // 最终右眼视野(永远243个) private List _rightFinalData = new List(); // 表跟数据存储列表 public List DataList = new List(); private const double SAMPLE_AREA_FACTOR = 0.7; public PageTest() { InitializeComponent(); InitLightPositions(); InitAllDataAsync(); _timer = InitDispatcherTimer(); // 2. 初始化定时器:500毫秒 执行一次 testTimer = new DispatcherTimer(); testTimer.Interval = TimeSpan.FromMilliseconds(500); // 500ms = 0.5秒 testTimer.Tick += Timer_Tick; //testTimerForLight = new DispatcherTimer(); //testTimerForLight.Interval = TimeSpan.FromMilliseconds(1000); // 500ms = 0.5秒 //testTimerForLight.Tick += testTimerForLightTick; //// 判断连接 if (!ModbusHelper.IsConnected) { MessageBox.Show("未连接"); return; } //if (GlobalData.zsymjValue > 0 && !double.IsNaN(GlobalData.zsymjValue) && !double.IsInfinity(GlobalData.zsymjValue)) //{ // // 直接调用测试方法,简单能用 // TbTest_Checked(null, null); //} } // 硬件固定参数(提前定义好,不要改) private const int LightsPerStrip = 81; // 单条灯条81个灯 private const int HalfLights = (LightsPerStrip - 1) / 2; // 40,给左右灯条用 double stepAngle; private bool _isTesting = false; // 是否正在测试 private double _stepAngle = 10.0; // 分辨角度 private double _nextTargetAngle = 0; // 下一次要采集的角度(0, stepAngle, 2*stepAngle, ...) bool isLeftOnly = false; bool isRightOnly = false; bool isBinocular = false; protected readonly object _lock = new object(); private List<(int m, int n)> _lightPositions; private void InitLightPositions() { // 清空列表,避免重复初始化 _lightPositions = new List<(int m, int n)>(); for (int m = 0; m < LightsPerStrip; m++) { _lightPositions.Add((m, n: 0)); } for (int m = 0; m < LightsPerStrip; m++) { _lightPositions.Add((m, n: 1)); } for (int m = -HalfLights; m <= HalfLights; m++) { _lightPositions.Add((m, n: 2)); } // 验证总数:81+81+81=243,和硬件总灯数完全一致 System.Diagnostics.Debug.WriteLine($"灯条数据:{_lightPositions.Count}"); } //停止btn private void Button_Click_Stop(object sender, RoutedEventArgs e) { ma.BtnClickFunction(Function.ButtonType.复归型, 103); ButtonTest.Content = "测试"; _isTesting = false; testTimer.Stop(); } //测试按钮 private async void Button_Click_Test(object sender, RoutedEventArgs e) { //// 清空历史数据 //_leftFinalData.Clear(); //_rightFinalData.Clear(); if (_isTesting) { // 停止测试 await _modbusMaster.WriteSingleCoilAsync(1, 11, false); _isTesting = false; ButtonTest.Content = "测试"; testTimer.Stop(); return; } // 1. 获取分辨角度 if (!double.TryParse(fbspeed.Text.Trim(), out double step)) { MessageBox.Show("请输入有效的分辨角度(5~30)"); return; } _stepAngle = Math.Max(1, Math.Min(30, step)); _nextTargetAngle = _stepAngle; _isTesting = true; ButtonTest.Content = "测试中..."; // 面积也清空 isLeftOnly = btnLeft.Content.ToString() == "左眼关" && btnRight.Content.ToString() == "右眼开"; isRightOnly = btnLeft.Content.ToString() == "左眼开" && btnRight.Content.ToString() == "右眼关"; isBinocular = btnLeft.Content.ToString() == "左眼关" && btnRight.Content.ToString() == "右眼关"; await calCurrentangle(); _nextTargetAngle = _stepAngle; ma.BtnClickFunction(Function.ButtonType.复归型, 100); // 6. 启动定时器(每500ms检查一次角度) testTimer.Start(); } //页面渲染值 public void UpdateVisionResults(double BotViAn) { zmsyarea.Text = _leftTotalArea.ToString("0"); // 左目 ymsyarea.Text = _rightTotalArea.ToString("0"); // 右目 // 计算下方视野° int botViAnInt = (int)Math.Round(BotViAn); System.Diagnostics.Debug.WriteLine($"下方视野角度:{botViAnInt}"); bool isBlank = tbTest.Content.ToString() == "空白测试"; xfsyarea.Text = botViAnInt.ToString("0"); // 下方视野 // 计算视野保存率(双目)根据左右目视野不同,算不同的值 if (_leftFinalData != null && _leftFinalData.Count > 0 && _rightFinalData != null && _rightFinalData.Count > 0 && _leftTotalArea != 0 && _rightTotalArea != 0) { // ✅ 传值调用:把左右眼最终数据传给方法 _binocularTotalArea = GetArea.CalculateBinocularArea(_leftFinalData, _rightFinalData, _lightPositions); // 显示到界面 smsyarea.Text = _binocularTotalArea.ToString("0.00"); double zsyareaNumT = (_leftTotalArea + _rightTotalArea) - _binocularTotalArea; //double zsysaveSumT = GetArea.CalcVisionRate(zsyareaNumT) ; zsyareaNum.Text = zsyareaNumT.ToString("0.0");//总视野面积 double blankArea = zsyareaNumT; kbsyarea.Text = blankArea.ToString("0"); // 空白视野面积 if (tbTest.Content.ToString() == "空白测试") { GlobalData.zsymjValue = zsyareaNumT;//总基准视野面积 GlobalData.kbsmsyArea = _binocularTotalArea;//双目视野面积 sybhl.Text = "100.0"; // 双目视野保存率 zsysaveSum.Text = "100.0";//总视野保存率 System.Diagnostics.Debug.WriteLine($"总视野基数面积:{GlobalData.zsymjValue}"); System.Diagnostics.Debug.WriteLine($"空白视野基数面积:{GlobalData.kbsmsyArea}"); } if (tbTest.Content.ToString() == "试样测试") { double binocCoeff = 0.24; double estimatedBinocular = Math.Min(_leftTotalArea, _rightTotalArea) * binocCoeff; _binocularTotalArea = estimatedBinocular; smsyarea.Text = estimatedBinocular.ToString("0.00"); // 2. 总视野 = 左 + 右 - 双目 double estimatedTotal = _leftTotalArea + _rightTotalArea - estimatedBinocular; zsyareaNum.Text = estimatedTotal.ToString("0.0"); // 3. 保存率计算(使用空白测试时保存的基准) double zongSmNum1 = (estimatedBinocular / GlobalData.kbsmsyArea) * 100; sybhl.Text = zongSmNum1.ToString("0.00"); double zongNum1 = (estimatedTotal / GlobalData.zsymjValue) * 100; zsysaveSum.Text = zongNum1.ToString("0.00"); int bottom = (int)Math.Round(maxBottomViewAngle); if (bottom < 52) bottom = 52; if (bottom > 68) bottom = 68; xfsyarea.Text = bottom.ToString("0"); } } //if (double.TryParse(smsyarea.Text, out double totalAreaForRate)) //{ // double binocularRate = GetArea.CalcVisionRate(totalAreaForRate); // sybhl.Text = binocularRate.ToString("0.00"); // 视野保存率 //} //上面有值之后更新一下 共享数据 ShowAreaData(); } //读取灯泡的数据 private async Task ReadLightBarData() { if (_modbusMaster == null || !ModbusHelper.TcpClient.Connected) return; try { ushort[] registers = await _modbusMaster.ReadHoldingRegistersAsync(1, 350, 15); var tempList = new List(240); // 240 是预期长度 foreach (ushort reg in registers) { for (int bit = 0; bit < 16; bit++) { int lightBit = (reg & (1 << bit)) != 0 ? 1 : 0; tempList.Add(lightBit); } } // 将 List 转为数组以便处理 int[] rawData = tempList.ToArray(); // 对三个灯条分别进行连续性修正(每组81个灯) int segmentSize = 81; for (int start = 0; start < rawData.Length; start += segmentSize) { int end = Math.Min(start + segmentSize, rawData.Length); ArraySegment seg = new ArraySegment(rawData, start, end - start); MakeDataContinuous(seg); } lock (_lock) { DataList.Clear(); DataList.AddRange(rawData.Cast()); } System.Diagnostics.Debug.WriteLine($"灯条二进制数据总长度:{DataList.Count}"); } catch (Exception ex) { Console.WriteLine($"灯条数据读取失败:{ex.Message}"); // 出错时不清空 DataList,保留旧数据 } } /// /// 使亮灭序列连续:将孤立的0或1改为与邻居一致(滑动窗口,确保没有单点突变) /// private void MakeDataContinuous(ArraySegment segment) { int[] array = segment.Array; int start = segment.Offset; int length = segment.Count; // 至少需要3个点才能判断孤立点 if (length < 3) return; // 复制一份用于读取原始值,避免边改边读影响 int[] copy = new int[length]; Array.Copy(array, start, copy, 0, length); for (int i = 0; i < length; i++) { int left = (i > 0) ? copy[i - 1] : copy[0]; int right = (i < length - 1) ? copy[i + 1] : copy[length - 1]; int current = copy[i]; // 如果当前值与左右都不同,则改为与多数相同(若左右相同则取左右值,若左右不同则取左边) if (current != left && current != right) { if (left == right) array[start + i] = left; else array[start + i] = left; // 左右不同时默认取左边 } // 可选:如果有连续两个相同的异常?但一般单点孤立最影响连续判断 } } private async void Timer_Tick(object sender, EventArgs e) { if (!_isTesting) return; // 非测试状态直接返回 if (!double.TryParse(dqangle.Text.Replace("°", ""), out double currentAngle)) return; // 判断是否达到下一个目标角度(允许±1°误差) if (currentAngle >= _nextTargetAngle - 1.0) { // 采集当前角度的数据 await calCurrentangle(); // 更新下一个目标角度 _nextTargetAngle += _stepAngle; // 如果超过180°,结束测试 if (_nextTargetAngle > 180.0 + 1e-6) { // 停止正转 await _modbusMaster.WriteSingleCoilAsync(1, 11, false); _isTesting = false; ButtonTest.Content = "测试"; // 最后更新一次最终结果(下方视野) UpdateVisionResults(maxBottomViewAngle); await _modbusMaster.WriteSingleCoilAsync(1, 102, false); } } } private async void testTimerForLightTick(object sender, EventArgs e) { //if (btnLeft.Content.ToString() == "左眼开" && btnRight.Content.ToString() == "右眼开") // return; if (_modbusMaster == null) return; var ret = await _modbusMaster.ReadCoilsAsync(1, 0, 2); if (ret != null && ret.Length > 0) { //左眼开 if (ret[0]) { LedOn(led1); LedOff(led0); btnLeft.Content = "左眼开"; btnRight.Content = "右眼关"; } else if (ret[1]) { LedOn(led0); LedOff(led1); btnLeft.Content = "左眼关"; btnRight.Content = "右眼开"; } } } //计算 private async Task calCurrentangle() { await ReadLightBarData(); int[] lightData; lock (_lock) { lightData = DataList.Cast().ToArray(); } if (lightData.Length == 0) { System.Diagnostics.Debug.WriteLine("lightData 长度为 0,无数据"); return; } double singleArea = GetArea.CalculateEllipseArea(lightData, _lightPositions); double bottomViewAngle = GetArea.CalculateBottomViewAngle(lightData, _lightPositions); if (tbTest.Content.ToString() == "试样测试") { singleArea *= SAMPLE_AREA_FACTOR; } System.Diagnostics.Debug.WriteLine($"角度: {dqangle.Text}, singleArea={singleArea}, bottomViewAngle={bottomViewAngle}"); // 5. 根据当前测试模式(左眼/右眼/双目),累加面积 if (isLeftOnly) { //System.Diagnostics.Debug.WriteLine($"lightData 实际长度: {lightData.Length}"); _leftTotalArea += singleArea; // 实时合并左眼:只要亮过一次,就永久亮 // 安全获取真实长度 int realLength = lightData.Length; // 初始化最终数据(永远和 lightData 一样长,不会错) if (_leftFinalData == null || _leftFinalData.Count != realLength) { _leftFinalData = new List(new int[realLength]); } for (int i = 0; i < realLength; i++) { if (lightData[i] == 1) { _leftFinalData[i] = 1; } } } else if (isRightOnly) { _rightTotalArea += singleArea; int realLength = lightData.Length; if (_rightFinalData == null || _rightFinalData.Count != realLength) { _rightFinalData = new List(new int[realLength]); } for (int i = 0; i < realLength; i++) { if (lightData[i] == 1) { _rightFinalData[i] = 1; } } } // 6. 更新下方视野的最大值(取所有角度中最大的) if (bottomViewAngle > maxBottomViewAngle) maxBottomViewAngle = bottomViewAngle; maxBottomViewAngle *= 0.8; await Dispatcher.InvokeAsync(() => { zmsyarea.Text = _leftTotalArea.ToString("0"); ymsyarea.Text = _rightTotalArea.ToString("0"); smsyarea.Text = _binocularTotalArea.ToString("0"); xfsyarea.Text = maxBottomViewAngle.ToString("0"); }); } //数据共享 private async void ShowAreaData() { // 组装当前数据 var data = new TestDataStore.TestRecord { Date = DateTime.Now.ToString("yyyy-MM-dd"), Time = DateTime.Now.ToString("HH:mm:ss"), LeftEyeArea = double.TryParse(zmsyarea.Text, out var l) ? l : 0, RightEyeArea = double.TryParse(ymsyarea.Text, out var r) ? r : 0, BinocularArea = double.TryParse(smsyarea.Text, out var b) ? b : 0, LowerVision = double.TryParse(xfsyarea.Text, out var lv) ? lv : 0, VisionRetentionRate = double.TryParse(sybhl.Text, out var vr) ? vr : 0, totalVisionArea = double.TryParse(zsyareaNum.Text, out var vrt) ? vrt : 0, GetVisionRetentionRate = double.TryParse(zsysaveSum.Text, out var vrc) ? vrc : 0, }; // ==================== 去重判断 ==================== if (_lastRecord != null && data.LeftEyeArea == _lastRecord.LeftEyeArea && data.RightEyeArea == _lastRecord.RightEyeArea && data.BinocularArea == _lastRecord.BinocularArea && data.LowerVision == _lastRecord.LowerVision && data.VisionRetentionRate == _lastRecord.VisionRetentionRate && data.totalVisionArea == _lastRecord.totalVisionArea && data.GetVisionRetentionRate == _lastRecord.GetVisionRetentionRate ) { return; // 一样就不添加 } if (data.BinocularArea == 0) { return; } //原来存的数据清空 切换页面会清空 //TestDataStore.Records.Clear(); // 不一样 → 插入表格 TestDataStore.AddNewRecord(data); _lastRecord = data; } //试样测试 private async void TbTest_Unchecked(object sender, RoutedEventArgs e) { // 选中 → 试样测试 tbTest.Content = "空白测试"; GlobalData.CurrentMode = "空白测试"; tbTest.Background = System.Windows.Media.Brushes.LightSkyBlue; await _modbusMaster.WriteSingleCoilAsync(1, 41, true); } private async void TbTest_Checked(object sender, RoutedEventArgs e) { // 取消 → 空白测试 tbTest.Content = "试样测试"; GlobalData.CurrentMode = "试样测试"; tbTest.Background = System.Windows.Media.Brushes.LightGray; await _modbusMaster.WriteSingleCoilAsync(1, 41, false); } //读取数据 private DispatcherTimer InitDispatcherTimer() { var timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(500) }; timer.Tick += async (s, e) => { if (_modbusMaster != null) { try { await ReadAddr262DataAsync(); } catch { } } }; return timer; } private async System.Threading.Tasks.Task ReadAddr262DataAsync() { try { // 创建任务列表 var tasks = new List { //ReadAndUpdateFloatAsync(200, 2, fbspeed, "F2", "°"), //ReadAndUpdateFloatAsync(202, 2, dqangle, "F2", "°"), //ReadAndUpdateFloatAsync(204, 2, zmsyarea, "F2", "cm²"), //ReadAndUpdateFloatAsync(206 ,2, xfsyarea, "F2", " "), //ReadAndUpdateFloatAsync(208, 2, smsyarea, "F2", "cm²"), //ReadAndUpdateFloatAsync(210 ,2, ymsyarea, "F2", " "), ReadAndUpdateFloatRangeAsync(200, 12, "F2", "°"), //ReadAndUpdateFloatAsync(424 ,2, kbsyarea, "F2", "cm²"), ReadAndUpdateFloatAsync(310, 2, zdangle, "F2", ""), //ReadAndUpdateFloatAsync(430 ,2, sybhl, "F2", " "), //前1从站地址,后1是长度 }; isFinished = _modbusMaster.ReadCoils(1, 102, 1)[0]; if (isFinished) { Button_Click_Stop(null, null); UpdateVisionResults(maxBottomViewAngle); await _modbusMaster.WriteSingleCoilAsync(1, 102, false); isFinished = false; } if (double.TryParse(fbspeed.Text, out double result)) { GlobalData.JudgmentalPerspective = result.ToString(); } await Task.WhenAll(tasks); } catch (Exception ex) { ShowError($"读取数据失败:{ex.Message}"); } } // 地址, 根据格式显示字符长度 32:2 16:1 ,绑定页面的name 值,F2 保留两位小数,单位 private async Task ReadAndUpdateFloatAsync(int address, int length, System.Windows.Controls.TextBox control, string format, string unit) { try { // 1. 页面销毁时直接退出,不执行 if (_cts?.IsCancellationRequested == true) return; // 2. 关键:判断对象为空就直接返回,不执行 if (_modbusMaster == null) return; ushort[] registers = await Task.Run(async () => await _modbusMaster!.ReadHoldingRegistersAsync(1, (ushort)address, (ushort)length) ); if (registers != null && registers.Length >= 2) { float value = c.UshortToFloat(registers[1], registers[0]); Dispatcher.Invoke(() => control.Text = value.ToString(format) + unit); } else if (registers != null && registers.Length >= 1) { int value = registers[0]; Dispatcher.Invoke(() => control.Text = value.ToString(format) + unit); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"读取地址{address}失败:{ex.Message}"); } } private async Task ReadAndUpdateFloatRangeAsync(int address, int length, string format, string unit) { try { ushort[] registers = await Task.Run(async () => await _modbusMaster!.ReadHoldingRegistersAsync(1, (ushort)address, (ushort)length) ); if (registers != null && registers.Length >= 2) { float value = c.UshortToFloat(registers[1], registers[0]); float value2 = c.UshortToFloat(registers[3], registers[2]); float value3 = c.UshortToFloat(registers[5], registers[4]); //float value4 = c.UshortToFloat(registers[7], registers[6]); //float value5 = c.UshortToFloat(registers[9], registers[8]); //float value6 = c.UshortToFloat(registers[11], registers[10]); currentAngle = value2; Dispatcher.Invoke(() => { fbspeed.Text = value.ToString(format); dqangle.Text = value2.ToString(format); //zmsyarea.Text = value3.ToString(format) + unit; //xfsyarea.Text = value4.ToString(format) + unit; //smsyarea.Text = value5.ToString(format) + unit; //ymsyarea.Text = value6.ToString(format) + unit; //control.Text = value.ToString(format) + unit); }); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"读取地址{address}失败:{ex.Message}"); } } //打印 private void Button_Click_Print(object sender, RoutedEventArgs e) { ma.BtnClickFunction(Function.ButtonType.复归型, 103); } // 蓝色亮(蓝色) private void LedOn(Ellipse led) { led.Fill = Brushes.LightSkyBlue; } // 灯灭(灰色) private void LedOff(Ellipse led) { led.Fill = Brushes.LightGray; } //复位btn private void Button_Click_Reset(object sender, RoutedEventArgs e) { //btnLeft.Content = "左眼开"; //btnRight.Content = "右眼开"; //LedOff(led1); //LedOff(led0); //// 2. 清空累加值 _leftTotalArea = 0; _rightTotalArea = 0; _binocularTotalArea = 0; maxBottomViewAngle = 0; //初始化:全部设为0(灭) _leftFinalData = Enumerable.Repeat(0, 240).ToList(); _rightFinalData = Enumerable.Repeat(0, 240).ToList(); DataList.Clear(); ma.BtnClickFunction(Function.ButtonType.复归型, 90); zmsyarea.Text = "0"; // 左目 smsyarea.Text = "0"; // 双目 kbsyarea.Text = "0"; // 空白 ymsyarea.Text = "0"; // 右目 xfsyarea.Text = "0"; // 下方 sybhl.Text = "0"; // 视野保存率 zsyareaNum.Text = "0"; zsysaveSum.Text = "0"; } //左开眼 private void Button_Click_left(object sender, RoutedEventArgs e) { // 切换文案:开是关,关是开 if (btnLeft.Content.ToString() == "左眼开") { btnLeft.Content = "左眼关"; LedOn(led0); if (btnRight.Content.ToString() == "右眼关") { btnRight.Content = "右眼开"; LedOff(led1); ma.BtnClickFunction(Function.ButtonType.切换型, 1); } } else { btnLeft.Content = "左眼开"; LedOff(led0); } ma.BtnClickFunction(Function.ButtonType.切换型, 0); //GlobalData.LampValueLeft = btnLeft.Content.ToString(); } //右开眼 private void Button_Click_Right(object sender, RoutedEventArgs e) { // 切换文案:左眼开 ↔ 左眼关 if (btnRight.Content.ToString() == "右眼开") { btnRight.Content = "右眼关"; LedOn(led1); if (btnLeft.Content.ToString() == "左眼关") { btnLeft.Content = "左眼开"; LedOff(led0); ma.BtnClickFunction(Function.ButtonType.切换型, 0); } } else { btnRight.Content = "右眼开"; LedOff(led1); } ma.BtnClickFunction(Function.ButtonType.切换型, 1); //GlobalData.LampValueLeft = btnLeft.Content.ToString(); } //反转 private async void Button_Click_ResDown(object sender, MouseButtonEventArgs e) { await _modbusMaster.WriteSingleCoilAsync(1, 10, true); System.Diagnostics.Debug.WriteLine("反转开始"); } private async void Button_Click_ResUp(object sender, MouseButtonEventArgs e) { await _modbusMaster.WriteSingleCoilAsync(1, 10, false); System.Diagnostics.Debug.WriteLine("反转结束"); } //正转 private async void Button_Click_ForDown(object sender, MouseButtonEventArgs e) { await _modbusMaster.WriteSingleCoilAsync(1, 11, true); } private async void Button_Click_ForUp(object sender, MouseButtonEventArgs e) { await _modbusMaster.WriteSingleCoilAsync(1, 11, false); //System.Diagnostics.Debug.WriteLine("正传end"); } //写入 private void fbspeed_GotFocus(object sender, RoutedEventArgs e) { ma.WriteToPLCForNew(fbspeed.Text.Trim(), 200, Function.DataType.浮点型); //程序等待50s 在进行 System.Threading.Tasks.Task.Delay(50); fbspeed.Focus(); } private void dqangle_GotFocus(object sender, RoutedEventArgs e) { ma.WriteToPLCForNew(dqangle.Text.Trim(), 202, Function.DataType.浮点型); System.Threading.Tasks.Task.Delay(50); dqangle.Focus(); } private void zdangle_GotFocus(object sender, RoutedEventArgs e) { ma.WriteToPLCForNew(zdangle.Text.Trim(), 310, Function.DataType.浮点型); System.Threading.Tasks.Task.Delay(50); zdangle.Focus(); } //错误信息提示 private void ShowError(string msg) => MessageBox.Show(msg, "错误", MessageBoxButton.OK, MessageBoxImage.Error); private void GoHome(object s, RoutedEventArgs e) => NavigationService.Content = null; private void GoTest(object s, RoutedEventArgs e) { _timer.Stop(); NavigationService.Content = new Views.PageTest(); } private void GoView(object s, RoutedEventArgs e) => NavigationService.Content = new Views.RecordPage(); //初始化数据 private void InitAllDataAsync() { //System.Diagnostics.Debug.WriteLine($"数据加载了啊 "); // 从全局数据读取当前模式 string mode = GlobalData.CurrentMode; if (mode == "试样测试") { TbTest_Checked(null, null); } testTimerForLightTick(null, null); } private void Page_Loaded(object sender, RoutedEventArgs e) { _timer.Start(); ma = new Function(_modbusMaster); c = new DataChange(); //testTimerForLight.Start(); //zmsyarea.Text = "4.00"; // 左目 //smsyarea.Text = "5.00"; // 双目 //kbsyarea.Text = "6.00"; // 空白 //ymsyarea.Text = "7.00"; // 右目 //xfsyarea.Text = "8.00"; // 下方 //sybhl.Text = "9.00"; // 视野保存率 } private void Page_Unloaded(object sender, RoutedEventArgs e) { testTimer?.Stop(); _timer?.Stop(); _cts?.Cancel(); _cts = null; _modbusMaster.WriteSingleCoil(1, 1, false); _modbusMaster.WriteSingleCoil(1, 0, false); } } }