添加页面

This commit is contained in:
2026-05-15 09:04:36 +08:00
parent bd871ee6c5
commit 8ef4a199c4
3 changed files with 146 additions and 22 deletions

View File

@@ -65,7 +65,13 @@ namespace TabletTester2025.ViewModels
OpenCalibrationCommand = new AsyncRelayCommand(() => { MessageBox.Show("校准功能待实现"); return Task.CompletedTask; });
// 跳转到 PlcDataPage 页面
ShowDataCommand = new AsyncRelayCommand(() => { new ShowData().ShowDialog(); return Task.CompletedTask; });
ShowDataCommand = new AsyncRelayCommand(async () =>
{
// 用你项目里已有的PLC实例假设叫 _plcClient
var window = new ShowData(_plc);
window.ShowDialog();
});
}
private async Task ConnectToPlc()

View File

@@ -1,13 +1,9 @@
<Window x:Class="片剂四用仪.Views.ShowData"
<Window x:Class="片剂四用仪.Views.PharmacopoeiaSettingsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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:local="clr-namespace:片剂四用仪.Views"
mc:Ignorable="d"
Title="ShowData" Height="768" Width="1024"
Title="药典参数设置" Height="768" Width="1024"
WindowStartupLocation="CenterScreen"
Background="#F5F5F5">
Background="#F0F2F5">
<Window.Resources>
@@ -15,7 +11,7 @@
<Style x:Key="CardStyle" TargetType="Border">
<Setter Property="Background" Value="White"/>
<Setter Property="CornerRadius" Value="10"/>
<Setter Property="Margin" Value="15"/>
<Setter Property="Margin" Value="15,15,80,15"/>
<Setter Property="Padding" Value="15"/>
<Setter Property="Effect">
<Setter.Value>

View File

@@ -1,25 +1,147 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using TabletTester2025.Services;
namespace .Views
{
/// <summary>
/// ShowData.xaml 的交互逻辑
/// </summary>
public partial class ShowData : Window
{
public ShowData()
private readonly IPlcService _plc;
private CancellationTokenSource _cts;
public ShowData(IPlcService plc)
{
InitializeComponent();
_plc = plc;
Loaded += ShowData_Loaded;
Closing += ShowData_Closing;
}
private async void ShowData_Loaded(object sender, RoutedEventArgs e)
{
_cts = new CancellationTokenSource();
BindAllTextBoxWriteEvents();
await StartPlcReadLoop(_cts.Token);
}
private void ShowData_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
_cts?.Cancel();
}
// ====================== 读取 PLC ======================
private async Task StartPlcReadLoop(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
try
{
foreach (var m in _paramMappings)
{
var tb = FindName(m.TextBoxName) as TextBox;
if (tb == null) continue;
if (m.Type == PlcParamType.Int)
{
ushort[] res = await _plc.ReadHoldingRegistersAsync((ushort)m.Address, 1);
Dispatcher.Invoke(() => tb.Text = res[0].ToString());
}
else
{
ushort[] res = await _plc.ReadHoldingRegistersAsync((ushort)m.Address, 2);
float value = BitConverter.ToSingle(BitConverter.GetBytes((uint)(res[0] << 16 | res[1])), 0);
Dispatcher.Invoke(() => tb.Text = value.ToString("F2"));
}
}
}
catch { }
await Task.Delay(1000, token);
}
}
// ====================== 写入 PLC ======================
private void BindAllTextBoxWriteEvents()
{
foreach (var m in _paramMappings)
{
var tb = FindName(m.TextBoxName) as TextBox;
if (tb == null) continue;
tb.LostFocus += async (s, e) =>
{
try
{
if (m.Type == PlcParamType.Int)
{
if (int.TryParse(tb.Text, out int val))
await _plc.WriteRegisterAsync((ushort)m.Address, (ushort)val);
}
else
{
if (float.TryParse(tb.Text, out float val))
{
byte[] bytes = BitConverter.GetBytes(val);
ushort[] regs = new ushort[2];
regs[0] = (ushort)(BitConverter.ToUInt16(bytes, 2));
regs[1] = (ushort)(BitConverter.ToUInt16(bytes, 0));
await _plc.WriteRegisterAsync((ushort)m.Address, (ushort)val);
}
}
}
catch { }
};
}
}
// ====================== 地址映射表 ======================
private readonly PlcParamMapping[] _paramMappings = new[]
{
new PlcParamMapping("txt_HardnessSpeed", 300, PlcParamType.Float),
new PlcParamMapping("txt_HardnessDisplacement", 310, PlcParamType.Float),
new PlcParamMapping("txt_HardnessMotorLimit", 298, PlcParamType.Float),
new PlcParamMapping("txt_HardnessDamageThreshold", 400, PlcParamType.Float),
new PlcParamMapping("txt_MaxForceCollect", 72, PlcParamType.Float),
new PlcParamMapping("txt_BrittlenessTestTime", 410, PlcParamType.Int),
new PlcParamMapping("txt_PreBrittlenessMass", 412, PlcParamType.Int),
new PlcParamMapping("txt_PostBrittlenessMass", 414, PlcParamType.Int),
new PlcParamMapping("txt_WeightLossRate", 416, PlcParamType.Int),
new PlcParamMapping("txt_DisintegrationSpeed", 330, PlcParamType.Float),
new PlcParamMapping("txt_DisintegrationTime", 420, PlcParamType.Int),
new PlcParamMapping("txt_DissolutionTime", 430, PlcParamType.Int),
new PlcParamMapping("txt_DissolutionSamplingInterval", 432, PlcParamType.Int),
new PlcParamMapping("txt_ForceDisplay", 1314, PlcParamType.Float),
new PlcParamMapping("txt_ForceCoefficient", 1320, PlcParamType.Float),
new PlcParamMapping("txt_ForceProtection", 1322, PlcParamType.Float),
new PlcParamMapping("txt_TemperatureCoefficient", 1428, PlcParamType.Float),
new PlcParamMapping("txt_TemperatureDisplay", 1430, PlcParamType.Float),
};
}
internal class PlcParamMapping
{
public string TextBoxName { get; }
public int Address { get; }
public PlcParamType Type { get; }
public PlcParamMapping(string textBoxName, int address, PlcParamType type)
{
TextBoxName = textBoxName;
Address = address;
Type = type;
}
}
internal enum PlcParamType
{
Int,
Float
}
}