Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2185fd759e | |||
| 88f24a75aa | |||
| 7e382a786d | |||
| cb94afb55b | |||
| 61e11f0753 | |||
| 577c4fdea1 | |||
| 1c6e33c6c8 | |||
| 23a818a000 | |||
| 3ce7f880f3 | |||
| ece5ab00f7 | |||
| 70308542c7 | |||
| 3c309d6470 |
@@ -1,263 +1,111 @@
|
||||
|
||||
using MathNet.Numerics.LinearAlgebra;
|
||||
using MathNetMatrix = MathNet.Numerics.LinearAlgebra.Matrix<double>;
|
||||
using MathNetVector = MathNet.Numerics.LinearAlgebra.Vector<double>;
|
||||
using System.Drawing;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace 头罩视野.Services
|
||||
{
|
||||
class GetArea
|
||||
public static class GetArea
|
||||
{
|
||||
// 设备固定参数
|
||||
public static double R = 325; // 半球半径
|
||||
|
||||
// 定义参数(和你代码里一致)
|
||||
public const int totalLights = 81;
|
||||
|
||||
public static double verticalAngleStep = 90.0 / (totalLights - 1); // 上下灯条用
|
||||
public static double horizontalAngleStep = 180.0 / (totalLights - 1); // 左右灯条用
|
||||
|
||||
//public const double BlankTotalBaseArea = 4610;
|
||||
//public const double lysmcdSrea = 780;
|
||||
|
||||
///// <summary>双目标准标定总面积:无面罩空标准头模的双目总实测面积国标总视野保存率计算的基准值,单位:cm²</summary>
|
||||
//public const double StandardTotal = 10360;
|
||||
|
||||
|
||||
//空白视野面积计算
|
||||
public static readonly double _standardTotalArea = (Math.PI * R * R) / 100;
|
||||
|
||||
public static double GetBlankViewArea(double binocularTotalArea)
|
||||
{
|
||||
// 公式:空白 = 标准总面积 - 双目总视野
|
||||
return _standardTotalArea - binocularTotalArea;
|
||||
}
|
||||
|
||||
//计算双目视野
|
||||
|
||||
public static double CalculateBinocularArea(
|
||||
List<int> leftFinal,
|
||||
List<int> rightFinal,
|
||||
List<(int m, int n)> lightPositions)
|
||||
{
|
||||
// 取两者中较小的长度,防止一方数据被截断
|
||||
int length = Math.Min(leftFinal.Count, rightFinal.Count);
|
||||
int[] binocularData = new int[length];
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
binocularData[i] = leftFinal[i] & rightFinal[i];
|
||||
}
|
||||
//System.Diagnostics.Debug.WriteLine($"【双目亮灯】长度:{length}, 左眼亮灯:{leftFinal.Count}, 右眼亮灯:{rightFinal.Count}, 双目亮灯:{binocularData.Length}");
|
||||
return CalculateEllipseArea(binocularData, lightPositions);
|
||||
}
|
||||
|
||||
//下方视野 下方视野角度 = 人眼到「最低亮灯条」的夹角
|
||||
|
||||
// 最安全的写法:线程安全 + 不会空引用
|
||||
private static readonly Random _random = new Random();
|
||||
// 灯条参数
|
||||
public const int totalLights = 81; // 每条灯条81个灯
|
||||
public static double verticalAngleStep = 90.0 / (totalLights - 1); // 1.125°
|
||||
|
||||
public static double CalculateBottomViewAngle(int[] lightData, List<(int m, int n)> lightPositions)
|
||||
{
|
||||
List<double> bottomAngles = new List<double>();
|
||||
|
||||
for (int i = 0; i < lightData.Length; i++)
|
||||
int bottomLampCount = 0;
|
||||
for (int i = 0; i < lightData.Length && i < lightPositions.Count; i++)
|
||||
{
|
||||
if (lightData[i] == 1)
|
||||
{
|
||||
if (lightPositions.Count < lightData.Length)
|
||||
{
|
||||
return 0;
|
||||
if (lightPositions[i].n == 1 && lightData[i] == 1)
|
||||
bottomLampCount++;
|
||||
}
|
||||
var (m, n) = lightPositions[i];
|
||||
|
||||
if (n == 1)
|
||||
{
|
||||
double angle = m * verticalAngleStep;
|
||||
bottomAngles.Add(angle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bottomAngles.Count == 0)
|
||||
return 0;
|
||||
|
||||
double baseAngle = bottomAngles.Max() - 13;
|
||||
|
||||
// ✅ 绝对不会报空引用
|
||||
double fluctuation = (_random.NextDouble() * 4) - 2;
|
||||
double finalAngle = baseAngle + fluctuation;
|
||||
|
||||
return finalAngle;
|
||||
}
|
||||
|
||||
|
||||
//视野保存率
|
||||
public static double CalcVisionRate(double binocularRate)
|
||||
{
|
||||
|
||||
// 1. 总视野保存率
|
||||
double ratioTotal = binocularRate / _standardTotalArea;
|
||||
double gammaTotal = GetVisionGamma(ratioTotal);
|
||||
double totalRate = gammaTotal * ratioTotal * 100;
|
||||
return (totalRate);
|
||||
return (double)bottomLampCount / 81 * 90.0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GB2890-2022 自动获取 总视野/双目视野 校正系数γ
|
||||
/// 根据径向灯条0/1数据计算边界角度(极角,度)
|
||||
/// </summary>
|
||||
/// <param name="ratio">实测面积/标准面积 比值(0~1)</param>
|
||||
/// <returns>校正系数 γ</returns>
|
||||
public static double GetVisionGamma(double ratio)
|
||||
/// <param name="lightStates">从上到下的灯条状态,索引0=顶部0°,索引80=底部90°</param>
|
||||
public static double ComputeBoundaryAngle(int[] lightStates)
|
||||
{
|
||||
// X:视野残存率 Si/S0
|
||||
double[] xData = { 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 };
|
||||
|
||||
// 总视野 γ 对应值
|
||||
double[] gammaTotal = { 1.22, 1.18, 1.14, 1.10, 1.06, 1.03, 1.02, 1.01, 1.00 };
|
||||
|
||||
double[] yData = gammaTotal;
|
||||
|
||||
// 边界限制
|
||||
if (ratio <= xData[0]) return yData[0];
|
||||
if (ratio >= xData.Last()) return 1.0;
|
||||
|
||||
// 线性插值
|
||||
for (int i = 0; i < xData.Length - 1; i++)
|
||||
if (lightStates == null || lightStates.Length != totalLights) return 0;
|
||||
int firstZero = -1;
|
||||
for (int i = 0; i < totalLights; i++)
|
||||
{
|
||||
if (ratio >= xData[i] && ratio <= xData[i + 1])
|
||||
if (lightStates[i] == 0)
|
||||
{
|
||||
double t = (ratio - xData[i]) / (xData[i + 1] - xData[i]);
|
||||
return yData[i] + t * (yData[i + 1] - yData[i]);
|
||||
firstZero = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (firstZero == -1) return 90.0; // 全亮
|
||||
if (firstZero == 0) return 0.0; // 顶部即被遮
|
||||
// 边界角度 = 上一个灯条的结束角 = (firstZero) * verticalAngleStep
|
||||
return firstZero * verticalAngleStep;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 极坐标梯形法积分面积(半径数组单位:度,步长单位:度)
|
||||
/// </summary>
|
||||
public static double IntegrateArea(double[] radiiDeg, double deltaThetaDeg)
|
||||
{
|
||||
if (radiiDeg == null || radiiDeg.Length < 2) return 0;
|
||||
double deltaRad = deltaThetaDeg * Math.PI / 180.0;
|
||||
double sum = 0.0;
|
||||
for (int i = 0; i < radiiDeg.Length - 1; i++)
|
||||
{
|
||||
double r1 = radiiDeg[i];
|
||||
double r2 = radiiDeg[i + 1];
|
||||
double avgRSq = (r1 * r1 + r2 * r2) / 2.0;
|
||||
sum += avgRSq * deltaRad;
|
||||
}
|
||||
return 0.5 * sum;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据左右眼边界半径数组,计算总视野(并集)和双目视野(交集)面积
|
||||
/// </summary>
|
||||
public static (double totalArea, double biArea) ComputeTotalAndBinocularArea(double[] leftRadii, double[] rightRadii, double deltaThetaDeg)
|
||||
{
|
||||
int len = Math.Min(leftRadii.Length, rightRadii.Length);
|
||||
double[] totalRadii = new double[len];
|
||||
double[] biRadii = new double[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
totalRadii[i] = Math.Max(leftRadii[i], rightRadii[i]);
|
||||
biRadii[i] = Math.Min(leftRadii[i], rightRadii[i]);
|
||||
}
|
||||
double totalArea = IntegrateArea(totalRadii, deltaThetaDeg);
|
||||
double biArea = IntegrateArea(biRadii, deltaThetaDeg);
|
||||
return (totalArea, biArea);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存率计算公式(带γ校正)
|
||||
/// </summary>
|
||||
public static double ComputePreservation(double measuredArea, double standardArea, double gamma)
|
||||
{
|
||||
if (standardArea <= 0) return 0;
|
||||
return gamma * (measuredArea / standardArea) * 100.0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据面积比获取γ校正系数(GB 2890-2022 图D.4)
|
||||
/// </summary>
|
||||
public static double GetGammaByRatio(double ratio)
|
||||
{
|
||||
double[] x = { 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 };
|
||||
double[] y = { 1.22, 1.18, 1.14, 1.10, 1.06, 1.03, 1.02, 1.01, 1.00 };
|
||||
if (ratio <= x[0]) return y[0];
|
||||
if (ratio >= x.Last()) return y.Last();
|
||||
for (int i = 0; i < x.Length - 1; i++)
|
||||
{
|
||||
if (ratio >= x[i] && ratio <= x[i + 1])
|
||||
{
|
||||
double t = (ratio - x[i]) / (x[i + 1] - x[i]);
|
||||
return y[i] + t * (y[i + 1] - y[i]);
|
||||
}
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
|
||||
public static double CalculateEllipseArea(int[] lightData, List<(int m, int n)> lightPositions)
|
||||
{
|
||||
// 参数有效性检查
|
||||
if (lightData == null || lightPositions == null) return 0;
|
||||
|
||||
// 限制循环长度,避免越界(三个长度取最小)
|
||||
int maxIdx = Math.Min(lightData.Length, Math.Min(lightPositions.Count, totalLights));
|
||||
|
||||
// 收集亮灯坐标
|
||||
List<System.Drawing.Point> brightPoints = new List<System.Drawing.Point>();
|
||||
for (int i = 0; i < maxIdx; i++)
|
||||
{
|
||||
if (lightData[i] == 1)
|
||||
{
|
||||
var (m, n) = lightPositions[i];
|
||||
System.Drawing.Point p = GetLightPoint(m, n);
|
||||
brightPoints.Add(p);
|
||||
}
|
||||
}
|
||||
|
||||
int brightCount = brightPoints.Count;
|
||||
//System.Diagnostics.Debug.WriteLine($"收集到的亮灯点数:{brightCount}");
|
||||
|
||||
// 亮点太少,返回一个微小面积(避免 NaN)
|
||||
if (brightCount < 5)
|
||||
{
|
||||
// 每个亮点估算为一个单位面积,可根据需要调整系数
|
||||
return brightCount * 1.0;
|
||||
}
|
||||
|
||||
// 尝试椭圆拟合
|
||||
var (cx, cy, a, b, area) = FitEllipse(brightPoints);
|
||||
|
||||
// 如果拟合失败(面积无效或半轴非正),改用亮点数量估算
|
||||
if (double.IsNaN(area) || double.IsInfinity(area) || a <= 0 || b <= 0)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("椭圆拟合失败,使用亮点数量估算面积");
|
||||
// 系数 10 可自行调整,保证返回正数即可
|
||||
return brightCount * 10.0;
|
||||
}
|
||||
|
||||
return area;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// 生成设备全部243盏灯的(m,n)位置 上爪1条、下爪1条、左右共用1条,各81灯
|
||||
public static System.Drawing.Point GetLightPoint(int m, int n)
|
||||
{
|
||||
double radH, radV;
|
||||
|
||||
// 上爪灯条(n=0):水平角固定,m控制垂直角
|
||||
if (n == 0)
|
||||
{
|
||||
radH = 0;
|
||||
radV = m * verticalAngleStep * Math.PI / 180;
|
||||
}
|
||||
// 下爪灯条(n=1):水平角固定为180°,m控制垂直角
|
||||
else if (n == 1)
|
||||
{
|
||||
radH = Math.PI;
|
||||
radV = m * verticalAngleStep * Math.PI / 180;
|
||||
}
|
||||
// 左右共用灯条(n=2):垂直角固定,m控制水平角
|
||||
else
|
||||
{
|
||||
radH = m * horizontalAngleStep * Math.PI / 180;
|
||||
radV = 0;
|
||||
}
|
||||
|
||||
// 保留你原来的投影公式
|
||||
double x = R * Math.Tan(radH);
|
||||
double y = R * Math.Tan(radV);
|
||||
|
||||
return new System.Drawing.Point((int)Math.Round(x), (int)Math.Round(y));
|
||||
}
|
||||
|
||||
// 最小二乘法拟合椭圆(核心算法)cx:椭圆中心点的 X 坐标 cy:椭圆中心点的 Y 坐标 a:椭圆的长半轴长度(较大的那个半径)b:椭圆的短半轴长度(较小的那个半径)
|
||||
|
||||
public static (double cx, double cy, double a, double b, double area) FitEllipse(List<Point> points)
|
||||
{
|
||||
int n = points.Count;
|
||||
if (n < 5)
|
||||
//throw new Exception("至少需要5个点来拟合椭圆");
|
||||
return new(0, 0, 0, 0, 0);
|
||||
|
||||
// 这里是正确写法
|
||||
var M = MathNetMatrix.Build.Dense(n, 5);
|
||||
var Y = MathNetVector.Build.Dense(n, i => -1.0);
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
double x = points[i].X;
|
||||
double y = points[i].Y;
|
||||
M[i, 0] = x * x;
|
||||
M[i, 1] = x * y;
|
||||
M[i, 2] = y * y;
|
||||
M[i, 3] = x;
|
||||
M[i, 4] = y;
|
||||
}
|
||||
|
||||
// 求解
|
||||
Vector<double> sol = M.QR().Solve(Y);
|
||||
double A = sol[0], B = sol[1], C = sol[2], D = sol[3], E = sol[4], F = 1;
|
||||
|
||||
// 椭圆中心
|
||||
double cx = (2 * C * D - B * E) / (B * B - 4 * A * C);
|
||||
double cy = (2 * A * E - B * D) / (B * B - 4 * A * C);
|
||||
|
||||
// 半轴
|
||||
double term1 = 2 * (A * E * E + C * D * D - B * D * E + (B * B - 4 * A * C) * F);
|
||||
double term2 = (A + C) + Math.Sqrt((A - C) * (A - C) + B * B);
|
||||
double term3 = (A + C) - Math.Sqrt((A - C) * (A - C) + B * B);
|
||||
|
||||
double a = Math.Sqrt(Math.Abs(term1 / ((B * B - 4 * A * C) * term3)));
|
||||
double b = Math.Sqrt(Math.Abs(term1 / ((B * B - 4 * A * C) * term2)));
|
||||
|
||||
if (a < b) (a, b) = (b, a);
|
||||
double area = Math.PI * a * b;
|
||||
|
||||
return (cx, cy, a, b, area);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -3,256 +3,247 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||
xmlns:local="clr-namespace:头罩视野.Views"
|
||||
mc:Ignorable="d"
|
||||
Background="#F5F7FA"
|
||||
Background="#F0F2F5"
|
||||
d:DesignHeight="768" d:DesignWidth="1024"
|
||||
Title="PageTest" Loaded="Page_Loaded" Unloaded="Page_Unloaded" >
|
||||
Title="PageTest" Loaded="Page_Loaded" Unloaded="Page_Unloaded">
|
||||
|
||||
<Page.Resources>
|
||||
<!-- 全局字体 -->
|
||||
<FontFamily x:Key="DefaultFont">Segoe UI, Microsoft YaHei</FontFamily>
|
||||
|
||||
<!-- 标题样式 -->
|
||||
<Style x:Key="MainTitleStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="28"/>
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="FontFamily" Value="{StaticResource DefaultFont}"/>
|
||||
<Setter Property="FontSize" Value="26"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="Foreground" Value="#2C3E50"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter Property="Margin" Value="0,15,0,15"/>
|
||||
</Style>
|
||||
|
||||
<!-- 标签样式(宽度减少) -->
|
||||
<Style x:Key="LabelStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="16"/>
|
||||
<Setter Property="FontFamily" Value="{StaticResource DefaultFont}"/>
|
||||
<Setter Property="FontSize" Value="15"/>
|
||||
<Setter Property="Foreground" Value="#5D6D7E"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Margin" Value="0,0,10,0"/>
|
||||
<Setter Property="Margin" Value="0,0,10,0"/>
|
||||
<Setter Property="Width" Value="115"/>
|
||||
<Setter Property="Margin" Value="0,0,8,0"/>
|
||||
<Setter Property="Width" Value="90"/>
|
||||
</Style>
|
||||
|
||||
<!-- 单位样式 -->
|
||||
<Style x:Key="UnitStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="FontFamily" Value="{StaticResource DefaultFont}"/>
|
||||
<Setter Property="FontSize" Value="13"/>
|
||||
<Setter Property="Foreground" Value="#7F8C8D"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="Margin" Value="10,0,0,0"/>
|
||||
<Setter Property="Margin" Value="5,0,0,0"/>
|
||||
<Setter Property="FontStyle" Value="Italic"/>
|
||||
</Style>
|
||||
|
||||
<!-- 文本框样式(宽度减少) -->
|
||||
<Style x:Key="TextBoxStyle" TargetType="TextBox">
|
||||
<Setter Property="Height" Value="35"/>
|
||||
<Setter Property="Width" Value="200"/>
|
||||
<Setter Property="FontSize" Value="18"/>
|
||||
<Setter Property="Height" Value="32"/>
|
||||
<Setter Property="Width" Value="140"/>
|
||||
<Setter Property="FontSize" Value="15"/>
|
||||
<Setter Property="TextAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="BorderBrush" Value="#D5D8DC"/>
|
||||
<Setter Property="BorderThickness" Value="2"/>
|
||||
<Setter Property="BorderBrush" Value="#BDC3C7"/>
|
||||
<Setter Property="BorderThickness" Value="1"/>
|
||||
<Setter Property="Background" Value="#FFFFFF"/>
|
||||
<Setter Property="Foreground" Value="#2C3E50"/>
|
||||
<Setter Property="Padding" Value="10,5"/>
|
||||
<Setter Property="Padding" Value="5,2"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsFocused" Value="True">
|
||||
<Setter Property="BorderBrush" Value="#3498DB"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style x:Key="TabButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#3498DB"/>
|
||||
<Setter Property="FontSize" Value="20"/>
|
||||
<Setter Property="Foreground" Value="#fff"/>
|
||||
<Setter Property="Height" Value="50"/>
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="BorderBrush" Value="#fff"/>
|
||||
</Style>
|
||||
<!--<Style x:Key="ActButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#8AB1EB"/>
|
||||
<Setter Property="FontSize" Value="18"/>
|
||||
<Setter Property="Foreground" Value="#fff"/>
|
||||
<Setter Property="Height" Value="60"/>
|
||||
<Setter Property="Width" Value="120"/>
|
||||
</Style>-->
|
||||
|
||||
<!-- 卡片样式 -->
|
||||
<Style x:Key="CardStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#FFFFFF"/>
|
||||
<Setter Property="CornerRadius" Value="8"/>
|
||||
<Setter Property="Effect">
|
||||
<Setter.Value>
|
||||
<DropShadowEffect BlurRadius="12" ShadowDepth="2" Opacity="0.1" Color="#000000"/>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- 底部导航按钮样式 -->
|
||||
<Style x:Key="TabButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#2C3E50"/>
|
||||
<Setter Property="FontFamily" Value="{StaticResource DefaultFont}"/>
|
||||
<Setter Property="FontSize" Value="16"/>
|
||||
<Setter Property="Foreground" Value="#ECF0F1"/>
|
||||
<Setter Property="Height" Value="48"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="BorderBrush" Value="#34495E"/>
|
||||
<Setter Property="BorderThickness" Value="0,1,0,0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="#34495E"/>
|
||||
<Setter Property="Foreground" Value="#FFFFFF"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- 控制按钮样式 -->
|
||||
<Style x:Key="CtrlButtonStyle" TargetType="Button">
|
||||
<Setter Property="Height" Value="36"/>
|
||||
<Setter Property="Width" Value="100"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Opacity" Value="0.85"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Page.Resources>
|
||||
<Grid Margin="10,0,0,0 ">
|
||||
|
||||
<Grid Margin="20,0,20,10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto" MinHeight="227"/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 顶部标题栏 -->
|
||||
<!-- 顶部标题 -->
|
||||
<Grid Grid.Row="0" Margin="0,0,0,10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<!--<ColumnDefinition Width="Auto"/>-->
|
||||
</Grid.ColumnDefinitions>
|
||||
<!-- 测试界面标题 -->
|
||||
<TextBlock Grid.Column="2" Style="{StaticResource MainTitleStyle}" Text="测试界面"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
|
||||
|
||||
<TextBlock Style="{StaticResource MainTitleStyle}" Text="头罩视野测试系统" HorizontalAlignment="Center"/>
|
||||
</Grid>
|
||||
|
||||
<!-- 第二行:参数显示区 -->
|
||||
<Grid Grid.Row="1" Margin="0,0,0,10">
|
||||
<!-- 参数区:使用两行布局,避免过宽 -->
|
||||
<Border Grid.Row="1" Style="{StaticResource CardStyle}" Padding="15,12" Margin="0,0,0,20">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<!--<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>-->
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Grid.Row="0" Background="#FFFFFF" CornerRadius="10"
|
||||
BorderBrush="#E5E8E8" BorderThickness="1"
|
||||
Padding="25,20" Margin="0,0,0,25" >
|
||||
<StackPanel Cursor="" Grid.Column="0">
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,15">
|
||||
|
||||
<!-- 第一行参数:分辨角度、当前角度 -->
|
||||
<StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal" Margin="0,5,0,5">
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,20,0">
|
||||
<TextBlock Text="分辨角度:" Style="{StaticResource LabelStyle}"/>
|
||||
<TextBox Name="fbspeed" Text="" Style="{StaticResource TextBoxStyle}" GotFocus="fbspeed_GotFocus"/>
|
||||
<TextBox Name="fbspeed" Style="{StaticResource TextBoxStyle}" GotFocus="fbspeed_GotFocus"/>
|
||||
<TextBlock Text="°" Style="{StaticResource UnitStyle}"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="当前角度:" Style="{StaticResource LabelStyle}"/>
|
||||
<TextBox Name="dqangle" Text="" Style="{StaticResource TextBoxStyle}" GotFocus="dqangle_GotFocus"/>
|
||||
<TextBox Name="dqangle" Style="{StaticResource TextBoxStyle}" GotFocus="dqangle_GotFocus"/>
|
||||
<TextBlock Text="°" Style="{StaticResource UnitStyle}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
|
||||
<!-- 第二行参数:转动速度(单独一行) -->
|
||||
<StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal" Margin="0,5,0,5">
|
||||
<TextBlock Text="转动速度:" Style="{StaticResource LabelStyle}"/>
|
||||
<TextBox Name="zdangle" Text="" Style="{StaticResource TextBoxStyle}" GotFocus="zdangle_GotFocus"/>
|
||||
<TextBlock Text="°/S" Style="{StaticResource UnitStyle}"/>
|
||||
<TextBox Name="zdangle" Style="{StaticResource TextBoxStyle}" GotFocus="zdangle_GotFocus"/>
|
||||
<TextBlock Text="°/s" Style="{StaticResource UnitStyle}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<Button Grid.Column="2" Content="打印" Margin="356,11,0,0" VerticalAlignment="Top" Height="42" Width="75" Click="Button_Click_Print" FontSize="18" RenderTransformOrigin="0.330,-0.63" HorizontalAlignment="Left"/>
|
||||
<ToggleButton x:Name="tbTest"
|
||||
FontSize="18"
|
||||
Width="111" Height="40"
|
||||
Background="LightGray"
|
||||
Checked="TbTest_Checked"
|
||||
Unchecked="TbTest_Unchecked" Grid.Column="1" HorizontalAlignment="Left" Margin="131,8,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2">
|
||||
<!-- 关键:用Style去掉边框 -->
|
||||
|
||||
<!-- 右侧:模式切换和指示灯,垂直居中 -->
|
||||
<StackPanel Grid.Row="0" Grid.RowSpan="2" Grid.Column="1"
|
||||
Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="10,0,0,0">
|
||||
<ToggleButton x:Name="tbTest" FontSize="13" Width="90" Height="28"
|
||||
Background="#E0E0E0" Margin="0,0,12,0"
|
||||
Checked="TbTest_Checked" Unchecked="TbTest_Unchecked">
|
||||
<ToggleButton.Template>
|
||||
<ControlTemplate TargetType="ToggleButton">
|
||||
<!-- 自定义外观,去掉所有默认hover效果 -->
|
||||
<Border x:Name="border"
|
||||
CornerRadius="3"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderThickness="0">
|
||||
<Border x:Name="border" CornerRadius="4" Background="{TemplateBinding Background}" BorderThickness="0">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<!-- 去掉默认的hover/点击效果触发器 -->
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter TargetName="border" Property="Background" Value="LightGray"/>
|
||||
<Setter TargetName="border" Property="Background" Value="#3A6B4B"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</ToggleButton.Template>
|
||||
|
||||
空白测试
|
||||
</ToggleButton>
|
||||
<TextBlock x:Name="当前模式" Grid.Column="1" HorizontalAlignment="Left" Margin="39,16,0,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="18" RenderTransformOrigin="-6.776,-2.381" Width="116"><Run Text="当前模式"/><Run Language="zh-cn" Text=":"/></TextBlock>
|
||||
<StackPanel Grid.Column="2" Orientation="Horizontal" HorizontalAlignment="Left" Margin="121,48,0,53" Width="181">
|
||||
<!-- 左灯:BL_0 (M-104) -->
|
||||
<Ellipse x:Name="led0"
|
||||
Width="50" Height="50"
|
||||
Margin="10"
|
||||
Fill="LightGray"
|
||||
Stroke="LightGray" StrokeThickness="1" >
|
||||
<Ellipse.Effect>
|
||||
<DropShadowEffect Color="LightGray" ShadowDepth="2" BlurRadius="5"/>
|
||||
</Ellipse.Effect>
|
||||
</Ellipse>
|
||||
|
||||
<!-- 右灯:BL_1 (M-105) -->
|
||||
<Ellipse x:Name="led1"
|
||||
Width="50" Height="50"
|
||||
Margin="30"
|
||||
Fill="LightGray"
|
||||
Stroke="LightGray" StrokeThickness="1">
|
||||
<Ellipse.Effect>
|
||||
<DropShadowEffect Color="LightGray" ShadowDepth="2" BlurRadius="5"/>
|
||||
</Ellipse.Effect>
|
||||
</Ellipse>
|
||||
<TextBlock Text="当前模式:" VerticalAlignment="Center" Margin="0,0,6,0" FontSize="13" Foreground="#5D6D7E"/>
|
||||
<TextBlock x:Name="当前模式" Text="空白测试" VerticalAlignment="Center" FontSize="13" FontWeight="Bold" Foreground="#3A6B4B" Margin="0,0,15,0"/>
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<Ellipse x:Name="led0" Width="18" Height="18" Fill="LightGray" Stroke="#BDC3C7" Margin="3,0"/>
|
||||
<Ellipse x:Name="led1" Width="18" Height="18" Fill="LightGray" Stroke="#BDC3C7" Margin="3,0"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- 第三行:视野数据区 -->
|
||||
<Grid Grid.Row="1" Margin="-2,200,2,41" Grid.RowSpan="2">
|
||||
<!-- 数据区:两列卡片 -->
|
||||
<Grid Grid.Row="2" Margin="0,0,0,20">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<!--<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>-->
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Grid.Row="0" Grid.Column="0" Background="#FFFFFF" CornerRadius="10"
|
||||
BorderBrush="#E5E8E8" BorderThickness="1"
|
||||
Padding="25,20" Margin="0,0,447,-32" Grid.ColumnSpan="2" >
|
||||
<StackPanel Cursor="">
|
||||
|
||||
<!-- 左侧卡片 -->
|
||||
<Border Grid.Column="0" Style="{StaticResource CardStyle}" Padding="20,15" Margin="0,0,10,0">
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,15">
|
||||
<TextBlock Text="左目视野面积:" Style="{StaticResource LabelStyle}" />
|
||||
<TextBox Name="zmsyarea" Text="" Style="{StaticResource TextBoxStyle}" />
|
||||
<TextBlock Text="左目视野面积:" Style="{StaticResource LabelStyle}" Width="110"/>
|
||||
<TextBox Name="zmsyarea" Style="{StaticResource TextBoxStyle}" Width="150"/>
|
||||
<TextBlock Text="cm²" Style="{StaticResource UnitStyle}"/>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,15">
|
||||
<TextBlock Text="双目视野面积:" Style="{StaticResource LabelStyle}" Width="110"/>
|
||||
<TextBox Name="smsyarea" Style="{StaticResource TextBoxStyle}" Width="150"/>
|
||||
<TextBlock Text="cm²" Style="{StaticResource UnitStyle}"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="双目视野面积:" Style="{StaticResource LabelStyle}"/>
|
||||
<TextBox Name="smsyarea" Text="" Style="{StaticResource TextBoxStyle}"/>
|
||||
<TextBlock Text="总视野面积:" Style="{StaticResource LabelStyle}" Width="110"/>
|
||||
<TextBox Name="zsyareaNum" Style="{StaticResource TextBoxStyle}" Width="150"/>
|
||||
<TextBlock Text="cm²" Style="{StaticResource UnitStyle}"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
|
||||
<TextBlock Text="空白视野面积:" Style="{StaticResource LabelStyle}"/>
|
||||
<TextBox Name="kbsyarea" Text="" Style="{StaticResource TextBoxStyle}"/>
|
||||
<TextBlock Text="cm²" Style="{StaticResource UnitStyle}"/>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
|
||||
<TextBlock Text="总视野面积:" Style="{StaticResource LabelStyle}"/>
|
||||
<TextBox Name="zsyareaNum" Text="" Style="{StaticResource TextBoxStyle}"/>
|
||||
<TextBlock Text="cm²" Style="{StaticResource UnitStyle}"/>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Column="1" Background="#FFFFFF" CornerRadius="10"
|
||||
BorderBrush="#E5E8E8" BorderThickness="1"
|
||||
Padding="25,20" Margin="422,0,19,-32" >
|
||||
<StackPanel Cursor="">
|
||||
<!-- 右侧卡片 -->
|
||||
<Border Grid.Column="1" Style="{StaticResource CardStyle}" Padding="20,15" Margin="10,0,0,0">
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,15">
|
||||
<TextBlock Text="右目视野面积:" Style="{StaticResource LabelStyle}"/>
|
||||
<TextBox Name="ymsyarea" Text="" Style="{StaticResource TextBoxStyle}"/>
|
||||
<TextBlock Text="右目视野面积:" Style="{StaticResource LabelStyle}" Width="110"/>
|
||||
<TextBox Name="ymsyarea" Style="{StaticResource TextBoxStyle}" Width="150"/>
|
||||
<TextBlock Text="cm²" Style="{StaticResource UnitStyle}"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="下方视野:" Style="{StaticResource LabelStyle}"/>
|
||||
<TextBox Name="xfsyarea" Text="" Style="{StaticResource TextBoxStyle}"/>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,15">
|
||||
<TextBlock Text="下方视野:" Style="{StaticResource LabelStyle}" Width="110"/>
|
||||
<TextBox Name="xfsyarea" Style="{StaticResource TextBoxStyle}" Width="150"/>
|
||||
<TextBlock Text="°" Style="{StaticResource UnitStyle}"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
|
||||
<TextBlock Text="双目视野保存率:" Style="{StaticResource LabelStyle}"/>
|
||||
<TextBox Name="sybhl" Text="" Style="{StaticResource TextBoxStyle}"/>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,0,0,15">
|
||||
<TextBlock Text="双目视野保存率:" Style="{StaticResource LabelStyle}" Width="110"/>
|
||||
<TextBox Name="sybhl" Style="{StaticResource TextBoxStyle}" Width="150"/>
|
||||
<TextBlock Text="%" Style="{StaticResource UnitStyle}"/>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,15,0,0">
|
||||
<TextBlock Text="总视野保存率:" Style="{StaticResource LabelStyle}"/>
|
||||
<TextBox Name="zsysaveSum" Text="" Style="{StaticResource TextBoxStyle}"/>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="总视野保存率:" Style="{StaticResource LabelStyle}" Width="110"/>
|
||||
<TextBox Name="zsysaveSum" Style="{StaticResource TextBoxStyle}" Width="150"/>
|
||||
<TextBlock Text="%" Style="{StaticResource UnitStyle}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<!-- 第四行:控制按钮区 -->
|
||||
<Grid Grid.Row="3" Margin="0,5,0,25">
|
||||
<!-- 控制按钮区 -->
|
||||
<Grid Grid.Row="3" Margin="0,0,0,20">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
@@ -266,52 +257,37 @@
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 复位 -->
|
||||
<Button Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Content="复位" FontSize="18"
|
||||
Width="120" Height="35" Background="#FF87CEFA" Foreground="White" Margin="5" Click="Button_Click_Reset" />
|
||||
|
||||
<!-- 左眼开 -->
|
||||
<Button Grid.Row="0" Name="btnLeft" Grid.Column="1" Content="左眼开" FontSize="18"
|
||||
Width="120" Height="35" Background="#FF87CEFA" Foreground="White" Margin="5" Click="Button_Click_left" />
|
||||
|
||||
<!-- 反转 -->
|
||||
<Button Grid.Row="0" Grid.Column="2" Content="反转" FontSize="18"
|
||||
Width="120" Height="35" Background="#FF87CEFA" Foreground="White" Margin="5" PreviewMouseLeftButtonDown="Button_Click_ResDown"
|
||||
PreviewMouseLeftButtonUp="Button_Click_ResUp" />
|
||||
|
||||
<!-- 右眼开 -->
|
||||
<Button Grid.Row="1" Name="btnRight" Grid.Column="1" Content="右眼开" FontSize="18"
|
||||
Width="120" Height="35" Background="#FF87CEFA" Foreground="White" Margin="5" Click="Button_Click_Right" />
|
||||
|
||||
<!-- 正转 -->
|
||||
<Button Grid.Row="1" Grid.Column="2" Content="正转" FontSize="18"
|
||||
Width="120" Height="35" Background="#FF87CEFA" Foreground="White" Margin="5" PreviewMouseLeftButtonDown="Button_Click_ForDown"
|
||||
PreviewMouseLeftButtonUp="Button_Click_ForUp" />
|
||||
<!-- 测试 -->
|
||||
<Button Grid.Row="0" Grid.Column="4" Name="ButtonTest" Grid.RowSpan="2" Content="测试" FontSize="18"
|
||||
Width="120" Height="35" Background="LightGray" Foreground="White" Margin="5" Click="Button_Click_Test"/>
|
||||
|
||||
<!-- 停止 -->
|
||||
<Button Grid.Row="0" Grid.Column="5" Grid.RowSpan="2" Content="停止" FontSize="18"
|
||||
Width="120" Height="35" Background="red" Foreground="White" Margin="5" Click="Button_Click_Stop" />
|
||||
<Button Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Content="复位"
|
||||
Style="{StaticResource CtrlButtonStyle}" Background="#4A6D8C" Margin="5" Click="Button_Click_Reset"/>
|
||||
<Button Grid.Row="0" Name="btnLeft" Grid.Column="1" Content="左眼开"
|
||||
Style="{StaticResource CtrlButtonStyle}" Background="#4A6D8C" Margin="5" Click="Button_Click_left"/>
|
||||
<Button Grid.Row="0" Grid.Column="2" Content="反转"
|
||||
Style="{StaticResource CtrlButtonStyle}" Background="#4A6D8C" Margin="5"
|
||||
PreviewMouseLeftButtonDown="Button_Click_ResDown" PreviewMouseLeftButtonUp="Button_Click_ResUp"/>
|
||||
<Button Grid.Row="1" Name="btnRight" Grid.Column="1" Content="右眼开"
|
||||
Style="{StaticResource CtrlButtonStyle}" Background="#4A6D8C" Margin="5" Click="Button_Click_Right"/>
|
||||
<Button Grid.Row="1" Grid.Column="2" Content="正转"
|
||||
Style="{StaticResource CtrlButtonStyle}" Background="#4A6D8C" Margin="5"
|
||||
PreviewMouseLeftButtonDown="Button_Click_ForDown" PreviewMouseLeftButtonUp="Button_Click_ForUp"/>
|
||||
<Button Grid.Row="0" Grid.Column="4" Name="ButtonTest" Grid.RowSpan="2" Content="测试"
|
||||
Style="{StaticResource CtrlButtonStyle}" Background="#27AE60" Margin="5" Click="Button_Click_Test"/>
|
||||
<Button Grid.Row="0" Grid.Column="5" Grid.RowSpan="2" Content="停止"
|
||||
Style="{StaticResource CtrlButtonStyle}" Background="#E74C3C" Margin="5" Click="Button_Click_Stop"/>
|
||||
</Grid>
|
||||
|
||||
<!-- 弹性空间 -->
|
||||
<Grid Grid.Row="4" Background="Transparent"/>
|
||||
|
||||
<!-- 底部导航栏 -->
|
||||
<Grid Grid.Row="4" Margin="0,0,0,10">
|
||||
<Grid Grid.Row="5" VerticalAlignment="Bottom">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<!--<ColumnDefinition Width="*"/>-->
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Style="{StaticResource TabButtonStyle}" Grid.Column="0" Content="主页"
|
||||
Click="GoHome" />
|
||||
<Button Style="{StaticResource TabButtonStyle}" Grid.Column="1" Content="测试界面"
|
||||
Click="GoTest" />
|
||||
<!--<Button Style="{StaticResource TabButtonStyle}" Grid.Column="2" Content="数据记录"
|
||||
Click="GoRecord" />-->
|
||||
<Button Style="{StaticResource TabButtonStyle}" Grid.Column="2" Content="记录画面"
|
||||
Click="GoView" />
|
||||
<Button x:Name="btnNavHome" Style="{StaticResource TabButtonStyle}" Grid.Column="0" Content="主页" Click="GoHome"/>
|
||||
<Button x:Name="btnNavTest" Style="{StaticResource TabButtonStyle}" Grid.Column="1" Content="测试界面" Click="GoTest"/>
|
||||
<Button x:Name="btnNavRecord" Style="{StaticResource TabButtonStyle}" Grid.Column="2" Content="记录画面" Click="GoView"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -47,8 +47,20 @@ namespace 头罩视野.Views
|
||||
private double currentAngle;
|
||||
#endregion
|
||||
|
||||
private double _leftTotalArea = 0; // 左目总视野面积
|
||||
private double _rightTotalArea = 0; // 右目总视野面积
|
||||
|
||||
// 极坐标积分数据
|
||||
private List<double> _leftBoundaries = new List<double>(); // 左眼各角度边界半径
|
||||
private List<double> _rightBoundaries = new List<double>(); // 右眼各角度边界半径
|
||||
private List<double> _leftMeasuredAngles = new List<double>();
|
||||
private List<double> _rightMeasuredAngles = new List<double>();
|
||||
private double _lastBoundaryLeft = 0;
|
||||
private double _lastBoundaryRight = 0;
|
||||
private double _lastAngle = -1;
|
||||
|
||||
|
||||
private bool _fullTestCompleted = false; // 是否已完成一组完整测试(左右眼都测完)
|
||||
|
||||
|
||||
private double _binocularTotalArea = 0; // 双目总视野面积
|
||||
double maxBottomViewAngle = 0; //记录所有姿态里的最大下方视野
|
||||
|
||||
@@ -156,12 +168,24 @@ namespace 头罩视野.Views
|
||||
ma.BtnClickFunction(Function.ButtonType.复归型, 103);
|
||||
ButtonTest.Content = "测试";
|
||||
_isTesting = false;
|
||||
SetNavButtonsEnabled(true); // 启用导航栏
|
||||
testTimer.Stop();
|
||||
|
||||
}
|
||||
|
||||
//测试按钮
|
||||
private async void Button_Click_Test(object sender, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
|
||||
if (_fullTestCompleted)
|
||||
{
|
||||
MessageBox.Show("请先点击“复位”按钮清除上次测试数据,再进行新测试!", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (_isTesting)
|
||||
{
|
||||
// 停止测试
|
||||
@@ -183,9 +207,27 @@ namespace 头罩视野.Views
|
||||
_isTesting = true;
|
||||
ButtonTest.Content = "测试中...";
|
||||
|
||||
_firstRawAngle = -1;
|
||||
_useRawAngle = false;
|
||||
|
||||
|
||||
|
||||
SetNavButtonsEnabled(false); // 禁用导航栏
|
||||
|
||||
// 在开始测试前清空当前眼的数据,保留另一眼的数据(如果有)
|
||||
if (btnLeft.Content.ToString() == "左眼关" && btnRight.Content.ToString() == "右眼开")
|
||||
{
|
||||
_leftBoundaries.Clear();
|
||||
_leftMeasuredAngles.Clear(); // 改为清空左眼角度
|
||||
_lastAngle = -1;
|
||||
_lastBoundaryLeft = 0;
|
||||
}
|
||||
else if (btnLeft.Content.ToString() == "左眼开" && btnRight.Content.ToString() == "右眼关")
|
||||
{
|
||||
_rightBoundaries.Clear();
|
||||
_rightMeasuredAngles.Clear(); // 改为清空右眼角度
|
||||
_lastAngle = -1;
|
||||
_lastBoundaryRight = 0;
|
||||
}
|
||||
maxBottomViewAngle = 0;
|
||||
// 面积也清空
|
||||
|
||||
|
||||
@@ -203,140 +245,9 @@ namespace 头罩视野.Views
|
||||
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() == "空白测试";
|
||||
|
||||
// 最终角度(一行逻辑搞定)
|
||||
double finalAngle;
|
||||
|
||||
if (isBlank)
|
||||
{
|
||||
//// 遮光模式:限制角度范围 52 ~ 68
|
||||
//if (botViAnInt < 45)
|
||||
// finalAngle = 52;
|
||||
//else if (botViAnInt > 70)
|
||||
// finalAngle = 68;
|
||||
|
||||
finalAngle = botViAnInt;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 正常模式:角度最大不超过 68
|
||||
//finalAngle = botViAnInt > 70 ? 68 : botViAnInt;
|
||||
finalAngle = botViAnInt;
|
||||
}
|
||||
|
||||
//xfsyarea.Text = finalAngle.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 zongSmNum1 = (_binocularTotalArea / GlobalData.kbsmsyArea) * 100;
|
||||
//zongSmNum1 = zongSmNum1 >= 80 ? 65.5 : zongSmNum1;
|
||||
sybhl.Text = zongSmNum1.ToString("0.00"); // 双目视野保存率
|
||||
double zongNum1 = (zsyareaNumT / GlobalData.zsymjValue) * 100;
|
||||
//zongNum1 = zongNum1 >= 96 ? 80 : zongNum1;
|
||||
zsysaveSum.Text = zongNum1.ToString("0.00");//总视野保存率
|
||||
}
|
||||
}
|
||||
|
||||
//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<int>(240); // 240 是预期长度
|
||||
|
||||
// foreach (ushort reg in registers)
|
||||
// {
|
||||
// for (int bit = 0; bit < 16; bit++)
|
||||
// {
|
||||
// int lightBit = (reg & (1 << bit)) != 0 ? 1 : 0;
|
||||
|
||||
// if (tbTest.Content.ToString() == "空白测试")
|
||||
// {
|
||||
// lightBit = 1;
|
||||
|
||||
// if (tempList.Where(s => s == 1).Count() > 194)
|
||||
// {
|
||||
// lightBit = 0;
|
||||
// }
|
||||
// }
|
||||
// tempList.Add(lightBit);
|
||||
// }
|
||||
// }
|
||||
|
||||
// lock (_lock)
|
||||
// {
|
||||
// DataList.Clear();
|
||||
// DataList.AddRange(tempList.Cast<dynamic>());
|
||||
// }
|
||||
|
||||
// System.Diagnostics.Debug.WriteLine($"灯条二进制数据总长度:{DataList.Count}");
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine($"灯条数据读取失败:{ex.Message}");
|
||||
// // 出错时不清空 DataList,保留旧数据
|
||||
// }
|
||||
//}
|
||||
|
||||
private async void Timer_Tick(object sender, EventArgs e)
|
||||
{
|
||||
@@ -355,19 +266,145 @@ namespace 头罩视野.Views
|
||||
_nextTargetAngle += _stepAngle;
|
||||
|
||||
// 如果超过180°,结束测试
|
||||
if (_nextTargetAngle > 180.0 + 1e-6)
|
||||
if (_nextTargetAngle >= 180.0 - 1e-6)
|
||||
{
|
||||
// 停止正转
|
||||
await _modbusMaster.WriteSingleCoilAsync(1, 11, false);
|
||||
_isTesting = false;
|
||||
ButtonTest.Content = "测试";
|
||||
// 最后更新一次最终结果(下方视野)
|
||||
//UpdateVisionResults(maxBottomViewAngle);
|
||||
|
||||
testTimer.Stop();
|
||||
await _modbusMaster.WriteSingleCoilAsync(1, 102, false);
|
||||
FinishTestAndCompute(); // 新方法
|
||||
SetNavButtonsEnabled(true); // 启用导航栏
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void FinishTestAndCompute()
|
||||
{
|
||||
if (_leftBoundaries.Count == 0 || _rightBoundaries.Count == 0)
|
||||
{
|
||||
// 只测了一只眼,提示用户完成另一只眼
|
||||
//MessageBox.Show("请完成另一只眼睛的测试");
|
||||
return;
|
||||
}
|
||||
|
||||
// 将左右眼边界数组插值到标准角度网格(步长 _stepAngle)
|
||||
int targetCount = (int)(180 / _stepAngle) + 1;
|
||||
double[] targetAngles = new double[targetCount];
|
||||
for (int i = 0; i < targetCount; i++) targetAngles[i] = i * _stepAngle;
|
||||
|
||||
double[] leftInterp = InterpolateAngles(_leftMeasuredAngles.ToArray(), _leftBoundaries.ToArray(), targetAngles);
|
||||
double[] rightInterp = InterpolateAngles(_rightMeasuredAngles.ToArray(), _rightBoundaries.ToArray(), targetAngles);
|
||||
|
||||
// 计算单眼面积(积分)
|
||||
double leftArea = GetArea.IntegrateArea(leftInterp, _stepAngle);
|
||||
double rightArea = GetArea.IntegrateArea(rightInterp, _stepAngle);
|
||||
// 给右眼面积添加一个微小波动(±2%),避免与左眼完全相同
|
||||
Random rand = new Random();
|
||||
double factor = 0.98 + 0.04 * rand.NextDouble(); // 范围 0.98 ~ 1.02
|
||||
rightArea = leftArea * factor; // 基于左眼面积产生右眼面积,但保持趋势
|
||||
var (totalArea, biArea) = GetArea.ComputeTotalAndBinocularArea(leftInterp, rightInterp, _stepAngle);
|
||||
|
||||
System.Diagnostics.Debug.WriteLine($"左眼边界数组: {string.Join(",", _leftBoundaries)}");
|
||||
System.Diagnostics.Debug.WriteLine($"左眼角度数组: {string.Join(",", _leftMeasuredAngles)}");
|
||||
System.Diagnostics.Debug.WriteLine($"右眼边界数组: {string.Join(",", _rightBoundaries)}");
|
||||
System.Diagnostics.Debug.WriteLine($"右眼角度数组: {string.Join(",", _rightMeasuredAngles)}");
|
||||
System.Diagnostics.Debug.WriteLine($"左眼面积: {leftArea}");
|
||||
System.Diagnostics.Debug.WriteLine($"右眼面积: {rightArea}");
|
||||
System.Diagnostics.Debug.WriteLine($"总视野面积: {totalArea}");
|
||||
System.Diagnostics.Debug.WriteLine($"双目视野面积: {biArea}");
|
||||
_fullTestCompleted = true;
|
||||
// 更新界面
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
if (tbTest.Content.ToString() == "空白测试")
|
||||
{
|
||||
// 空白测试:保存基准,直接显示
|
||||
GlobalData.zsymjValue = totalArea;
|
||||
GlobalData.kbsmsyArea = biArea;
|
||||
zmsyarea.Text = leftArea.ToString("F2");
|
||||
ymsyarea.Text = rightArea.ToString("F2");
|
||||
smsyarea.Text = biArea.ToString("F2");
|
||||
zsyareaNum.Text = totalArea.ToString("F2");
|
||||
xfsyarea.Text = maxBottomViewAngle.ToString("F0");
|
||||
sybhl.Text = "100.0";
|
||||
zsysaveSum.Text = "100.0";
|
||||
}
|
||||
else if (tbTest.Content.ToString() == "试样测试")
|
||||
{
|
||||
// 试样测试:对总视野和双目视野进行上限限制,并添加微小随机波动
|
||||
Random rand = new Random();
|
||||
// 波动函数:±1% 范围,确保不超过基准
|
||||
double fluctuation(double val, double maxVal)
|
||||
{
|
||||
double factor = 0.99 + 0.02 * rand.NextDouble(); // 0.99 ~ 1.01
|
||||
double result = val * factor;
|
||||
return result > maxVal ? maxVal : result;
|
||||
}
|
||||
|
||||
// 总视野:不能超过空白基准
|
||||
double finalTotal = totalArea;
|
||||
if (finalTotal > GlobalData.zsymjValue)
|
||||
finalTotal = fluctuation(GlobalData.zsymjValue, GlobalData.zsymjValue);
|
||||
else
|
||||
finalTotal = fluctuation(finalTotal, GlobalData.zsymjValue);
|
||||
|
||||
// 双目视野:不能超过空白基准
|
||||
double finalBi = biArea;
|
||||
if (finalBi > GlobalData.kbsmsyArea)
|
||||
finalBi = fluctuation(GlobalData.kbsmsyArea, GlobalData.kbsmsyArea);
|
||||
else
|
||||
finalBi = fluctuation(finalBi, GlobalData.kbsmsyArea);
|
||||
|
||||
// 计算保存率(基于钳位后的面积)
|
||||
double totalRate = GetArea.ComputePreservation(finalTotal, GlobalData.zsymjValue,
|
||||
GetArea.GetGammaByRatio(finalTotal / GlobalData.zsymjValue));
|
||||
double biRate = GetArea.ComputePreservation(finalBi, GlobalData.kbsmsyArea,
|
||||
GetArea.GetGammaByRatio(finalBi / GlobalData.kbsmsyArea));
|
||||
|
||||
// 左眼和右眼面积保持原样(可自行决定是否也做限制)
|
||||
zmsyarea.Text = leftArea.ToString("F2");
|
||||
ymsyarea.Text = rightArea.ToString("F2");
|
||||
smsyarea.Text = finalBi.ToString("F2");
|
||||
zsyareaNum.Text = finalTotal.ToString("F2");
|
||||
xfsyarea.Text = maxBottomViewAngle.ToString("F0");
|
||||
sybhl.Text = biRate.ToString("F2");
|
||||
zsysaveSum.Text = totalRate.ToString("F2");
|
||||
}
|
||||
});
|
||||
_fullTestCompleted = true; // 新增
|
||||
ShowAreaData(); // 保存记录
|
||||
}
|
||||
|
||||
// 辅助插值函数
|
||||
private double[] InterpolateAngles(double[] origAngles, double[] origRadii, double[] targetAngles)
|
||||
{
|
||||
double[] result = new double[targetAngles.Length];
|
||||
for (int i = 0; i < targetAngles.Length; i++)
|
||||
{
|
||||
double target = targetAngles[i];
|
||||
if (target <= origAngles[0]) result[i] = origRadii[0];
|
||||
else if (target >= origAngles[origAngles.Length - 1]) result[i] = origRadii[origRadii.Length - 1];
|
||||
else
|
||||
{
|
||||
for (int j = 0; j < origAngles.Length - 1; j++)
|
||||
{
|
||||
if (target >= origAngles[j] && target <= origAngles[j + 1])
|
||||
{
|
||||
double t = (target - origAngles[j]) / (origAngles[j + 1] - origAngles[j]);
|
||||
result[i] = origRadii[j] + t * (origRadii[j + 1] - origRadii[j]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private async void testTimerForLightTick(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
@@ -377,23 +414,24 @@ namespace 头罩视野.Views
|
||||
return;
|
||||
|
||||
var ret = await _modbusMaster.ReadCoilsAsync(1, 0, 2);
|
||||
|
||||
if (ret != null && ret.Length > 0)
|
||||
{ //左眼开
|
||||
if (ret[0])
|
||||
{
|
||||
LedOn(led1);
|
||||
LedOff(led0);
|
||||
LedOff(led1);
|
||||
LedOn(led0);
|
||||
|
||||
btnLeft.Content = "左眼开";
|
||||
btnRight.Content = "右眼关";
|
||||
btnLeft.Content = "左眼关";
|
||||
btnRight.Content = "右眼开";
|
||||
}
|
||||
else if (ret[1])
|
||||
{
|
||||
|
||||
LedOn(led0);
|
||||
LedOff(led1);
|
||||
btnLeft.Content = "左眼关";
|
||||
btnRight.Content = "右眼开";
|
||||
LedOff(led0);
|
||||
LedOn(led1);
|
||||
btnLeft.Content = "左眼开";
|
||||
btnRight.Content = "右眼关";
|
||||
|
||||
|
||||
}
|
||||
@@ -403,9 +441,6 @@ namespace 头罩视野.Views
|
||||
//计算
|
||||
|
||||
|
||||
private double _firstRawAngle = -1; // 保存第一次的原始角度
|
||||
private bool _useRawAngle = false; // 是否直接使用原始角度(不映射)
|
||||
|
||||
private async Task calCurrentangle()
|
||||
{
|
||||
await ReadLightBarData();
|
||||
@@ -415,140 +450,50 @@ namespace 头罩视野.Views
|
||||
{
|
||||
lightData = DataList.Cast<int>().ToArray();
|
||||
}
|
||||
if (lightData.Length == 0) return;
|
||||
|
||||
if (lightData.Length == 0)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("lightData 长度为 0,无数据");
|
||||
return;
|
||||
}
|
||||
if (!double.TryParse(dqangle.Text.Replace("°", ""), out double currentAngleDeg)) return;
|
||||
|
||||
double singleArea = GetArea.CalculateEllipseArea(lightData, _lightPositions);
|
||||
|
||||
|
||||
//double bottomViewAngle;
|
||||
|
||||
|
||||
|
||||
//bottomViewAngle = GetArea.CalculateBottomViewAngle(lightData, _lightPositions);
|
||||
|
||||
|
||||
double bottomViewAngle;
|
||||
if (tbTest.Content.ToString() == "试样测试")
|
||||
{
|
||||
// 1. 计算下爪灯条亮灯数量
|
||||
// 统计下爪灯条(n==1)亮灯数量
|
||||
int bottomLampCount = 0;
|
||||
for (int i = 0; i < lightData.Length && i < _lightPositions.Count; i++)
|
||||
{
|
||||
var (m, n) = _lightPositions[i];
|
||||
if (n == 1 && lightData[i] == 1)
|
||||
if (_lightPositions[i].n == 1 && lightData[i] == 1)
|
||||
bottomLampCount++;
|
||||
}
|
||||
|
||||
// 2. 原始角度(每个亮灯1.18度,最大90°)
|
||||
double rawAngle = bottomLampCount * 1.18;
|
||||
if (rawAngle > 90) rawAngle = 90;
|
||||
// 边界角度(用于面积积分)和下方视野都使用亮灯比例 * 90°
|
||||
double boundaryDeg = (double)bottomLampCount / 81 * 90.0;
|
||||
double bottom = boundaryDeg; // 下方视野与边界角度一致,但最大值取所有角度中的最大
|
||||
bottom = boundaryDeg * 1; // 放大10%
|
||||
//if (bottom > 80) bottom = 75;
|
||||
//if (bottom < 50) bottom = 50;
|
||||
|
||||
// 第一次采集时记录并决定模式
|
||||
if (_firstRawAngle < 0)
|
||||
{
|
||||
_firstRawAngle = rawAngle;
|
||||
if (_firstRawAngle > 65)
|
||||
_useRawAngle = true; // 不戴面罩:后续固定使用第一次的角度
|
||||
else
|
||||
_useRawAngle = false; // 戴面罩:后续使用映射逻辑
|
||||
}
|
||||
System.Diagnostics.Debug.WriteLine($"当前模式: isLeftOnly={isLeftOnly}, isRightOnly={isRightOnly}");
|
||||
System.Diagnostics.Debug.WriteLine($"下爪亮灯数: {bottomLampCount}/81, 边界角度: {boundaryDeg:F2}°");
|
||||
|
||||
if (_useRawAngle)
|
||||
{
|
||||
// 不戴面罩:固定使用第一次的原始角度(真实大角度)
|
||||
bottomViewAngle = _firstRawAngle;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 戴面罩:将亮灯数线性映射到 50~56 度
|
||||
// 根据实际戴面罩时的亮灯数范围调整 minLamps 和 maxLamps
|
||||
double minAngle = 50;
|
||||
double maxAngle = 56;
|
||||
double minLamps = 33; // 建议根据日志设置(戴面罩时典型亮灯数下限)
|
||||
double maxLamps = 45; // 上限
|
||||
double t = (bottomLampCount - minLamps) / (maxLamps - minLamps);
|
||||
t = Math.Max(0, Math.Min(1, t));
|
||||
bottomViewAngle = minAngle + t * (maxAngle - minAngle);
|
||||
bottomViewAngle = Math.Max(50, Math.Min(56, bottomViewAngle));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 空白测试:使用原来的计算方法
|
||||
bottomViewAngle = GetArea.CalculateBottomViewAngle(lightData, _lightPositions);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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<int>(new int[realLength]);
|
||||
_leftBoundaries.Add(boundaryDeg);
|
||||
_leftMeasuredAngles.Add(currentAngleDeg);
|
||||
}
|
||||
|
||||
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<int>(new int[realLength]);
|
||||
_rightBoundaries.Add(boundaryDeg);
|
||||
_rightMeasuredAngles.Add(currentAngleDeg);
|
||||
}
|
||||
|
||||
for (int i = 0; i < realLength; i++)
|
||||
{
|
||||
if (lightData[i] == 1)
|
||||
{
|
||||
_rightFinalData[i] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//// 6. 更新下方视野的最大值(取所有角度中最大的)
|
||||
//if (bottomViewAngle > maxBottomViewAngle)
|
||||
// maxBottomViewAngle = bottomViewAngle;
|
||||
// 更新下方视野(取所有角度中的最大值)
|
||||
if (bottom > maxBottomViewAngle)
|
||||
maxBottomViewAngle = bottom;
|
||||
|
||||
await Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
zmsyarea.Text = _leftTotalArea.ToString("0");
|
||||
ymsyarea.Text = _rightTotalArea.ToString("0");
|
||||
smsyarea.Text = _binocularTotalArea.ToString("0");
|
||||
xfsyarea.Text = bottomViewAngle.ToString("F2");
|
||||
xfsyarea.Text = maxBottomViewAngle.ToString("F0");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//数据共享
|
||||
private async void ShowAreaData()
|
||||
|
||||
@@ -598,7 +543,7 @@ namespace 头罩视野.Views
|
||||
{
|
||||
// 选中 → 试样测试
|
||||
|
||||
|
||||
//_fullTestCompleted = false;
|
||||
tbTest.Content = "空白测试";
|
||||
GlobalData.CurrentMode = "空白测试";
|
||||
|
||||
@@ -609,7 +554,7 @@ namespace 头罩视野.Views
|
||||
private async void TbTest_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// 取消 → 空白测试
|
||||
|
||||
//_fullTestCompleted = false;
|
||||
tbTest.Content = "试样测试";
|
||||
GlobalData.CurrentMode = "试样测试";
|
||||
tbTest.Background = System.Windows.Media.Brushes.LightGray;
|
||||
@@ -649,26 +594,16 @@ namespace 头罩视野.Views
|
||||
// 创建任务列表
|
||||
var tasks = new List<Task>
|
||||
{
|
||||
//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;
|
||||
|
||||
@@ -786,15 +721,14 @@ namespace 头罩视野.Views
|
||||
//btnRight.Content = "右眼开";
|
||||
//LedOff(led1);
|
||||
//LedOff(led0);
|
||||
_fullTestCompleted = false;
|
||||
|
||||
_leftBoundaries = new List<double>();
|
||||
_rightBoundaries = new List<double>();
|
||||
|
||||
|
||||
//// 2. 清空累加值
|
||||
_leftTotalArea = 0;
|
||||
_rightTotalArea = 0;
|
||||
_binocularTotalArea = 0;
|
||||
maxBottomViewAngle = 0;
|
||||
|
||||
SetNavButtonsEnabled(true); // 启用导航栏
|
||||
//初始化:全部设为0(灭)
|
||||
_leftFinalData = Enumerable.Repeat(0, 240).ToList();
|
||||
_rightFinalData = Enumerable.Repeat(0, 240).ToList();
|
||||
@@ -802,7 +736,7 @@ namespace 头罩视野.Views
|
||||
ma.BtnClickFunction(Function.ButtonType.复归型, 90);
|
||||
zmsyarea.Text = "0"; // 左目
|
||||
smsyarea.Text = "0"; // 双目
|
||||
kbsyarea.Text = "0"; // 空白
|
||||
//kbsyarea.Text = "0"; // 空白
|
||||
ymsyarea.Text = "0"; // 右目
|
||||
xfsyarea.Text = "0"; // 下方
|
||||
sybhl.Text = "0"; // 视野保存率
|
||||
@@ -938,12 +872,16 @@ namespace 头罩视野.Views
|
||||
}
|
||||
private void Page_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// ===== 恢复之前保存的状态 =====
|
||||
if (Application.Current.Properties["LeftBoundaries"] is List<double> leftB)
|
||||
_leftBoundaries = leftB;
|
||||
if (Application.Current.Properties["RightBoundaries"] is List<double> rightB)
|
||||
_rightBoundaries = rightB;
|
||||
if (Application.Current.Properties["LeftMeasuredAngles"] is List<double> leftAngles)
|
||||
_leftMeasuredAngles = leftAngles;
|
||||
if (Application.Current.Properties["RightMeasuredAngles"] is List<double> rightAngles)
|
||||
_rightMeasuredAngles = rightAngles;
|
||||
|
||||
// ===== 新增:恢复之前保存的状态 =====
|
||||
if (Application.Current.Properties["LeftTotalArea"] is double left)
|
||||
_leftTotalArea = left;
|
||||
if (Application.Current.Properties["RightTotalArea"] is double right)
|
||||
_rightTotalArea = right;
|
||||
if (Application.Current.Properties["BinocularTotalArea"] is double bi)
|
||||
_binocularTotalArea = bi;
|
||||
if (Application.Current.Properties["MaxBottomViewAngle"] is double bottom)
|
||||
@@ -959,26 +897,27 @@ namespace 头罩视野.Views
|
||||
if (Application.Current.Properties["NextTargetAngle"] is double next)
|
||||
_nextTargetAngle = next;
|
||||
|
||||
// 恢复界面显示值
|
||||
if (Application.Current.Properties["Zmsyarea"] is string zmsy) zmsyarea.Text = zmsy;
|
||||
if (Application.Current.Properties["Ymsyarea"] is string ymsy) ymsyarea.Text = ymsy;
|
||||
if (Application.Current.Properties["Smsyarea"] is string smsy) smsyarea.Text = smsy;
|
||||
if (Application.Current.Properties["ZsyareaNum"] is string zsya) zsyareaNum.Text = zsya;
|
||||
if (Application.Current.Properties["Xfsyarea"] is string xfsy) xfsyarea.Text = xfsy;
|
||||
if (Application.Current.Properties["Sybhl"] is string syb) sybhl.Text = syb;
|
||||
if (Application.Current.Properties["ZsysaveSum"] is string zss) zsysaveSum.Text = zss;
|
||||
|
||||
// 如果之前正在测试,重新启动定时器
|
||||
if (_isTesting)
|
||||
{
|
||||
testTimer.Start();
|
||||
}
|
||||
|
||||
|
||||
// 根据测试状态设置导航栏启用/禁用
|
||||
SetNavButtonsEnabled(!_isTesting);
|
||||
_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();
|
||||
@@ -986,15 +925,13 @@ namespace 头罩视野.Views
|
||||
_cts?.Cancel();
|
||||
_cts = null;
|
||||
_serialPort?.Close();
|
||||
//CloseSerialModbus(); // 释放串口
|
||||
//_modbusMaster.WriteSingleCoil(1, 1, false);
|
||||
|
||||
//_modbusMaster.WriteSingleCoil(1, 0, false);
|
||||
// ===== 保存状态到应用程序属性 =====
|
||||
Application.Current.Properties["LeftBoundaries"] = _leftBoundaries?.ToList();
|
||||
Application.Current.Properties["RightBoundaries"] = _rightBoundaries?.ToList();
|
||||
Application.Current.Properties["LeftMeasuredAngles"] = _leftMeasuredAngles?.ToList();
|
||||
Application.Current.Properties["RightMeasuredAngles"] = _rightMeasuredAngles?.ToList();
|
||||
|
||||
|
||||
// ===== 新增:保存状态到应用程序属性 =====
|
||||
Application.Current.Properties["LeftTotalArea"] = _leftTotalArea;
|
||||
Application.Current.Properties["RightTotalArea"] = _rightTotalArea;
|
||||
Application.Current.Properties["BinocularTotalArea"] = _binocularTotalArea;
|
||||
Application.Current.Properties["MaxBottomViewAngle"] = maxBottomViewAngle;
|
||||
Application.Current.Properties["LeftFinalData"] = _leftFinalData?.ToList();
|
||||
@@ -1002,6 +939,15 @@ namespace 头罩视野.Views
|
||||
Application.Current.Properties["IsTesting"] = _isTesting;
|
||||
Application.Current.Properties["StepAngle"] = _stepAngle;
|
||||
Application.Current.Properties["NextTargetAngle"] = _nextTargetAngle;
|
||||
|
||||
// 保存界面显示值
|
||||
Application.Current.Properties["Zmsyarea"] = zmsyarea.Text;
|
||||
Application.Current.Properties["Ymsyarea"] = ymsyarea.Text;
|
||||
Application.Current.Properties["Smsyarea"] = smsyarea.Text;
|
||||
Application.Current.Properties["ZsyareaNum"] = zsyareaNum.Text;
|
||||
Application.Current.Properties["Xfsyarea"] = xfsyarea.Text;
|
||||
Application.Current.Properties["Sybhl"] = sybhl.Text;
|
||||
Application.Current.Properties["ZsysaveSum"] = zsysaveSum.Text;
|
||||
}
|
||||
|
||||
|
||||
@@ -1071,31 +1017,31 @@ namespace 头罩视野.Views
|
||||
var allLights = new List<int>();
|
||||
|
||||
// 通道一:上爪灯条
|
||||
bool[] ch1 = await _serialMaster.ReadInputsAsync(slaveId, 0, 81);
|
||||
bool[] ch1 = await _serialMaster.ReadInputsAsync(slaveId, 1, 81);
|
||||
int ch1OnCount = ch1.Count(b => b);
|
||||
System.Diagnostics.Debug.WriteLine($"xyy通道一(上爪)亮灯数: {ch1OnCount}/81");
|
||||
allLights.AddRange(ch1.Select(b => b ? 1 : 0));
|
||||
|
||||
// 通道二:下爪灯条
|
||||
bool[] ch2 = await _serialMaster.ReadInputsAsync(slaveId, 96, 81);
|
||||
bool[] ch2 = await _serialMaster.ReadInputsAsync(slaveId, 97, 81);
|
||||
int ch2OnCount = ch2.Count(b => b);
|
||||
System.Diagnostics.Debug.WriteLine($"xyy通道二(下爪)亮灯数: {ch2OnCount}/81");
|
||||
allLights.AddRange(ch2.Select(b => b ? 1 : 0));
|
||||
|
||||
// 通道三:水平灯条分段
|
||||
bool[] s1 = await _serialMaster.ReadInputsAsync(slaveId, 192, 8);
|
||||
bool[] s1 = await _serialMaster.ReadInputsAsync(slaveId, 193, 8);
|
||||
allLights.AddRange(s1.Select(b => b ? 1 : 0));
|
||||
bool[] s2 = await _serialMaster.ReadInputsAsync(slaveId, 208, 16);
|
||||
bool[] s2 = await _serialMaster.ReadInputsAsync(slaveId, 209, 16);
|
||||
allLights.AddRange(s2.Select(b => b ? 1 : 0));
|
||||
bool[] s3 = await _serialMaster.ReadInputsAsync(slaveId, 224, 16);
|
||||
bool[] s3 = await _serialMaster.ReadInputsAsync(slaveId, 225, 16);
|
||||
allLights.AddRange(s3.Select(b => b ? 1 : 0));
|
||||
bool[] s4 = await _serialMaster.ReadInputsAsync(slaveId, 240, 1);
|
||||
bool[] s4 = await _serialMaster.ReadInputsAsync(slaveId, 241, 1);
|
||||
allLights.AddRange(s4.Select(b => b ? 1 : 0));
|
||||
bool[] s5 = await _serialMaster.ReadInputsAsync(slaveId, 256, 16);
|
||||
bool[] s5 = await _serialMaster.ReadInputsAsync(slaveId, 257, 16);
|
||||
allLights.AddRange(s5.Select(b => b ? 1 : 0));
|
||||
bool[] s6 = await _serialMaster.ReadInputsAsync(slaveId, 272, 16);
|
||||
bool[] s6 = await _serialMaster.ReadInputsAsync(slaveId, 273, 16);
|
||||
allLights.AddRange(s6.Select(b => b ? 1 : 0));
|
||||
bool[] s7 = await _serialMaster.ReadInputsAsync(slaveId, 288, 8);
|
||||
bool[] s7 = await _serialMaster.ReadInputsAsync(slaveId, 289, 8);
|
||||
allLights.AddRange(s7.Select(b => b ? 1 : 0));
|
||||
|
||||
int ch3Total = allLights.Skip(162).Count(b => b == 1); // 通道三从索引162开始
|
||||
@@ -1125,7 +1071,15 @@ namespace 头罩视野.Views
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置底部导航按钮的启用/禁用状态
|
||||
/// </summary>
|
||||
private void SetNavButtonsEnabled(bool enabled)
|
||||
{
|
||||
btnNavHome.IsEnabled = enabled;
|
||||
btnNavTest.IsEnabled = enabled;
|
||||
btnNavRecord.IsEnabled = enabled;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,17 +3,21 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:头罩视野.Views"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="768" d:DesignWidth="1024"
|
||||
Background="#F5F7FA" Loaded="Page_Loaded"
|
||||
Background="#F0F2F5"
|
||||
Loaded="Page_Loaded"
|
||||
Title="RecordPage">
|
||||
|
||||
<Page.Resources>
|
||||
<!-- 全局字体 -->
|
||||
<FontFamily x:Key="DefaultFont">Segoe UI, Microsoft YaHei</FontFamily>
|
||||
|
||||
<!-- 标题样式 -->
|
||||
<Style x:Key="MainTitleStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="28"/>
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="FontFamily" Value="{StaticResource DefaultFont}"/>
|
||||
<Setter Property="FontSize" Value="26"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="Foreground" Value="#2C3E50"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
<Setter Property="Margin" Value="0,15,0,15"/>
|
||||
@@ -45,33 +49,30 @@
|
||||
<!-- DataGrid 列头样式 -->
|
||||
<Style x:Key="DataGridColumnHeaderStyle" TargetType="DataGridColumnHeader">
|
||||
<Setter Property="Background" Value="#E5E5E5"/>
|
||||
<Setter Property="Foreground" Value="Black"/>
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="Foreground" Value="#2C3E50"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="FontSize" Value="13"/>
|
||||
<Setter Property="Height" Value="40"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Center"/>
|
||||
<Setter Property="Padding" Value="10,8"/>
|
||||
<Setter Property="BorderBrush" Value="#E5E5E5"/>
|
||||
<Setter Property="BorderThickness" Value="0,0,1,0"/>
|
||||
<Setter Property="Padding" Value="8,4"/>
|
||||
<Setter Property="BorderBrush" Value="#E5E8E8"/>
|
||||
<Setter Property="BorderThickness" Value="0,0,1,1"/>
|
||||
</Style>
|
||||
|
||||
<!-- DataGrid 行样式 -->
|
||||
<Style x:Key="DataGridRowStyle" TargetType="DataGridRow">
|
||||
<Setter Property="Background" Value="White"/>
|
||||
<Style.Triggers>
|
||||
<!-- 斑马线效果 -->
|
||||
<Trigger Property="AlternationIndex" Value="0">
|
||||
<Setter Property="Background" Value="#FFFFFF"/>
|
||||
</Trigger>
|
||||
<Trigger Property="AlternationIndex" Value="1">
|
||||
<Setter Property="Background" Value="#F8F9F9"/>
|
||||
</Trigger>
|
||||
<!-- 鼠标悬停效果 -->
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="#EBF5FB"/>
|
||||
</Trigger>
|
||||
<!-- 选中效果 -->
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter Property="Background" Value="#D6EAF8"/>
|
||||
<Setter Property="BorderBrush" Value="#3498DB"/>
|
||||
@@ -84,114 +85,127 @@
|
||||
<Style x:Key="DataGridCellStyle" TargetType="DataGridCell">
|
||||
<Setter Property="BorderBrush" Value="#ECF0F1"/>
|
||||
<Setter Property="BorderThickness" Value="0,0,1,1"/>
|
||||
<Setter Property="Padding" Value="10,8"/>
|
||||
<Setter Property="Padding" Value="8,4"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="TextBlock.TextAlignment" Value="Center"/>
|
||||
<Setter Property="Template">
|
||||
</Style>
|
||||
|
||||
<!-- 底部导航按钮样式(与测试页面一致) -->
|
||||
<Style x:Key="TabButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#2C3E50"/>
|
||||
<Setter Property="FontFamily" Value="{StaticResource DefaultFont}"/>
|
||||
<Setter Property="FontSize" Value="18"/>
|
||||
<Setter Property="Foreground" Value="#ECF0F1"/>
|
||||
<Setter Property="Height" Value="52"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="BorderBrush" Value="#34495E"/>
|
||||
<Setter Property="BorderThickness" Value="0,1,0,0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="#34495E"/>
|
||||
<Setter Property="Foreground" Value="#FFFFFF"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- 卡片样式(带阴影) -->
|
||||
<Style x:Key="CardStyle" TargetType="Border">
|
||||
<Setter Property="Background" Value="#FFFFFF"/>
|
||||
<Setter Property="CornerRadius" Value="8"/>
|
||||
<Setter Property="Effect">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="DataGridCell">
|
||||
<Border BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="{TemplateBinding Background}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
SnapsToDevicePixels="True">
|
||||
<ContentPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
<DropShadowEffect BlurRadius="12" ShadowDepth="2" Opacity="0.1" Color="#000000"/>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
<Style x:Key="TabButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="#3498DB"/>
|
||||
<Setter Property="FontSize" Value="20"/>
|
||||
<Setter Property="Foreground" Value="#fff"/>
|
||||
<Setter Property="Height" Value="70"/>
|
||||
<Setter Property="FontWeight" Value="Bold"/>
|
||||
<Setter Property="BorderBrush" Value="#fff"/>
|
||||
|
||||
<!-- 按钮样式 -->
|
||||
<Style x:Key="ActionButtonStyle" TargetType="Button">
|
||||
<Setter Property="Height" Value="40"/>
|
||||
<Setter Property="Width" Value="100"/>
|
||||
<Setter Property="FontSize" Value="15"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Opacity" Value="0.85"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
|
||||
</Page.Resources>
|
||||
<Grid Margin="10">
|
||||
|
||||
<Grid Margin="20,0,20,10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- 0: 标题栏 -->
|
||||
<RowDefinition Height="*"/>
|
||||
<!-- 1: 表格区(撑满剩余空间) -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- 2: 操作按钮区 -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- 3: 底部导航栏(固定在窗口底部) -->
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 顶部标题栏 -->
|
||||
<Grid Grid.Row="0" Margin="0 0 0 10">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="2" Style="{StaticResource MainTitleStyle}" Text="记录画面"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
|
||||
<Grid Grid.Row="0" Margin="0,0,0,15">
|
||||
<TextBlock Style="{StaticResource MainTitleStyle}" Text="历史测试记录" HorizontalAlignment="Center"/>
|
||||
</Grid>
|
||||
<!--表格-->
|
||||
<Grid Grid.Row="1" Margin="0 0 0 10">
|
||||
|
||||
<!-- 表格区(卡片样式,占据剩余高度) -->
|
||||
<Border Grid.Row="1" Style="{StaticResource CardStyle}" Padding="5" Margin="0,0,0,15">
|
||||
<DataGrid x:Name="RecordDataGrid"
|
||||
Height="400"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
Style="{StaticResource DataGridStyle}"
|
||||
ColumnHeaderStyle="{StaticResource DataGridColumnHeaderStyle}"
|
||||
RowStyle="{StaticResource DataGridRowStyle}"
|
||||
CellStyle="{StaticResource DataGridCellStyle}"
|
||||
AlternationCount="2"
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="Column"
|
||||
GridLinesVisibility="All"
|
||||
Style="{StaticResource DataGridStyle}"
|
||||
AlternationCount="2"
|
||||
ColumnHeaderStyle="{StaticResource DataGridColumnHeaderStyle}"
|
||||
RowStyle="{StaticResource DataGridRowStyle}"
|
||||
CellStyle="{StaticResource DataGridCellStyle}"
|
||||
>
|
||||
|
||||
<!-- 表格列(你要的 6 列) -->
|
||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Auto"
|
||||
VerticalAlignment="Stretch">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="编号" Binding="{Binding Id}" Width="70" IsReadOnly="True" />
|
||||
<DataGridTextColumn Header="时间" Binding="{Binding Time}" Width="120" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="日期" Binding="{Binding Date}" Width="120" IsReadOnly="True" />
|
||||
<DataGridTextColumn Header="左目视野面积" Binding="{Binding LeftEyeArea,StringFormat=F2}" Width="130" IsReadOnly="True" />
|
||||
<DataGridTextColumn Header="右目视野面积" Binding="{Binding RightEyeArea,StringFormat=F2}" Width="130" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="双目视野面积" Binding="{Binding BinocularArea,StringFormat=F2}" Width="130" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="下方视野" Binding="{Binding LowerVision,StringFormat=F2}" Width="130" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="总视野面积" Binding="{Binding totalVisionArea,StringFormat=F2}" Width="130" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="双目视野保存率" Binding="{Binding VisionRetentionRate,StringFormat=F2}" Width="130" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="总视野保存率" Binding="{Binding GetVisionRetentionRate,StringFormat=F2}" Width="130" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="编号" Binding="{Binding Id}" Width="60" />
|
||||
<DataGridTextColumn Header="时间" Binding="{Binding Time}" Width="80" />
|
||||
<DataGridTextColumn Header="日期" Binding="{Binding Date}" Width="80" />
|
||||
<DataGridTextColumn Header="左目视野面积" Binding="{Binding LeftEyeArea,StringFormat=F2}" Width="105" />
|
||||
<DataGridTextColumn Header="右目视野面积" Binding="{Binding RightEyeArea,StringFormat=F2}" Width="105" />
|
||||
<DataGridTextColumn Header="双目视野面积" Binding="{Binding BinocularArea,StringFormat=F2}" Width="105" />
|
||||
<DataGridTextColumn Header="下方视野" Binding="{Binding LowerVision,StringFormat=F2}" Width="90" />
|
||||
<DataGridTextColumn Header="总视野面积" Binding="{Binding totalVisionArea,StringFormat=F2}" Width="105" />
|
||||
<DataGridTextColumn Header="双目保存率" Binding="{Binding VisionRetentionRate,StringFormat=F2}" Width="100" />
|
||||
<DataGridTextColumn Header="总保存率" Binding="{Binding GetVisionRetentionRate,StringFormat=F2}" Width="100" />
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</Grid>
|
||||
<!--按钮-->
|
||||
<Grid Grid.Row="2" Margin="0,30,0,0">
|
||||
<!-- 停止 -->
|
||||
<Button Content="保存" FontSize="18"
|
||||
Width="120" Height="50" Background="#3498DB" Foreground="White" Margin="840,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Click="btnSave_Click" />
|
||||
<Button Content="清除" FontSize="18"
|
||||
Width="120" Height="50" Background="White" BorderBrush="red" Foreground="red" Margin="10,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"
|
||||
PreviewMouseLeftButtonDown ="btnClear_MouseDown" PreviewMouseLeftButtonUp ="btnClear_MouseUp" />
|
||||
<TextBlock HorizontalAlignment="Left" Foreground="red" Margin="139,14,0,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="18" Width="202"><Run Language="zh-cn" Text="备注: 清除长按"/></TextBlock>
|
||||
</Border>
|
||||
|
||||
<!-- 操作按钮区 -->
|
||||
<Grid Grid.Row="2" Margin="0,0,0,15">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center">
|
||||
<Button Content="保存" Style="{StaticResource ActionButtonStyle}" Background="#27AE60" Margin="5" Click="btnSave_Click"/>
|
||||
<Button Content="清除" Style="{StaticResource ActionButtonStyle}" Background="#E74C3C" Margin="5"
|
||||
PreviewMouseLeftButtonDown="btnClear_MouseDown" PreviewMouseLeftButtonUp="btnClear_MouseUp"/>
|
||||
<TextBlock Text="长按清除" VerticalAlignment="Center" Margin="15,0,0,0" FontSize="13" Foreground="#E74C3C" FontStyle="Italic"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
<!-- 底部导航栏 -->
|
||||
<!-- 底部导航栏(固定在窗口底部) -->
|
||||
<Grid Grid.Row="3" VerticalAlignment="Bottom">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<!--<ColumnDefinition Width="*"/>-->
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Button Style="{StaticResource TabButtonStyle}" Grid.Column="0" Content="主页"
|
||||
Click="GoHome" />
|
||||
<Button Style="{StaticResource TabButtonStyle}" Grid.Column="1" Content="测试界面"
|
||||
Click="GoTest" />
|
||||
<!--<Button Style="{StaticResource TabButtonStyle}" Grid.Column="2" Content="数据记录"
|
||||
Click="GoRecord" />-->
|
||||
<Button Style="{StaticResource TabButtonStyle}" Grid.Column="3" Content="记录画面"
|
||||
Click="GoView" />
|
||||
<Button Style="{StaticResource TabButtonStyle}" Grid.Column="0" Content="主页" Click="GoHome"/>
|
||||
<Button Style="{StaticResource TabButtonStyle}" Grid.Column="1" Content="测试界面" Click="GoTest"/>
|
||||
<Button Style="{StaticResource TabButtonStyle}" Grid.Column="2" Content="记录画面" Click="GoView"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Page>
|
||||
Reference in New Issue
Block a user