完善保护功能
This commit is contained in:
parent
1a8c113fbc
commit
61819a3139
@ -97,6 +97,12 @@ public partial class ProtectRow : ObservableObject
|
|||||||
[ObservableProperty] private double _tripTimeMs;
|
[ObservableProperty] private double _tripTimeMs;
|
||||||
[ObservableProperty] private TestStatus _status = TestStatus.Untested;
|
[ObservableProperty] private TestStatus _status = TestStatus.Untested;
|
||||||
|
|
||||||
|
public bool CanMeasureFromPower =>
|
||||||
|
ProtectType is "跳闸" or "过压" or "欠压" or "限流";
|
||||||
|
|
||||||
|
partial void OnProtectTypeChanged(string value) =>
|
||||||
|
OnPropertyChanged(nameof(CanMeasureFromPower));
|
||||||
|
|
||||||
public static string BuildMeasuredValue(string protectType, double? inputVoltage, double? inputCurrent) => protectType switch
|
public static string BuildMeasuredValue(string protectType, double? inputVoltage, double? inputCurrent) => protectType switch
|
||||||
{
|
{
|
||||||
"跳闸" when inputCurrent.HasValue => $"{inputCurrent.Value:F3} A",
|
"跳闸" when inputCurrent.HasValue => $"{inputCurrent.Value:F3} A",
|
||||||
@ -105,3 +111,63 @@ public partial class ProtectRow : ObservableObject
|
|||||||
_ => "----"
|
_ => "----"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>保护功能固定测试项与结果初始化逻辑。</summary>
|
||||||
|
public static class ProtectTestPlan
|
||||||
|
{
|
||||||
|
public const string ManualJudgeMode = "人工判别";
|
||||||
|
|
||||||
|
public static readonly IReadOnlyList<(string ProtectType, string Trigger)> Items = new[]
|
||||||
|
{
|
||||||
|
("跳闸", "1.5×额定电流"),
|
||||||
|
("短路", "输出短路"),
|
||||||
|
("过温", "≥85℃"),
|
||||||
|
("过压", "≥32V"),
|
||||||
|
("欠压", "≤22V"),
|
||||||
|
("限流", "≥1.2A"),
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void EnsureRows(Project project)
|
||||||
|
{
|
||||||
|
var existing = project.ProtectResults
|
||||||
|
.GroupBy(x => x.ProtectType)
|
||||||
|
.ToDictionary(x => x.Key, x => x.First());
|
||||||
|
|
||||||
|
project.ProtectResults.Clear();
|
||||||
|
for (int i = 0; i < Items.Count; i++)
|
||||||
|
{
|
||||||
|
var item = Items[i];
|
||||||
|
if (!existing.TryGetValue(item.ProtectType, out var row))
|
||||||
|
{
|
||||||
|
row = new ProtectRow
|
||||||
|
{
|
||||||
|
ProtectType = item.ProtectType,
|
||||||
|
Status = TestStatus.Untested
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
row.Index = i + 1;
|
||||||
|
row.ProtectType = item.ProtectType;
|
||||||
|
if (string.IsNullOrWhiteSpace(row.Trigger))
|
||||||
|
row.Trigger = item.Trigger;
|
||||||
|
if (string.IsNullOrWhiteSpace(row.JudgeMode))
|
||||||
|
row.JudgeMode = ManualJudgeMode;
|
||||||
|
|
||||||
|
project.ProtectResults.Add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshMeasuredValues(project, overwriteExisting: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RefreshMeasuredValues(Project project, bool overwriteExisting = true)
|
||||||
|
{
|
||||||
|
var latestPower = project.PowerResults.LastOrDefault();
|
||||||
|
foreach (var row in project.ProtectResults)
|
||||||
|
{
|
||||||
|
if (!overwriteExisting && !string.IsNullOrWhiteSpace(row.MeasuredValue) && row.MeasuredValue != "----")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
row.MeasuredValue = ProtectRow.BuildMeasuredValue(row.ProtectType, latestPower?.Vin, latestPower?.Iin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -98,7 +98,7 @@ internal sealed class LegacyReportGenerator
|
|||||||
|
|
||||||
if (sel.Protect && (p.ProtectResults.Count > 0 || HasManualNote(p.TestFunction?.Protect)))
|
if (sel.Protect && (p.ProtectResults.Count > 0 || HasManualNote(p.TestFunction?.Protect)))
|
||||||
{
|
{
|
||||||
Section(col, "7. 保护功能(框架占位)");
|
Section(col, "7. 保护功能");
|
||||||
if (p.ProtectResults.Count > 0) col.Item().Element(e => ProtectTable(e, p));
|
if (p.ProtectResults.Count > 0) col.Item().Element(e => ProtectTable(e, p));
|
||||||
ManualNote(col, p.TestFunction?.Protect);
|
ManualNote(col, p.TestFunction?.Protect);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,47 +2,30 @@ using SSPCTester.Logic.Models;
|
|||||||
|
|
||||||
namespace SSPCTester.Logic.Testing;
|
namespace SSPCTester.Logic.Testing;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>保护功能测试:刷新固定保护测试项的实测值与测量状态。</summary>
|
||||||
/// 保护功能测试:当前阶段仅生成框架占位结果,不真正触发故障。
|
|
||||||
/// </summary>
|
|
||||||
public sealed class ProtectTest : ITestModule
|
public sealed class ProtectTest : ITestModule
|
||||||
{
|
{
|
||||||
public string Name => "保护功能";
|
public const string ModuleName = "保护功能";
|
||||||
|
public string Name => ModuleName;
|
||||||
private static readonly (string Type, string Trigger)[] _items = new[]
|
|
||||||
{
|
|
||||||
("跳闸", "1.5×额定电流"),
|
|
||||||
("短路", "输出短路"),
|
|
||||||
("过温", "≥85℃"),
|
|
||||||
("过压", "≥32V"),
|
|
||||||
("欠压", "≤22V"),
|
|
||||||
("限流", "≥1.2A"),
|
|
||||||
};
|
|
||||||
|
|
||||||
public async Task RunAsync(TestContext ctx, IProgress<TestProgress> progress, CancellationToken ct)
|
public async Task RunAsync(TestContext ctx, IProgress<TestProgress> progress, CancellationToken ct)
|
||||||
{
|
{
|
||||||
ctx.Project.ProtectResults.Clear();
|
ProtectTestPlan.EnsureRows(ctx.Project);
|
||||||
var latestPower = ctx.Project.PowerResults.LastOrDefault();
|
|
||||||
for (int i = 0; i < _items.Length; i++)
|
for (int i = 0; i < ctx.Project.ProtectResults.Count; i++)
|
||||||
{
|
{
|
||||||
ct.ThrowIfCancellationRequested();
|
ct.ThrowIfCancellationRequested();
|
||||||
var row = new ProtectRow
|
var row = ctx.Project.ProtectResults[i];
|
||||||
{
|
bool preserveManualJudgement = row.Status is TestStatus.Pass or TestStatus.Fail;
|
||||||
Index = i + 1,
|
if (!preserveManualJudgement)
|
||||||
ProtectType = _items[i].Type,
|
row.Status = TestStatus.Running;
|
||||||
Trigger = _items[i].Trigger,
|
ProtectTestPlan.RefreshMeasuredValues(ctx.Project, overwriteExisting: false);
|
||||||
MeasuredValue = ProtectRow.BuildMeasuredValue(_items[i].Type, latestPower?.Vin, latestPower?.Iin),
|
progress.Report(new TestProgress { ModuleName = Name, Step = i, TotalSteps = ctx.Project.ProtectResults.Count, Message = $"保护项测量:{row.ProtectType}" });
|
||||||
JudgeMode = "人工判别",
|
|
||||||
Status = TestStatus.Running
|
|
||||||
};
|
|
||||||
ctx.Project.ProtectResults.Add(row);
|
|
||||||
progress.Report(new TestProgress { ModuleName = Name, Step = i, TotalSteps = _items.Length, Message = $"框架占位:{row.ProtectType}" });
|
|
||||||
|
|
||||||
await Task.Delay(150, ct).ConfigureAwait(false);
|
await Task.Delay(150, ct).ConfigureAwait(false);
|
||||||
// 框架占位:固定演示数据
|
if (!preserveManualJudgement && row.Status == TestStatus.Running)
|
||||||
row.TripTimeMs = 2.0 + i * 0.3;
|
row.Status = TestStatus.Measured;
|
||||||
row.Status = TestStatus.Pass;
|
progress.Report(new TestProgress { ModuleName = Name, Step = i + 1, TotalSteps = ctx.Project.ProtectResults.Count, StepStatus = row.Status });
|
||||||
progress.Report(new TestProgress { ModuleName = Name, Step = i + 1, TotalSteps = _items.Length, StepStatus = row.Status });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
72
SSPCTester.Tests/ProtectTestTests.cs
Normal file
72
SSPCTester.Tests/ProtectTestTests.cs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
using SSPCTester.Logic.Models;
|
||||||
|
using SSPCTester.Logic.Testing;
|
||||||
|
|
||||||
|
namespace SSPCTester.Tests;
|
||||||
|
|
||||||
|
public sealed class ProtectTestTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task ProtectTest_EnsuresSixProtectionRowsAndRefreshesMeasuredValues()
|
||||||
|
{
|
||||||
|
var project = new Project();
|
||||||
|
project.PowerResults.Add(new PowerLossRow
|
||||||
|
{
|
||||||
|
Vin = 28.193,
|
||||||
|
Iin = 1.049,
|
||||||
|
Status = TestStatus.Pass
|
||||||
|
});
|
||||||
|
|
||||||
|
var progress = new List<TestProgress>();
|
||||||
|
var context = new TestContext(project, null!, null!, null!, null!);
|
||||||
|
|
||||||
|
await new ProtectTest().RunAsync(context, new InlineProgress(progress.Add), CancellationToken.None);
|
||||||
|
|
||||||
|
Assert.Equal(6, project.ProtectResults.Count);
|
||||||
|
Assert.Collection(project.ProtectResults,
|
||||||
|
row => AssertProtection(row, 1, "跳闸", "1.5×额定电流", "1.049 A"),
|
||||||
|
row => AssertProtection(row, 2, "短路", "输出短路", "----"),
|
||||||
|
row => AssertProtection(row, 3, "过温", "≥85℃", "----"),
|
||||||
|
row => AssertProtection(row, 4, "过压", "≥32V", "28.193 V"),
|
||||||
|
row => AssertProtection(row, 5, "欠压", "≤22V", "28.193 V"),
|
||||||
|
row => AssertProtection(row, 6, "限流", "≥1.2A", "1.049 A"));
|
||||||
|
Assert.All(project.ProtectResults, row => Assert.Equal(TestStatus.Measured, row.Status));
|
||||||
|
Assert.Contains(progress, x => x.ModuleName == ProtectTest.ModuleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ProtectTest_PreservesEditedTriggerAndMeasuredValue()
|
||||||
|
{
|
||||||
|
var project = new Project();
|
||||||
|
project.ProtectResults.Add(new ProtectRow
|
||||||
|
{
|
||||||
|
ProtectType = "跳闸",
|
||||||
|
Trigger = "用户触发条件",
|
||||||
|
MeasuredValue = "1.234 A",
|
||||||
|
JudgeMode = ProtectTestPlan.ManualJudgeMode,
|
||||||
|
Status = TestStatus.Pass
|
||||||
|
});
|
||||||
|
|
||||||
|
var context = new TestContext(project, null!, null!, null!, null!);
|
||||||
|
|
||||||
|
await new ProtectTest().RunAsync(context, new InlineProgress(_ => { }), CancellationToken.None);
|
||||||
|
|
||||||
|
var trip = project.ProtectResults.Single(x => x.ProtectType == "跳闸");
|
||||||
|
Assert.Equal("用户触发条件", trip.Trigger);
|
||||||
|
Assert.Equal("1.234 A", trip.MeasuredValue);
|
||||||
|
Assert.Equal(TestStatus.Pass, trip.Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AssertProtection(ProtectRow row, int index, string type, string trigger, string measured)
|
||||||
|
{
|
||||||
|
Assert.Equal(index, row.Index);
|
||||||
|
Assert.Equal(type, row.ProtectType);
|
||||||
|
Assert.Equal(trigger, row.Trigger);
|
||||||
|
Assert.Equal(measured, row.MeasuredValue);
|
||||||
|
Assert.Equal(ProtectTestPlan.ManualJudgeMode, row.JudgeMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class InlineProgress(Action<TestProgress> handler) : IProgress<TestProgress>
|
||||||
|
{
|
||||||
|
public void Report(TestProgress value) => handler(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -30,6 +30,7 @@ public sealed class WordReportGeneratorTests
|
|||||||
Assert.Contains("ProjectA", text);
|
Assert.Contains("ProjectA", text);
|
||||||
Assert.Contains("基础测试", text);
|
Assert.Contains("基础测试", text);
|
||||||
Assert.Contains("功率损耗", text);
|
Assert.Contains("功率损耗", text);
|
||||||
|
Assert.Contains("PROTECTION FUNCTION", text);
|
||||||
|
|
||||||
var fontNames = document.MainDocumentPart.Document.Descendants<RunFonts>()
|
var fontNames = document.MainDocumentPart.Document.Descendants<RunFonts>()
|
||||||
.SelectMany(x => new[] { x.Ascii?.Value, x.HighAnsi?.Value, x.EastAsia?.Value })
|
.SelectMany(x => new[] { x.Ascii?.Value, x.HighAnsi?.Value, x.EastAsia?.Value })
|
||||||
|
|||||||
@ -1,87 +1,73 @@
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using SSPCTester.Devices.Interfaces;
|
||||||
using SSPCTester.Logic.Models;
|
using SSPCTester.Logic.Models;
|
||||||
using SSPCTester.UI.Services;
|
using SSPCTester.UI.Services;
|
||||||
|
|
||||||
namespace SSPCTester.UI.ViewModels;
|
namespace SSPCTester.UI.ViewModels;
|
||||||
|
|
||||||
/// <summary>保护功能页 VM(框架占位)。</summary>
|
/// <summary>保护功能页 VM。</summary>
|
||||||
public partial class ProtectViewModel : ObservableObject
|
public partial class ProtectViewModel : ObservableObject
|
||||||
{
|
{
|
||||||
|
private readonly IPowerSupply _power;
|
||||||
private readonly UiLogSink _log;
|
private readonly UiLogSink _log;
|
||||||
|
private TestSessionViewModel? _session;
|
||||||
public ObservableCollection<ProtectRow> Rows { get; } = new();
|
public ObservableCollection<ProtectRow> Rows { get; } = new();
|
||||||
|
|
||||||
[ObservableProperty] private Project? _project;
|
[ObservableProperty] private Project? _project;
|
||||||
[ObservableProperty] private bool _enableTrip = true;
|
|
||||||
[ObservableProperty] private bool _enableShort = true;
|
|
||||||
[ObservableProperty] private bool _enableOverTemp = true;
|
|
||||||
[ObservableProperty] private bool _enableOverVolt = true;
|
|
||||||
[ObservableProperty] private bool _enableUnderVolt = true;
|
|
||||||
[ObservableProperty] private bool _enableLimit = true;
|
|
||||||
|
|
||||||
[ObservableProperty] private double _overVoltThreshold = 32;
|
public ProtectViewModel(IPowerSupply power, UiLogSink log)
|
||||||
[ObservableProperty] private double _underVoltThreshold = 22;
|
{
|
||||||
[ObservableProperty] private double _overCurrentThreshold = 1.2;
|
_power = power;
|
||||||
[ObservableProperty] private double _overTempThreshold = 85;
|
_log = log;
|
||||||
|
}
|
||||||
public ProtectViewModel(UiLogSink log) { _log = log; }
|
|
||||||
|
|
||||||
public void SetProject(Project p)
|
public void SetProject(Project p)
|
||||||
{
|
{
|
||||||
Project = p;
|
Project = p;
|
||||||
|
ProtectTestPlan.EnsureRows(p);
|
||||||
SyncRowsFromProject();
|
SyncRowsFromProject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AttachSession(TestSessionViewModel session)
|
||||||
|
{
|
||||||
|
if (_session != null)
|
||||||
|
_session.ProtectResultsChanged -= SyncRowsFromProject;
|
||||||
|
|
||||||
|
_session = session;
|
||||||
|
_session.ProtectResultsChanged += SyncRowsFromProject;
|
||||||
|
}
|
||||||
|
|
||||||
private void SyncRowsFromProject()
|
private void SyncRowsFromProject()
|
||||||
{
|
{
|
||||||
if (Project == null) return;
|
if (Project == null) return;
|
||||||
|
|
||||||
var latestPower = Project.PowerResults.LastOrDefault();
|
ProtectTestPlan.RefreshMeasuredValues(Project, overwriteExisting: false);
|
||||||
for (int i = 0; i < Project.ProtectResults.Count; i++)
|
|
||||||
{
|
|
||||||
var row = Project.ProtectResults[i];
|
|
||||||
row.Index = i + 1;
|
|
||||||
row.MeasuredValue = ProtectRow.BuildMeasuredValue(row.ProtectType, latestPower?.Vin, latestPower?.Iin);
|
|
||||||
if (string.IsNullOrWhiteSpace(row.JudgeMode))
|
|
||||||
row.JudgeMode = "人工判别";
|
|
||||||
}
|
|
||||||
|
|
||||||
Rows.Clear();
|
Rows.Clear();
|
||||||
foreach (var row in Project.ProtectResults) Rows.Add(row);
|
foreach (var row in Project.ProtectResults) Rows.Add(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private void RunDemo()
|
private async Task MeasurePowerAsync(ProtectRow? row)
|
||||||
{
|
{
|
||||||
if (Project == null) return;
|
if (row == null || !row.CanMeasureFromPower) return;
|
||||||
Project.ProtectResults.Clear();
|
|
||||||
Rows.Clear();
|
try
|
||||||
var latestPower = Project.PowerResults.LastOrDefault();
|
|
||||||
var items = new (string, string)[]
|
|
||||||
{
|
{
|
||||||
("跳闸", "1.5x额定电流"),
|
var (volts, amps) = await _power.ReadAsync();
|
||||||
("短路", "输出短路"),
|
row.MeasuredValue = row.ProtectType switch
|
||||||
("过温", $">={OverTempThreshold} ℃"),
|
{
|
||||||
("过压", $">={OverVoltThreshold} V"),
|
"过压" or "欠压" => $"{volts:F3} V",
|
||||||
("欠压", $"<={UnderVoltThreshold} V"),
|
_ => $"{amps:F3} A"
|
||||||
("限流", $">={OverCurrentThreshold} A"),
|
|
||||||
};
|
};
|
||||||
for (int i = 0; i < items.Length; i++)
|
if (row.Status is TestStatus.Untested or TestStatus.Running)
|
||||||
|
row.Status = TestStatus.Measured;
|
||||||
|
_log.Add(UiLogLevel.Success, $"保护功能 {row.ProtectType} 实测值:{row.MeasuredValue}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var r = new ProtectRow
|
_log.Add(UiLogLevel.Error, $"读取电源失败:{ex.Message}");
|
||||||
{
|
}
|
||||||
Index = i + 1,
|
|
||||||
ProtectType = items[i].Item1,
|
|
||||||
Trigger = items[i].Item2,
|
|
||||||
MeasuredValue = ProtectRow.BuildMeasuredValue(items[i].Item1, latestPower?.Vin, latestPower?.Iin),
|
|
||||||
JudgeMode = "人工判别",
|
|
||||||
TripTimeMs = 2 + i * 0.3,
|
|
||||||
Status = TestStatus.Pass
|
|
||||||
};
|
|
||||||
Project.ProtectResults.Add(r);
|
|
||||||
Rows.Add(r);
|
|
||||||
}
|
|
||||||
_log.Add(UiLogLevel.Warning, "保护功能模块仅生成框架演示数据。");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,5 +32,6 @@ public partial class TestHostViewModel : ObservableObject
|
|||||||
{
|
{
|
||||||
Session = s;
|
Session = s;
|
||||||
Curve.AttachSession(s);
|
Curve.AttachSession(s);
|
||||||
|
Protect.AttachSession(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,7 @@ public sealed class TestSessionViewModel
|
|||||||
private readonly CancellationTokenSource _cts = new();
|
private readonly CancellationTokenSource _cts = new();
|
||||||
|
|
||||||
public event Action<int, CurveData, CurveData>? CurveReady;
|
public event Action<int, CurveData, CurveData>? CurveReady;
|
||||||
|
public event Action? ProtectResultsChanged;
|
||||||
|
|
||||||
public TestSessionViewModel(IServiceProvider sp, Project project,
|
public TestSessionViewModel(IServiceProvider sp, Project project,
|
||||||
ISspc sspc, IPowerSupply power, ILoad load, IDaq daq, UiLogSink logSink)
|
ISspc sspc, IPowerSupply power, ILoad load, IDaq daq, UiLogSink logSink)
|
||||||
@ -50,6 +51,9 @@ public sealed class TestSessionViewModel
|
|||||||
|
|
||||||
IProgress<TestProgress> progress = new Progress<TestProgress>(p =>
|
IProgress<TestProgress> progress = new Progress<TestProgress>(p =>
|
||||||
{
|
{
|
||||||
|
if (p.ModuleName == ProtectTest.ModuleName)
|
||||||
|
ProtectResultsChanged?.Invoke();
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(p.Message))
|
if (!string.IsNullOrEmpty(p.Message))
|
||||||
{
|
{
|
||||||
var lvl = p.StepStatus switch
|
var lvl = p.StepStatus switch
|
||||||
|
|||||||
@ -27,15 +27,49 @@
|
|||||||
<Border Style="{StaticResource Card}" Margin="0,0,12,0">
|
<Border Style="{StaticResource Card}" Margin="0,0,12,0">
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
<TextBlock DockPanel.Dock="Top" Style="{StaticResource CardTitle}" Text="测试记录" />
|
<TextBlock DockPanel.Dock="Top" Style="{StaticResource CardTitle}" Text="测试记录" />
|
||||||
<DataGrid ItemsSource="{Binding Rows}">
|
<DataGrid ItemsSource="{Binding Rows}" IsReadOnly="False">
|
||||||
<DataGrid.Columns>
|
<DataGrid.Columns>
|
||||||
<DataGridTextColumn Header="序号" Binding="{Binding Index}" Width="60" />
|
<DataGridTextColumn Header="序号" Binding="{Binding Index}" Width="60" IsReadOnly="True" />
|
||||||
<DataGridTextColumn Header="保护类型" Binding="{Binding ProtectType}" Width="*" />
|
<DataGridTextColumn Header="保护类型" Binding="{Binding ProtectType}" Width="*" IsReadOnly="True" />
|
||||||
<DataGridTextColumn Header="触发条件" Binding="{Binding Trigger}" Width="2*" />
|
<DataGridTextColumn Header="触发条件" Binding="{Binding Trigger, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="2*" />
|
||||||
<DataGridTextColumn Header="实测值" Width="*">
|
<DataGridTemplateColumn Header="实测值" Width="*">
|
||||||
<DataGridTextColumn.Binding><Binding Path="MeasuredValue" /></DataGridTextColumn.Binding>
|
<DataGridTemplateColumn.CellTemplate>
|
||||||
<DataGridTextColumn.ElementStyle><Style TargetType="TextBlock" BasedOn="{StaticResource MonoText}" /></DataGridTextColumn.ElementStyle>
|
<DataTemplate>
|
||||||
</DataGridTextColumn>
|
<DockPanel LastChildFill="True">
|
||||||
|
<Button DockPanel.Dock="Right"
|
||||||
|
Content="测"
|
||||||
|
Width="30"
|
||||||
|
Height="24"
|
||||||
|
Padding="0"
|
||||||
|
Margin="6,0,0,0"
|
||||||
|
Command="{Binding DataContext.MeasurePowerCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||||
|
CommandParameter="{Binding}"
|
||||||
|
Visibility="{Binding CanMeasureFromPower, Converter={StaticResource BoolToVis}}" />
|
||||||
|
<TextBlock Text="{Binding MeasuredValue}"
|
||||||
|
Style="{StaticResource MonoText}"
|
||||||
|
VerticalAlignment="Center" />
|
||||||
|
</DockPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
|
<DataGridTemplateColumn.CellEditingTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<DockPanel LastChildFill="True">
|
||||||
|
<Button DockPanel.Dock="Right"
|
||||||
|
Content="测"
|
||||||
|
Width="30"
|
||||||
|
Height="24"
|
||||||
|
Padding="0"
|
||||||
|
Margin="6,0,0,0"
|
||||||
|
Command="{Binding DataContext.MeasurePowerCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||||
|
CommandParameter="{Binding}"
|
||||||
|
Visibility="{Binding CanMeasureFromPower, Converter={StaticResource BoolToVis}}" />
|
||||||
|
<TextBox Text="{Binding MeasuredValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||||
|
FontFamily="{StaticResource FontMono}"
|
||||||
|
VerticalContentAlignment="Center" />
|
||||||
|
</DockPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</DataGridTemplateColumn.CellEditingTemplate>
|
||||||
|
</DataGridTemplateColumn>
|
||||||
<DataGridTemplateColumn Header="判别模式" Width="120">
|
<DataGridTemplateColumn Header="判别模式" Width="120">
|
||||||
<DataGridTemplateColumn.CellTemplate>
|
<DataGridTemplateColumn.CellTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
@ -56,6 +90,8 @@
|
|||||||
MinWidth="90">
|
MinWidth="90">
|
||||||
<ComboBoxItem Content="合格" Tag="{x:Static model:TestStatus.Pass}" />
|
<ComboBoxItem Content="合格" Tag="{x:Static model:TestStatus.Pass}" />
|
||||||
<ComboBoxItem Content="不合格" Tag="{x:Static model:TestStatus.Fail}" />
|
<ComboBoxItem Content="不合格" Tag="{x:Static model:TestStatus.Fail}" />
|
||||||
|
<ComboBoxItem Content="已测量" Tag="{x:Static model:TestStatus.Measured}" />
|
||||||
|
<ComboBoxItem Content="未判定" Tag="{x:Static model:TestStatus.Untested}" />
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
@ -72,7 +108,7 @@
|
|||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
|
||||||
<Border Grid.Column="1" Style="{StaticResource Card}" Padding="14">
|
<Border Grid.Column="0" Style="{StaticResource Card}" Padding="14">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user