CNC数据存储问题,包括中间的处理情况的缓存
This commit is contained in:
@@ -0,0 +1,340 @@
|
|||||||
|
using Moq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using XP.Common.Configs;
|
||||||
|
using XP.Common.Database.Implementations;
|
||||||
|
using XP.Common.Database.Interfaces;
|
||||||
|
using XP.Common.Logging.Interfaces;
|
||||||
|
using XplorePlane.Models;
|
||||||
|
using XplorePlane.Services.InspectionResults;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace XplorePlane.Tests.Services
|
||||||
|
{
|
||||||
|
public class InspectionResultStoreTests : IDisposable
|
||||||
|
{
|
||||||
|
private readonly string _tempRoot;
|
||||||
|
private readonly Mock<ILoggerService> _mockLogger;
|
||||||
|
private readonly IDbContext _dbContext;
|
||||||
|
private readonly InspectionResultStore _store;
|
||||||
|
|
||||||
|
public InspectionResultStoreTests()
|
||||||
|
{
|
||||||
|
_tempRoot = Path.Combine(Path.GetTempPath(), "XplorePlane.Tests", Guid.NewGuid().ToString("N"));
|
||||||
|
Directory.CreateDirectory(_tempRoot);
|
||||||
|
|
||||||
|
_mockLogger = new Mock<ILoggerService>();
|
||||||
|
_mockLogger.Setup(l => l.ForModule(It.IsAny<string>())).Returns(_mockLogger.Object);
|
||||||
|
_mockLogger.Setup(l => l.ForModule<InspectionResultStore>()).Returns(_mockLogger.Object);
|
||||||
|
|
||||||
|
var sqliteConfig = new SqliteConfig
|
||||||
|
{
|
||||||
|
DbFilePath = Path.Combine(_tempRoot, "inspection-results.db"),
|
||||||
|
CreateIfNotExists = true,
|
||||||
|
EnableWalMode = false,
|
||||||
|
EnableSqlLogging = false
|
||||||
|
};
|
||||||
|
|
||||||
|
_dbContext = new SqliteContext(sqliteConfig, _mockLogger.Object);
|
||||||
|
_store = new InspectionResultStore(_dbContext, _mockLogger.Object, Path.Combine(_tempRoot, "assets"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task FullRun_WithTwoNodes_CanRoundTripDetailAndQuery()
|
||||||
|
{
|
||||||
|
var startedAt = new DateTime(2026, 4, 21, 10, 0, 0, DateTimeKind.Utc);
|
||||||
|
var run = new InspectionRunRecord
|
||||||
|
{
|
||||||
|
ProgramName = "NewCncProgram",
|
||||||
|
WorkpieceId = "QFN_1",
|
||||||
|
SerialNumber = "SN-001",
|
||||||
|
StartedAt = startedAt
|
||||||
|
};
|
||||||
|
|
||||||
|
var runSource = CreateTempFile("run-source.bmp", "run-source");
|
||||||
|
await _store.BeginRunAsync(run, new InspectionAssetWriteRequest
|
||||||
|
{
|
||||||
|
AssetType = InspectionAssetType.RunSourceImage,
|
||||||
|
SourceFilePath = runSource,
|
||||||
|
FileFormat = "bmp"
|
||||||
|
});
|
||||||
|
|
||||||
|
var pipelineA = BuildPipeline("Recipe-A", ("GaussianBlur", 0), ("Threshold", 1));
|
||||||
|
var node1Id = Guid.NewGuid();
|
||||||
|
await _store.AppendNodeResultAsync(
|
||||||
|
new InspectionNodeResult
|
||||||
|
{
|
||||||
|
RunId = run.RunId,
|
||||||
|
NodeId = node1Id,
|
||||||
|
NodeIndex = 1,
|
||||||
|
NodeName = "检测节点1",
|
||||||
|
PipelineId = pipelineA.Id,
|
||||||
|
PipelineName = pipelineA.Name,
|
||||||
|
NodePass = true,
|
||||||
|
DurationMs = 135
|
||||||
|
},
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
new InspectionMetricResult
|
||||||
|
{
|
||||||
|
MetricKey = "bridge.rate",
|
||||||
|
MetricName = "Bridge Rate",
|
||||||
|
MetricValue = 0.12,
|
||||||
|
Unit = "%",
|
||||||
|
UpperLimit = 0.2,
|
||||||
|
IsPass = true,
|
||||||
|
DisplayOrder = 1
|
||||||
|
},
|
||||||
|
new InspectionMetricResult
|
||||||
|
{
|
||||||
|
MetricKey = "void.area",
|
||||||
|
MetricName = "Void Area",
|
||||||
|
MetricValue = 5.6,
|
||||||
|
Unit = "px",
|
||||||
|
UpperLimit = 8,
|
||||||
|
IsPass = true,
|
||||||
|
DisplayOrder = 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new PipelineExecutionSnapshot
|
||||||
|
{
|
||||||
|
PipelineName = pipelineA.Name,
|
||||||
|
PipelineDefinitionJson = JsonSerializer.Serialize(pipelineA)
|
||||||
|
},
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
new InspectionAssetWriteRequest
|
||||||
|
{
|
||||||
|
AssetType = InspectionAssetType.NodeInputImage,
|
||||||
|
SourceFilePath = CreateTempFile("node1-input.bmp", "node1-input"),
|
||||||
|
FileFormat = "bmp"
|
||||||
|
},
|
||||||
|
new InspectionAssetWriteRequest
|
||||||
|
{
|
||||||
|
AssetType = InspectionAssetType.NodeResultImage,
|
||||||
|
SourceFilePath = CreateTempFile("node1-result.bmp", "node1-result"),
|
||||||
|
FileFormat = "bmp"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var pipelineB = BuildPipeline("Recipe-B", ("MeanFilter", 0), ("ContourDetection", 1));
|
||||||
|
var node2Id = Guid.NewGuid();
|
||||||
|
await _store.AppendNodeResultAsync(
|
||||||
|
new InspectionNodeResult
|
||||||
|
{
|
||||||
|
RunId = run.RunId,
|
||||||
|
NodeId = node2Id,
|
||||||
|
NodeIndex = 2,
|
||||||
|
NodeName = "检测节点2",
|
||||||
|
PipelineId = pipelineB.Id,
|
||||||
|
PipelineName = pipelineB.Name,
|
||||||
|
NodePass = false,
|
||||||
|
Status = InspectionNodeStatus.Failed,
|
||||||
|
DurationMs = 240
|
||||||
|
},
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
new InspectionMetricResult
|
||||||
|
{
|
||||||
|
MetricKey = "solder.height",
|
||||||
|
MetricName = "Solder Height",
|
||||||
|
MetricValue = 1.7,
|
||||||
|
Unit = "mm",
|
||||||
|
LowerLimit = 1.8,
|
||||||
|
IsPass = false,
|
||||||
|
DisplayOrder = 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new PipelineExecutionSnapshot
|
||||||
|
{
|
||||||
|
PipelineName = pipelineB.Name,
|
||||||
|
PipelineDefinitionJson = JsonSerializer.Serialize(pipelineB)
|
||||||
|
},
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
new InspectionAssetWriteRequest
|
||||||
|
{
|
||||||
|
AssetType = InspectionAssetType.NodeResultImage,
|
||||||
|
SourceFilePath = CreateTempFile("node2-result.bmp", "node2-result"),
|
||||||
|
FileFormat = "bmp"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await _store.CompleteRunAsync(run.RunId);
|
||||||
|
|
||||||
|
var queried = await _store.QueryRunsAsync(new InspectionRunQuery
|
||||||
|
{
|
||||||
|
ProgramName = "NewCncProgram",
|
||||||
|
WorkpieceId = "QFN_1",
|
||||||
|
PipelineName = "Recipe-A"
|
||||||
|
});
|
||||||
|
|
||||||
|
var detail = await _store.GetRunDetailAsync(run.RunId);
|
||||||
|
|
||||||
|
Assert.Single(queried);
|
||||||
|
Assert.Equal(run.RunId, queried[0].RunId);
|
||||||
|
Assert.False(detail.Run.OverallPass);
|
||||||
|
Assert.Equal(2, detail.Run.NodeCount);
|
||||||
|
Assert.Equal(2, detail.Nodes.Count);
|
||||||
|
Assert.Equal(3, detail.Metrics.Count);
|
||||||
|
Assert.Equal(4, detail.Assets.Count);
|
||||||
|
Assert.Equal(2, detail.PipelineSnapshots.Count);
|
||||||
|
Assert.Contains(detail.Nodes, n => n.NodeId == node1Id && n.NodePass);
|
||||||
|
Assert.Contains(detail.Nodes, n => n.NodeId == node2Id && !n.NodePass);
|
||||||
|
Assert.All(detail.PipelineSnapshots, snapshot => Assert.False(string.IsNullOrWhiteSpace(snapshot.PipelineHash)));
|
||||||
|
|
||||||
|
var manifestPath = Path.Combine(_tempRoot, "assets", detail.Run.ResultRootPath.Replace('/', Path.DirectorySeparatorChar), "manifest.json");
|
||||||
|
Assert.True(File.Exists(manifestPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task AppendNodeResult_MissingAsset_DoesNotCrashAndMarksAssetMissing()
|
||||||
|
{
|
||||||
|
var run = new InspectionRunRecord
|
||||||
|
{
|
||||||
|
ProgramName = "Program-A",
|
||||||
|
WorkpieceId = "Part-01",
|
||||||
|
SerialNumber = "SN-404"
|
||||||
|
};
|
||||||
|
|
||||||
|
await _store.BeginRunAsync(run);
|
||||||
|
|
||||||
|
var nodeId = Guid.NewGuid();
|
||||||
|
await _store.AppendNodeResultAsync(
|
||||||
|
new InspectionNodeResult
|
||||||
|
{
|
||||||
|
RunId = run.RunId,
|
||||||
|
NodeId = nodeId,
|
||||||
|
NodeIndex = 1,
|
||||||
|
NodeName = "缺图节点",
|
||||||
|
PipelineId = Guid.NewGuid(),
|
||||||
|
PipelineName = "Recipe-Missing",
|
||||||
|
NodePass = true
|
||||||
|
},
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
new InspectionMetricResult
|
||||||
|
{
|
||||||
|
MetricKey = "metric.only",
|
||||||
|
MetricName = "Metric Only",
|
||||||
|
MetricValue = 1,
|
||||||
|
Unit = "pcs",
|
||||||
|
IsPass = true,
|
||||||
|
DisplayOrder = 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new PipelineExecutionSnapshot
|
||||||
|
{
|
||||||
|
PipelineName = "Recipe-Missing",
|
||||||
|
PipelineDefinitionJson = "{\"nodes\":[\"gaussian\"]}"
|
||||||
|
},
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
new InspectionAssetWriteRequest
|
||||||
|
{
|
||||||
|
AssetType = InspectionAssetType.NodeResultImage,
|
||||||
|
SourceFilePath = Path.Combine(_tempRoot, "missing-file.bmp"),
|
||||||
|
FileFormat = "bmp"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var detail = await _store.GetRunDetailAsync(run.RunId);
|
||||||
|
var node = Assert.Single(detail.Nodes);
|
||||||
|
|
||||||
|
Assert.Equal(InspectionNodeStatus.AssetMissing, node.Status);
|
||||||
|
Assert.Single(detail.Metrics);
|
||||||
|
Assert.Empty(detail.Assets);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task PipelineSnapshot_IsStoredAsExecutionSnapshot_NotDependentOnLaterChanges()
|
||||||
|
{
|
||||||
|
var run = new InspectionRunRecord
|
||||||
|
{
|
||||||
|
ProgramName = "Program-Snapshot",
|
||||||
|
WorkpieceId = "Part-02",
|
||||||
|
SerialNumber = "SN-SNAP"
|
||||||
|
};
|
||||||
|
|
||||||
|
await _store.BeginRunAsync(run);
|
||||||
|
|
||||||
|
var pipeline = BuildPipeline("Recipe-Snapshot", ("GaussianBlur", 0), ("ContourDetection", 1));
|
||||||
|
var snapshotJson = JsonSerializer.Serialize(pipeline);
|
||||||
|
var originalHash = ComputeExpectedHash(snapshotJson);
|
||||||
|
|
||||||
|
await _store.AppendNodeResultAsync(
|
||||||
|
new InspectionNodeResult
|
||||||
|
{
|
||||||
|
RunId = run.RunId,
|
||||||
|
NodeId = Guid.NewGuid(),
|
||||||
|
NodeIndex = 1,
|
||||||
|
NodeName = "快照节点",
|
||||||
|
PipelineId = pipeline.Id,
|
||||||
|
PipelineName = pipeline.Name,
|
||||||
|
NodePass = true
|
||||||
|
},
|
||||||
|
pipelineSnapshot: new PipelineExecutionSnapshot
|
||||||
|
{
|
||||||
|
PipelineName = pipeline.Name,
|
||||||
|
PipelineDefinitionJson = snapshotJson
|
||||||
|
});
|
||||||
|
|
||||||
|
pipeline.Name = "Recipe-Snapshot-Changed";
|
||||||
|
pipeline.Nodes[0].OperatorKey = "MeanFilter";
|
||||||
|
|
||||||
|
var detail = await _store.GetRunDetailAsync(run.RunId);
|
||||||
|
var snapshot = Assert.Single(detail.PipelineSnapshots);
|
||||||
|
|
||||||
|
Assert.Equal("Recipe-Snapshot", snapshot.PipelineName);
|
||||||
|
Assert.Equal(snapshotJson, snapshot.PipelineDefinitionJson);
|
||||||
|
Assert.Equal(originalHash, snapshot.PipelineHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_dbContext.Dispose();
|
||||||
|
if (Directory.Exists(_tempRoot))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.Delete(_tempRoot, true);
|
||||||
|
}
|
||||||
|
catch (IOException)
|
||||||
|
{
|
||||||
|
// SQLite file handles may release slightly after test teardown.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string CreateTempFile(string fileName, string content)
|
||||||
|
{
|
||||||
|
var path = Path.Combine(_tempRoot, fileName);
|
||||||
|
File.WriteAllText(path, content);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PipelineModel BuildPipeline(string name, params (string OperatorKey, int Order)[] nodes)
|
||||||
|
{
|
||||||
|
return new PipelineModel
|
||||||
|
{
|
||||||
|
Name = name,
|
||||||
|
Nodes = nodes.Select(node => new PipelineNodeModel
|
||||||
|
{
|
||||||
|
OperatorKey = node.OperatorKey,
|
||||||
|
Order = node.Order
|
||||||
|
}).ToList()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ComputeExpectedHash(string value)
|
||||||
|
{
|
||||||
|
using var sha = System.Security.Cryptography.SHA256.Create();
|
||||||
|
var bytes = System.Text.Encoding.UTF8.GetBytes(value);
|
||||||
|
return Convert.ToHexString(sha.ComputeHash(bytes));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,6 +36,7 @@ using XplorePlane.Services.Camera;
|
|||||||
using XplorePlane.Services.Cnc;
|
using XplorePlane.Services.Cnc;
|
||||||
using XplorePlane.Services.Matrix;
|
using XplorePlane.Services.Matrix;
|
||||||
using XplorePlane.Services.Measurement;
|
using XplorePlane.Services.Measurement;
|
||||||
|
using XplorePlane.Services.InspectionResults;
|
||||||
using XplorePlane.Services.Recipe;
|
using XplorePlane.Services.Recipe;
|
||||||
using XplorePlane.ViewModels;
|
using XplorePlane.ViewModels;
|
||||||
using XplorePlane.ViewModels.Cnc;
|
using XplorePlane.ViewModels.Cnc;
|
||||||
@@ -317,6 +318,7 @@ namespace XplorePlane
|
|||||||
containerRegistry.RegisterSingleton<ICncProgramService, CncProgramService>();
|
containerRegistry.RegisterSingleton<ICncProgramService, CncProgramService>();
|
||||||
containerRegistry.RegisterSingleton<IMatrixService, MatrixService>();
|
containerRegistry.RegisterSingleton<IMatrixService, MatrixService>();
|
||||||
containerRegistry.RegisterSingleton<IMeasurementDataService, MeasurementDataService>();
|
containerRegistry.RegisterSingleton<IMeasurementDataService, MeasurementDataService>();
|
||||||
|
containerRegistry.RegisterSingleton<IInspectionResultStore, InspectionResultStore>();
|
||||||
|
|
||||||
// ── CNC / 矩阵 ViewModel(瞬态)──
|
// ── CNC / 矩阵 ViewModel(瞬态)──
|
||||||
containerRegistry.Register<CncEditorViewModel>();
|
containerRegistry.Register<CncEditorViewModel>();
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace XplorePlane.Models
|
||||||
|
{
|
||||||
|
public enum InspectionAssetType
|
||||||
|
{
|
||||||
|
RunSourceImage,
|
||||||
|
NodeInputImage,
|
||||||
|
NodeResultImage
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum InspectionNodeStatus
|
||||||
|
{
|
||||||
|
Succeeded,
|
||||||
|
Failed,
|
||||||
|
PartialSuccess,
|
||||||
|
AssetMissing
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InspectionRunRecord
|
||||||
|
{
|
||||||
|
public Guid RunId { get; set; } = Guid.NewGuid();
|
||||||
|
public string ProgramName { get; set; } = string.Empty;
|
||||||
|
public string WorkpieceId { get; set; } = string.Empty;
|
||||||
|
public string SerialNumber { get; set; } = string.Empty;
|
||||||
|
public DateTime StartedAt { get; set; } = DateTime.UtcNow;
|
||||||
|
public DateTime? CompletedAt { get; set; }
|
||||||
|
public bool OverallPass { get; set; }
|
||||||
|
public string SourceImagePath { get; set; } = string.Empty;
|
||||||
|
public string ResultRootPath { get; set; } = string.Empty;
|
||||||
|
public int NodeCount { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InspectionNodeResult
|
||||||
|
{
|
||||||
|
public Guid RunId { get; set; }
|
||||||
|
public Guid NodeId { get; set; } = Guid.NewGuid();
|
||||||
|
public int NodeIndex { get; set; }
|
||||||
|
public string NodeName { get; set; } = string.Empty;
|
||||||
|
public Guid PipelineId { get; set; }
|
||||||
|
public string PipelineName { get; set; } = string.Empty;
|
||||||
|
public string PipelineVersionHash { get; set; } = string.Empty;
|
||||||
|
public bool NodePass { get; set; }
|
||||||
|
public string SourceImagePath { get; set; } = string.Empty;
|
||||||
|
public string ResultImagePath { get; set; } = string.Empty;
|
||||||
|
public InspectionNodeStatus Status { get; set; } = InspectionNodeStatus.Succeeded;
|
||||||
|
public long DurationMs { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InspectionMetricResult
|
||||||
|
{
|
||||||
|
public Guid RunId { get; set; }
|
||||||
|
public Guid NodeId { get; set; }
|
||||||
|
public string MetricKey { get; set; } = string.Empty;
|
||||||
|
public string MetricName { get; set; } = string.Empty;
|
||||||
|
public double MetricValue { get; set; }
|
||||||
|
public string Unit { get; set; } = string.Empty;
|
||||||
|
public double? LowerLimit { get; set; }
|
||||||
|
public double? UpperLimit { get; set; }
|
||||||
|
public bool IsPass { get; set; }
|
||||||
|
public int DisplayOrder { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InspectionAssetRecord
|
||||||
|
{
|
||||||
|
public Guid RunId { get; set; }
|
||||||
|
public Guid? NodeId { get; set; }
|
||||||
|
public InspectionAssetType AssetType { get; set; }
|
||||||
|
public string RelativePath { get; set; } = string.Empty;
|
||||||
|
public string FileFormat { get; set; } = string.Empty;
|
||||||
|
public int Width { get; set; }
|
||||||
|
public int Height { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PipelineExecutionSnapshot
|
||||||
|
{
|
||||||
|
public Guid RunId { get; set; }
|
||||||
|
public Guid NodeId { get; set; }
|
||||||
|
public string PipelineName { get; set; } = string.Empty;
|
||||||
|
public string PipelineDefinitionJson { get; set; } = string.Empty;
|
||||||
|
public string PipelineHash { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InspectionAssetWriteRequest
|
||||||
|
{
|
||||||
|
public InspectionAssetType AssetType { get; set; }
|
||||||
|
public string FileName { get; set; } = string.Empty;
|
||||||
|
public string SourceFilePath { get; set; } = string.Empty;
|
||||||
|
public byte[] Content { get; set; }
|
||||||
|
public string FileFormat { get; set; } = string.Empty;
|
||||||
|
public int Width { get; set; }
|
||||||
|
public int Height { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InspectionRunQuery
|
||||||
|
{
|
||||||
|
public string ProgramName { get; set; } = string.Empty;
|
||||||
|
public string WorkpieceId { get; set; } = string.Empty;
|
||||||
|
public string SerialNumber { get; set; } = string.Empty;
|
||||||
|
public string PipelineName { get; set; } = string.Empty;
|
||||||
|
public DateTime? From { get; set; }
|
||||||
|
public DateTime? To { get; set; }
|
||||||
|
public int? Skip { get; set; }
|
||||||
|
public int? Take { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InspectionRunDetail
|
||||||
|
{
|
||||||
|
public InspectionRunRecord Run { get; set; } = new();
|
||||||
|
public IReadOnlyList<InspectionNodeResult> Nodes { get; set; } = Array.Empty<InspectionNodeResult>();
|
||||||
|
public IReadOnlyList<InspectionMetricResult> Metrics { get; set; } = Array.Empty<InspectionMetricResult>();
|
||||||
|
public IReadOnlyList<InspectionAssetRecord> Assets { get; set; } = Array.Empty<InspectionAssetRecord>();
|
||||||
|
public IReadOnlyList<PipelineExecutionSnapshot> PipelineSnapshots { get; set; } = Array.Empty<PipelineExecutionSnapshot>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using XplorePlane.Models;
|
||||||
|
|
||||||
|
namespace XplorePlane.Services.InspectionResults
|
||||||
|
{
|
||||||
|
public interface IInspectionResultStore
|
||||||
|
{
|
||||||
|
Task BeginRunAsync(InspectionRunRecord runRecord, InspectionAssetWriteRequest runSourceAsset = null);
|
||||||
|
|
||||||
|
Task AppendNodeResultAsync(
|
||||||
|
InspectionNodeResult nodeResult,
|
||||||
|
IEnumerable<InspectionMetricResult> metrics = null,
|
||||||
|
PipelineExecutionSnapshot pipelineSnapshot = null,
|
||||||
|
IEnumerable<InspectionAssetWriteRequest> assets = null);
|
||||||
|
|
||||||
|
Task CompleteRunAsync(Guid runId, bool? overallPass = null, DateTime? completedAt = null);
|
||||||
|
|
||||||
|
Task<IReadOnlyList<InspectionRunRecord>> QueryRunsAsync(InspectionRunQuery query = null);
|
||||||
|
|
||||||
|
Task<InspectionRunDetail> GetRunDetailAsync(Guid runId);
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -4,10 +4,10 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:cnc="clr-namespace:XplorePlane.Views.Cnc"
|
xmlns:cnc="clr-namespace:XplorePlane.Views.Cnc"
|
||||||
Title="CNC 编辑器"
|
Title="CNC 编辑器"
|
||||||
Width="544"
|
Width="1180"
|
||||||
Height="750"
|
Height="780"
|
||||||
MinWidth="544"
|
MinWidth="1040"
|
||||||
MinHeight="750"
|
MinHeight="720"
|
||||||
ResizeMode="CanResize"
|
ResizeMode="CanResize"
|
||||||
ShowInTaskbar="False"
|
ShowInTaskbar="False"
|
||||||
WindowStartupLocation="CenterOwner">
|
WindowStartupLocation="CenterOwner">
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
xmlns:prism="http://prismlibrary.com/"
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
xmlns:vm="clr-namespace:XplorePlane.ViewModels.Cnc"
|
xmlns:vm="clr-namespace:XplorePlane.ViewModels.Cnc"
|
||||||
d:DesignHeight="760"
|
d:DesignHeight="760"
|
||||||
d:DesignWidth="1040"
|
d:DesignWidth="1180"
|
||||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
|
||||||
@@ -17,19 +17,35 @@
|
|||||||
<local:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
<local:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||||
|
|
||||||
<SolidColorBrush x:Key="PanelBg" Color="White" />
|
<SolidColorBrush x:Key="PanelBg" Color="White" />
|
||||||
<SolidColorBrush x:Key="PanelBorder" Color="#cdcbcb" />
|
<SolidColorBrush x:Key="PanelBorder" Color="#CDCBCB" />
|
||||||
<SolidColorBrush x:Key="SeparatorBrush" Color="#E0E0E0" />
|
<SolidColorBrush x:Key="SeparatorBrush" Color="#E5E5E5" />
|
||||||
<SolidColorBrush x:Key="TreeItemHover" Color="#F5F9FF" />
|
<SolidColorBrush x:Key="HeaderBg" Color="#F7F7F7" />
|
||||||
<SolidColorBrush x:Key="TreeItemSelected" Color="#E8F0FE" />
|
<SolidColorBrush x:Key="SoftBlue" Color="#E8F0FE" />
|
||||||
|
<SolidColorBrush x:Key="SoftBlueBorder" Color="#5B9BD5" />
|
||||||
|
<FontFamily x:Key="UiFont">Microsoft YaHei UI</FontFamily>
|
||||||
|
|
||||||
<Style x:Key="ToolbarBtn" TargetType="Button">
|
<Style x:Key="ToolbarBtn" TargetType="Button">
|
||||||
<Setter Property="Height" Value="28" />
|
<Setter Property="Height" Value="26" />
|
||||||
|
<Setter Property="MinWidth" Value="40" />
|
||||||
<Setter Property="Margin" Value="2,0" />
|
<Setter Property="Margin" Value="2,0" />
|
||||||
<Setter Property="Padding" Value="6,0" />
|
<Setter Property="Padding" Value="8,0" />
|
||||||
<Setter Property="Background" Value="Transparent" />
|
<Setter Property="Background" Value="White" />
|
||||||
<Setter Property="BorderBrush" Value="#cdcbcb" />
|
<Setter Property="BorderBrush" Value="#CDCBCB" />
|
||||||
<Setter Property="BorderThickness" Value="1" />
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
<Setter Property="FontFamily" Value="Microsoft YaHei UI" />
|
<Setter Property="FontFamily" Value="{StaticResource UiFont}" />
|
||||||
|
<Setter Property="FontSize" Value="11" />
|
||||||
|
<Setter Property="Cursor" Value="Hand" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="InsertBtn" TargetType="Button">
|
||||||
|
<Setter Property="Height" Value="28" />
|
||||||
|
<Setter Property="Margin" Value="0,0,0,6" />
|
||||||
|
<Setter Property="Padding" Value="8,0" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Left" />
|
||||||
|
<Setter Property="Background" Value="White" />
|
||||||
|
<Setter Property="BorderBrush" Value="#D7D7D7" />
|
||||||
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
|
<Setter Property="FontFamily" Value="{StaticResource UiFont}" />
|
||||||
<Setter Property="FontSize" Value="11" />
|
<Setter Property="FontSize" Value="11" />
|
||||||
<Setter Property="Cursor" Value="Hand" />
|
<Setter Property="Cursor" Value="Hand" />
|
||||||
</Style>
|
</Style>
|
||||||
@@ -41,10 +57,46 @@
|
|||||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="EditorTitle" TargetType="TextBlock">
|
||||||
|
<Setter Property="FontFamily" Value="{StaticResource UiFont}" />
|
||||||
|
<Setter Property="FontSize" Value="13" />
|
||||||
|
<Setter Property="FontWeight" Value="SemiBold" />
|
||||||
|
<Setter Property="Margin" Value="0,0,0,8" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="LabelStyle" TargetType="TextBlock">
|
||||||
|
<Setter Property="FontFamily" Value="{StaticResource UiFont}" />
|
||||||
|
<Setter Property="FontSize" Value="11" />
|
||||||
|
<Setter Property="Foreground" Value="#666666" />
|
||||||
|
<Setter Property="Margin" Value="0,0,0,3" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="EditorBox" TargetType="TextBox">
|
||||||
|
<Setter Property="Height" Value="28" />
|
||||||
|
<Setter Property="Padding" Value="8,3" />
|
||||||
|
<Setter Property="Margin" Value="0,0,0,8" />
|
||||||
|
<Setter Property="BorderBrush" Value="#CFCFCF" />
|
||||||
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
|
<Setter Property="FontFamily" Value="{StaticResource UiFont}" />
|
||||||
|
<Setter Property="FontSize" Value="11" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="EditorCheck" TargetType="CheckBox">
|
||||||
|
<Setter Property="Margin" Value="0,2,0,8" />
|
||||||
|
<Setter Property="FontFamily" Value="{StaticResource UiFont}" />
|
||||||
|
<Setter Property="FontSize" Value="11" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="CompactGroupBox" TargetType="GroupBox">
|
||||||
|
<Setter Property="Margin" Value="0,0,0,10" />
|
||||||
|
<Setter Property="Padding" Value="0" />
|
||||||
|
<Setter Property="FontFamily" Value="{StaticResource UiFont}" />
|
||||||
|
<Setter Property="FontSize" Value="11" />
|
||||||
|
</Style>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
<Border
|
<Border
|
||||||
MinWidth="550"
|
MinWidth="980"
|
||||||
Background="{StaticResource PanelBg}"
|
Background="{StaticResource PanelBg}"
|
||||||
BorderBrush="{StaticResource PanelBorder}"
|
BorderBrush="{StaticResource PanelBorder}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
@@ -53,7 +105,9 @@
|
|||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="280" MinWidth="240" />
|
<ColumnDefinition Width="280" MinWidth="240" />
|
||||||
<ColumnDefinition Width="1" />
|
<ColumnDefinition Width="1" />
|
||||||
<ColumnDefinition Width="*" MinWidth="300" />
|
<ColumnDefinition Width="430" MinWidth="360" />
|
||||||
|
<ColumnDefinition Width="1" />
|
||||||
|
<ColumnDefinition Width="*" MinWidth="260" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<Grid Grid.Column="0">
|
<Grid Grid.Column="0">
|
||||||
@@ -65,116 +119,116 @@
|
|||||||
<Border
|
<Border
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Padding="10,8"
|
Padding="10,8"
|
||||||
|
Background="{StaticResource HeaderBg}"
|
||||||
BorderBrush="{StaticResource SeparatorBrush}"
|
BorderBrush="{StaticResource SeparatorBrush}"
|
||||||
BorderThickness="0,0,0,1">
|
BorderThickness="0,0,0,1">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
FontFamily="Microsoft YaHei UI"
|
FontFamily="{StaticResource UiFont}"
|
||||||
FontSize="14"
|
FontSize="14"
|
||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
Text="{Binding ProgramName, TargetNullValue=CNC Program}" />
|
Text="{Binding ProgramName, TargetNullValue=NewCncProgram}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="0,4,0,0"
|
Margin="0,3,0,0"
|
||||||
FontFamily="Microsoft YaHei UI"
|
FontFamily="{StaticResource UiFont}"
|
||||||
FontSize="11"
|
FontSize="10.5"
|
||||||
Foreground="#666"
|
Foreground="#666666"
|
||||||
Text="模块节点下会自动归类显示标记/等待/消息节点" />
|
Text="模块节点下会自动显示标记、等待、消息等子节点" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<TreeView
|
<TreeView
|
||||||
x:Name="CncTreeView"
|
x:Name="CncTreeView"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
|
Padding="4,6"
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
BorderThickness="0"
|
BorderThickness="0"
|
||||||
ItemsSource="{Binding TreeNodes}"
|
ItemsSource="{Binding TreeNodes}"
|
||||||
SelectedItemChanged="CncTreeView_SelectedItemChanged">
|
SelectedItemChanged="CncTreeView_SelectedItemChanged">
|
||||||
<TreeView.Resources>
|
<TreeView.Resources>
|
||||||
<HierarchicalDataTemplate DataType="{x:Type vm:CncNodeViewModel}" ItemsSource="{Binding Children}">
|
<HierarchicalDataTemplate DataType="{x:Type vm:CncNodeViewModel}" ItemsSource="{Binding Children}">
|
||||||
<Grid x:Name="NodeRoot" MinHeight="42">
|
<Grid x:Name="NodeRoot" MinHeight="34">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="34" />
|
<ColumnDefinition Width="30" />
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<Border
|
<Border
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Width="26"
|
Width="22"
|
||||||
Height="26"
|
Height="22"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
BorderBrush="Transparent"
|
|
||||||
BorderThickness="0"
|
|
||||||
CornerRadius="4">
|
CornerRadius="4">
|
||||||
<Image
|
<Image
|
||||||
Width="18"
|
Width="15"
|
||||||
Height="18"
|
Height="15"
|
||||||
Source="{Binding Icon}"
|
Source="{Binding Icon}"
|
||||||
Stretch="Uniform" />
|
Stretch="Uniform" />
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="6,0,0,0"
|
Margin="4,0,0,0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Orientation="Horizontal">
|
Orientation="Horizontal">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
FontFamily="Microsoft YaHei UI"
|
FontFamily="{StaticResource UiFont}"
|
||||||
FontSize="11"
|
FontSize="10.5"
|
||||||
Foreground="#888"
|
Foreground="#888888"
|
||||||
Text="{Binding Index, StringFormat='[{0}] '}" />
|
Text="{Binding Index, StringFormat='[{0}] '}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
FontFamily="Microsoft YaHei UI"
|
FontFamily="{StaticResource UiFont}"
|
||||||
FontSize="12"
|
FontSize="11.5"
|
||||||
Text="{Binding Name}" />
|
Text="{Binding Name}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel
|
<StackPanel
|
||||||
x:Name="NodeActions"
|
x:Name="NodeActions"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Margin="0,0,4,0"
|
Margin="0,0,2,0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Orientation="Horizontal"
|
Orientation="Horizontal"
|
||||||
Visibility="Collapsed">
|
Visibility="Collapsed">
|
||||||
<Button
|
<Button
|
||||||
Width="22"
|
Width="20"
|
||||||
Height="22"
|
Height="20"
|
||||||
Margin="1,0"
|
Margin="1,0"
|
||||||
Background="Transparent"
|
Background="White"
|
||||||
BorderBrush="#cdcbcb"
|
BorderBrush="#CDCBCB"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Command="{Binding DataContext.MoveNodeUpCommand, RelativeSource={RelativeSource AncestorType=TreeView}}"
|
Command="{Binding DataContext.MoveNodeUpCommand, RelativeSource={RelativeSource AncestorType=TreeView}}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Content="▲"
|
Content="↑"
|
||||||
Cursor="Hand"
|
Cursor="Hand"
|
||||||
FontSize="10"
|
FontSize="10"
|
||||||
ToolTip="上移" />
|
ToolTip="上移" />
|
||||||
<Button
|
<Button
|
||||||
Width="22"
|
Width="20"
|
||||||
Height="22"
|
Height="20"
|
||||||
Margin="1,0"
|
Margin="1,0"
|
||||||
Background="Transparent"
|
Background="White"
|
||||||
BorderBrush="#cdcbcb"
|
BorderBrush="#CDCBCB"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Command="{Binding DataContext.MoveNodeDownCommand, RelativeSource={RelativeSource AncestorType=TreeView}}"
|
Command="{Binding DataContext.MoveNodeDownCommand, RelativeSource={RelativeSource AncestorType=TreeView}}"
|
||||||
CommandParameter="{Binding}"
|
CommandParameter="{Binding}"
|
||||||
Content="▼"
|
Content="↓"
|
||||||
Cursor="Hand"
|
Cursor="Hand"
|
||||||
FontSize="10"
|
FontSize="10"
|
||||||
ToolTip="下移" />
|
ToolTip="下移" />
|
||||||
<Button
|
<Button
|
||||||
Width="22"
|
Width="20"
|
||||||
Height="22"
|
Height="20"
|
||||||
Margin="1,0"
|
Margin="1,0"
|
||||||
Background="Transparent"
|
Background="White"
|
||||||
BorderBrush="#E05050"
|
BorderBrush="#E05050"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
Command="{Binding DataContext.DeleteNodeCommand, RelativeSource={RelativeSource AncestorType=TreeView}}"
|
Command="{Binding DataContext.DeleteNodeCommand, RelativeSource={RelativeSource AncestorType=TreeView}}"
|
||||||
Content="✕"
|
Content="×"
|
||||||
Cursor="Hand"
|
Cursor="Hand"
|
||||||
FontSize="10"
|
FontSize="10"
|
||||||
ToolTip="删除" />
|
ToolTip="删除" />
|
||||||
@@ -199,42 +253,15 @@
|
|||||||
Fill="{StaticResource SeparatorBrush}" />
|
Fill="{StaticResource SeparatorBrush}" />
|
||||||
|
|
||||||
<ScrollViewer Grid.Column="2" VerticalScrollBarVisibility="Auto">
|
<ScrollViewer Grid.Column="2" VerticalScrollBarVisibility="Auto">
|
||||||
<Grid Margin="18,18,22,18">
|
<Grid Margin="14,12,16,12">
|
||||||
<Grid.Resources>
|
|
||||||
<Style x:Key="EditorTitle" TargetType="TextBlock">
|
|
||||||
<Setter Property="FontFamily" Value="Microsoft YaHei UI" />
|
|
||||||
<Setter Property="FontSize" Value="13" />
|
|
||||||
<Setter Property="FontWeight" Value="SemiBold" />
|
|
||||||
<Setter Property="Margin" Value="0,0,0,12" />
|
|
||||||
</Style>
|
|
||||||
<Style x:Key="LabelStyle" TargetType="TextBlock">
|
|
||||||
<Setter Property="FontFamily" Value="Microsoft YaHei UI" />
|
|
||||||
<Setter Property="FontSize" Value="12" />
|
|
||||||
<Setter Property="Foreground" Value="#666" />
|
|
||||||
<Setter Property="Margin" Value="0,0,0,4" />
|
|
||||||
</Style>
|
|
||||||
<Style x:Key="EditorBox" TargetType="TextBox">
|
|
||||||
<Setter Property="Height" Value="30" />
|
|
||||||
<Setter Property="Padding" Value="8,4" />
|
|
||||||
<Setter Property="Margin" Value="0,0,0,12" />
|
|
||||||
<Setter Property="BorderBrush" Value="#CFCFCF" />
|
|
||||||
<Setter Property="BorderThickness" Value="1" />
|
|
||||||
<Setter Property="FontFamily" Value="Microsoft YaHei UI" />
|
|
||||||
</Style>
|
|
||||||
<Style x:Key="EditorCheck" TargetType="CheckBox">
|
|
||||||
<Setter Property="Margin" Value="0,4,0,12" />
|
|
||||||
<Setter Property="FontFamily" Value="Microsoft YaHei UI" />
|
|
||||||
</Style>
|
|
||||||
</Grid.Resources>
|
|
||||||
|
|
||||||
<StackPanel Visibility="{Binding SelectedNode, Converter={StaticResource NullToVisibilityConverter}}">
|
<StackPanel Visibility="{Binding SelectedNode, Converter={StaticResource NullToVisibilityConverter}}">
|
||||||
<TextBlock Style="{StaticResource EditorTitle}" Text="节点属性" />
|
<TextBlock Style="{StaticResource EditorTitle}" Text="节点属性" />
|
||||||
|
|
||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="名称" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="名称" />
|
||||||
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Name, UpdateSourceTrigger=PropertyChanged}" />
|
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Name, UpdateSourceTrigger=PropertyChanged}" />
|
||||||
|
|
||||||
<UniformGrid Columns="2" Margin="0,0,0,12">
|
<UniformGrid Columns="2" Margin="0,0,0,8">
|
||||||
<StackPanel Margin="0,0,12,0">
|
<StackPanel Margin="0,0,8,0">
|
||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="索引" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="索引" />
|
||||||
<TextBox Style="{StaticResource EditorBox}" IsReadOnly="True" Text="{Binding SelectedNode.Index, Mode=OneWay}" />
|
<TextBox Style="{StaticResource EditorBox}" IsReadOnly="True" Text="{Binding SelectedNode.Index, Mode=OneWay}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
@@ -245,11 +272,11 @@
|
|||||||
</UniformGrid>
|
</UniformGrid>
|
||||||
|
|
||||||
<GroupBox
|
<GroupBox
|
||||||
Margin="0,0,0,12"
|
Style="{StaticResource CompactGroupBox}"
|
||||||
Header="运动参数"
|
Header="运动参数"
|
||||||
Visibility="{Binding SelectedNode.IsMotionSnapshotNode, Converter={StaticResource BoolToVisibilityConverter}}">
|
Visibility="{Binding SelectedNode.IsMotionSnapshotNode, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
<UniformGrid Margin="12" Columns="2">
|
<UniformGrid Margin="10,8,10,6" Columns="2">
|
||||||
<StackPanel Margin="0,0,12,0">
|
<StackPanel Margin="0,0,8,0">
|
||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="XM" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="XM" />
|
||||||
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.XM, UpdateSourceTrigger=LostFocus}" />
|
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.XM, UpdateSourceTrigger=LostFocus}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
@@ -257,7 +284,7 @@
|
|||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="YM" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="YM" />
|
||||||
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.YM, UpdateSourceTrigger=LostFocus}" />
|
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.YM, UpdateSourceTrigger=LostFocus}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Margin="0,0,12,0">
|
<StackPanel Margin="0,0,8,0">
|
||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="ZT" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="ZT" />
|
||||||
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.ZT, UpdateSourceTrigger=LostFocus}" />
|
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.ZT, UpdateSourceTrigger=LostFocus}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
@@ -265,7 +292,7 @@
|
|||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="ZD" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="ZD" />
|
||||||
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.ZD, UpdateSourceTrigger=LostFocus}" />
|
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.ZD, UpdateSourceTrigger=LostFocus}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Margin="0,0,12,0">
|
<StackPanel Margin="0,0,8,0">
|
||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="TiltD" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="TiltD" />
|
||||||
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.TiltD, UpdateSourceTrigger=LostFocus}" />
|
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.TiltD, UpdateSourceTrigger=LostFocus}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
@@ -277,10 +304,10 @@
|
|||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox
|
<GroupBox
|
||||||
Margin="0,0,0,12"
|
Style="{StaticResource CompactGroupBox}"
|
||||||
Header="射线源"
|
Header="射线源"
|
||||||
Visibility="{Binding SelectedNode.IsReferencePoint, Converter={StaticResource BoolToVisibilityConverter}}">
|
Visibility="{Binding SelectedNode.IsReferencePoint, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
<StackPanel Margin="12">
|
<StackPanel Margin="10,8,10,6">
|
||||||
<CheckBox Style="{StaticResource EditorCheck}" Content="射线源开启" IsChecked="{Binding SelectedNode.IsRayOn}" />
|
<CheckBox Style="{StaticResource EditorCheck}" Content="射线源开启" IsChecked="{Binding SelectedNode.IsRayOn}" />
|
||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="电压 (kV)" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="电压 (kV)" />
|
||||||
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Voltage, UpdateSourceTrigger=LostFocus}" />
|
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Voltage, UpdateSourceTrigger=LostFocus}" />
|
||||||
@@ -290,10 +317,10 @@
|
|||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox
|
<GroupBox
|
||||||
Margin="0,0,0,12"
|
Style="{StaticResource CompactGroupBox}"
|
||||||
Header="采集参数"
|
Header="采集参数"
|
||||||
Visibility="{Binding SelectedNode.IsSaveNode, Converter={StaticResource BoolToVisibilityConverter}}">
|
Visibility="{Binding SelectedNode.IsSaveNode, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
<StackPanel Margin="12">
|
<StackPanel Margin="10,8,10,6">
|
||||||
<CheckBox Style="{StaticResource EditorCheck}" Content="射线源开启" IsChecked="{Binding SelectedNode.IsRayOn}" />
|
<CheckBox Style="{StaticResource EditorCheck}" Content="射线源开启" IsChecked="{Binding SelectedNode.IsRayOn}" />
|
||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="电压 (kV)" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="电压 (kV)" />
|
||||||
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Voltage, UpdateSourceTrigger=LostFocus}" />
|
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Voltage, UpdateSourceTrigger=LostFocus}" />
|
||||||
@@ -309,10 +336,10 @@
|
|||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox
|
<GroupBox
|
||||||
Margin="0,0,0,12"
|
Style="{StaticResource CompactGroupBox}"
|
||||||
Header="采集参数"
|
Header="采集参数"
|
||||||
Visibility="{Binding SelectedNode.IsSaveNodeWithImage, Converter={StaticResource BoolToVisibilityConverter}}">
|
Visibility="{Binding SelectedNode.IsSaveNodeWithImage, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
<StackPanel Margin="12">
|
<StackPanel Margin="10,8,10,6">
|
||||||
<CheckBox Style="{StaticResource EditorCheck}" Content="射线源开启" IsChecked="{Binding SelectedNode.IsRayOn}" />
|
<CheckBox Style="{StaticResource EditorCheck}" Content="射线源开启" IsChecked="{Binding SelectedNode.IsRayOn}" />
|
||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="电压 (kV)" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="电压 (kV)" />
|
||||||
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Voltage, UpdateSourceTrigger=LostFocus}" />
|
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Voltage, UpdateSourceTrigger=LostFocus}" />
|
||||||
@@ -330,20 +357,20 @@
|
|||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox
|
<GroupBox
|
||||||
Margin="0,0,0,12"
|
Style="{StaticResource CompactGroupBox}"
|
||||||
Header="检测模块"
|
Header="检测模块"
|
||||||
Visibility="{Binding SelectedNode.IsInspectionModule, Converter={StaticResource BoolToVisibilityConverter}}">
|
Visibility="{Binding SelectedNode.IsInspectionModule, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
<StackPanel Margin="12">
|
<StackPanel Margin="10,8,10,6">
|
||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="Pipeline 名称" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="Pipeline 名称" />
|
||||||
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.PipelineName, UpdateSourceTrigger=PropertyChanged}" />
|
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.PipelineName, UpdateSourceTrigger=PropertyChanged}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox
|
<GroupBox
|
||||||
Margin="0,0,0,12"
|
Style="{StaticResource CompactGroupBox}"
|
||||||
Header="标记参数"
|
Header="标记参数"
|
||||||
Visibility="{Binding SelectedNode.IsInspectionMarker, Converter={StaticResource BoolToVisibilityConverter}}">
|
Visibility="{Binding SelectedNode.IsInspectionMarker, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
<StackPanel Margin="12">
|
<StackPanel Margin="10,8,10,6">
|
||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="标记类型" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="标记类型" />
|
||||||
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.MarkerType, UpdateSourceTrigger=PropertyChanged}" />
|
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.MarkerType, UpdateSourceTrigger=PropertyChanged}" />
|
||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="MarkerX" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="MarkerX" />
|
||||||
@@ -354,28 +381,32 @@
|
|||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox
|
<GroupBox
|
||||||
Margin="0,0,0,12"
|
Style="{StaticResource CompactGroupBox}"
|
||||||
Header="消息弹窗"
|
Header="消息弹窗"
|
||||||
Visibility="{Binding SelectedNode.IsPauseDialog, Converter={StaticResource BoolToVisibilityConverter}}">
|
Visibility="{Binding SelectedNode.IsPauseDialog, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
<StackPanel Margin="12">
|
<StackPanel Margin="10,8,10,6">
|
||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="标题" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="标题" />
|
||||||
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.DialogTitle, UpdateSourceTrigger=PropertyChanged}" />
|
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.DialogTitle, UpdateSourceTrigger=PropertyChanged}" />
|
||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="消息内容" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="消息内容" />
|
||||||
<TextBox
|
<TextBox
|
||||||
MinHeight="80"
|
MinHeight="68"
|
||||||
Margin="0,0,0,12"
|
Margin="0,0,0,8"
|
||||||
Padding="8,6"
|
Padding="8,6"
|
||||||
AcceptsReturn="True"
|
AcceptsReturn="True"
|
||||||
|
BorderBrush="#CFCFCF"
|
||||||
|
BorderThickness="1"
|
||||||
|
FontFamily="{StaticResource UiFont}"
|
||||||
|
FontSize="11"
|
||||||
Text="{Binding SelectedNode.DialogMessage, UpdateSourceTrigger=PropertyChanged}"
|
Text="{Binding SelectedNode.DialogMessage, UpdateSourceTrigger=PropertyChanged}"
|
||||||
TextWrapping="Wrap" />
|
TextWrapping="Wrap" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox
|
<GroupBox
|
||||||
Margin="0,0,0,12"
|
Style="{StaticResource CompactGroupBox}"
|
||||||
Header="等待参数"
|
Header="等待参数"
|
||||||
Visibility="{Binding SelectedNode.IsWaitDelay, Converter={StaticResource BoolToVisibilityConverter}}">
|
Visibility="{Binding SelectedNode.IsWaitDelay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
<StackPanel Margin="12">
|
<StackPanel Margin="10,8,10,6">
|
||||||
<TextBlock Style="{StaticResource LabelStyle}" Text="延时 (ms)" />
|
<TextBlock Style="{StaticResource LabelStyle}" Text="延时 (ms)" />
|
||||||
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.DelayMilliseconds, UpdateSourceTrigger=LostFocus}" />
|
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.DelayMilliseconds, UpdateSourceTrigger=LostFocus}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
@@ -383,7 +414,7 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<Border
|
<Border
|
||||||
Padding="24"
|
Padding="18"
|
||||||
Background="#FAFAFA"
|
Background="#FAFAFA"
|
||||||
BorderBrush="#E6E6E6"
|
BorderBrush="#E6E6E6"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
@@ -391,19 +422,260 @@
|
|||||||
Visibility="{Binding SelectedNode, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Invert}">
|
Visibility="{Binding SelectedNode, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=Invert}">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
FontFamily="Microsoft YaHei UI"
|
FontFamily="{StaticResource UiFont}"
|
||||||
FontSize="15"
|
FontSize="14"
|
||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"
|
||||||
Text="未选择节点" />
|
Text="未选择节点" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="0,8,0,0"
|
Margin="0,6,0,0"
|
||||||
FontFamily="Microsoft YaHei UI"
|
FontFamily="{StaticResource UiFont}"
|
||||||
Foreground="#666"
|
FontSize="11"
|
||||||
Text="从左侧树中选择一个节点后,这里会显示并允许编辑该节点的参数。" />
|
Foreground="#666666"
|
||||||
|
Text="从左侧树中选择一个节点后,这里会显示可编辑的参数。" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
</Grid>
|
</Grid>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
|
||||||
|
<Rectangle
|
||||||
|
Grid.Column="3"
|
||||||
|
Width="1"
|
||||||
|
Fill="{StaticResource SeparatorBrush}" />
|
||||||
|
|
||||||
|
<Grid Grid.Column="4">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Border
|
||||||
|
Grid.Row="0"
|
||||||
|
Padding="8,6"
|
||||||
|
Background="{StaticResource HeaderBg}"
|
||||||
|
BorderBrush="{StaticResource SeparatorBrush}"
|
||||||
|
BorderThickness="0,0,0,1">
|
||||||
|
<TextBlock
|
||||||
|
FontFamily="{StaticResource UiFont}"
|
||||||
|
FontSize="12"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Text="图像" />
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<Border
|
||||||
|
Grid.Row="1"
|
||||||
|
Padding="6,4"
|
||||||
|
BorderBrush="{StaticResource SeparatorBrush}"
|
||||||
|
BorderThickness="0,0,0,1">
|
||||||
|
<WrapPanel>
|
||||||
|
<Button Command="{Binding NewProgramCommand}" Content="新建" Style="{StaticResource ToolbarBtn}" />
|
||||||
|
<Button Command="{Binding SaveProgramCommand}" Content="保存" Style="{StaticResource ToolbarBtn}" />
|
||||||
|
<Button Command="{Binding ExportCsvCommand}" Content="另存为" Style="{StaticResource ToolbarBtn}" />
|
||||||
|
<Button Command="{Binding LoadProgramCommand}" Content="加载" Style="{StaticResource ToolbarBtn}" />
|
||||||
|
</WrapPanel>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<Border
|
||||||
|
Grid.Row="2"
|
||||||
|
Margin="8,8,8,6"
|
||||||
|
Padding="10"
|
||||||
|
Background="#FBFBFB"
|
||||||
|
BorderBrush="#DDDDDD"
|
||||||
|
BorderThickness="1">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
FontFamily="{StaticResource UiFont}"
|
||||||
|
FontSize="11"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Foreground="#D90000"
|
||||||
|
Text="{Binding ProgramName, StringFormat='配方名:{0}.xpm'}" />
|
||||||
|
|
||||||
|
<Border
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="0,8,0,10"
|
||||||
|
Height="140"
|
||||||
|
Background="Black">
|
||||||
|
<Grid>
|
||||||
|
<TextBlock
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontFamily="{StaticResource UiFont}"
|
||||||
|
FontSize="11"
|
||||||
|
Foreground="White"
|
||||||
|
Opacity="0.72"
|
||||||
|
Text="图像预览区域" />
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="2">
|
||||||
|
<Button Command="{Binding InsertReferencePointCommand}" Style="{StaticResource InsertBtn}">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Border
|
||||||
|
Width="20"
|
||||||
|
Height="20"
|
||||||
|
Margin="0,0,8,0"
|
||||||
|
Background="{StaticResource SoftBlue}"
|
||||||
|
BorderBrush="{StaticResource SoftBlueBorder}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="4">
|
||||||
|
<Image Width="13" Height="13" Source="/Assets/Icons/reference.png" Stretch="Uniform" />
|
||||||
|
</Border>
|
||||||
|
<TextBlock VerticalAlignment="Center" Text="参考点" />
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button Command="{Binding InsertInspectionModuleCommand}" Style="{StaticResource InsertBtn}">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Border
|
||||||
|
Width="20"
|
||||||
|
Height="20"
|
||||||
|
Margin="0,0,8,0"
|
||||||
|
Background="{StaticResource SoftBlue}"
|
||||||
|
BorderBrush="{StaticResource SoftBlueBorder}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="4">
|
||||||
|
<Image Width="13" Height="13" Source="/Assets/Icons/Module.png" Stretch="Uniform" />
|
||||||
|
</Border>
|
||||||
|
<TextBlock VerticalAlignment="Center" Text="检测模块" />
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button Command="{Binding InsertInspectionMarkerCommand}" Style="{StaticResource InsertBtn}">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Border
|
||||||
|
Width="20"
|
||||||
|
Height="20"
|
||||||
|
Margin="0,0,8,0"
|
||||||
|
Background="{StaticResource SoftBlue}"
|
||||||
|
BorderBrush="{StaticResource SoftBlueBorder}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="4">
|
||||||
|
<Image Width="13" Height="13" Source="/Assets/Icons/mark.png" Stretch="Uniform" />
|
||||||
|
</Border>
|
||||||
|
<TextBlock VerticalAlignment="Center" Text="标记节点" />
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button Command="{Binding InsertSaveNodeCommand}" Style="{StaticResource InsertBtn}" Content="插入保存节点" />
|
||||||
|
<Button Command="{Binding InsertSaveNodeWithImageCommand}" Style="{StaticResource InsertBtn}" Content="插入带图像保存节点" />
|
||||||
|
<Button Command="{Binding InsertSavePositionCommand}" Style="{StaticResource InsertBtn}" Content="插入保存位置" />
|
||||||
|
<Button Command="{Binding InsertPauseDialogCommand}" Style="{StaticResource InsertBtn}" Content="插入消息节点" />
|
||||||
|
<Button Command="{Binding InsertWaitDelayCommand}" Style="{StaticResource InsertBtn}" Content="插入等待节点" />
|
||||||
|
<Button Command="{Binding InsertCompleteProgramCommand}" Style="{StaticResource InsertBtn}" Content="插入结束节点" />
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<Border
|
||||||
|
Grid.Row="3"
|
||||||
|
Padding="8,6"
|
||||||
|
Background="{StaticResource HeaderBg}"
|
||||||
|
BorderBrush="{StaticResource SeparatorBrush}"
|
||||||
|
BorderThickness="0,1,0,1">
|
||||||
|
<TextBlock
|
||||||
|
FontFamily="{StaticResource UiFont}"
|
||||||
|
FontSize="12"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
Text="参数配置" />
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="4" Margin="8,8,8,0">
|
||||||
|
<TextBlock Style="{StaticResource LabelStyle}" Text="节点名称" />
|
||||||
|
<TextBox Style="{StaticResource EditorBox}" Text="{Binding SelectedNode.Name, UpdateSourceTrigger=PropertyChanged}" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="5" Margin="8,4,8,8">
|
||||||
|
<Grid Margin="0,0,0,6">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="84" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontFamily="{StaticResource UiFont}"
|
||||||
|
FontSize="11"
|
||||||
|
Text="节点类型" />
|
||||||
|
<TextBox
|
||||||
|
Grid.Column="1"
|
||||||
|
Height="26"
|
||||||
|
Padding="6,3"
|
||||||
|
BorderBrush="#CFCFCF"
|
||||||
|
BorderThickness="1"
|
||||||
|
FontFamily="{StaticResource UiFont}"
|
||||||
|
FontSize="11"
|
||||||
|
IsReadOnly="True"
|
||||||
|
Text="{Binding SelectedNode.NodeTypeDisplay}" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid Margin="0,0,0,6" Visibility="{Binding SelectedNode.IsMotionSnapshotNode, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="84" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontFamily="{StaticResource UiFont}"
|
||||||
|
FontSize="11"
|
||||||
|
Text="Dist" />
|
||||||
|
<TextBox
|
||||||
|
Grid.Column="1"
|
||||||
|
Height="26"
|
||||||
|
Padding="6,3"
|
||||||
|
BorderBrush="#CFCFCF"
|
||||||
|
BorderThickness="1"
|
||||||
|
FontFamily="{StaticResource UiFont}"
|
||||||
|
FontSize="11"
|
||||||
|
Text="{Binding SelectedNode.Dist, UpdateSourceTrigger=LostFocus}" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid Margin="0,0,0,6" Visibility="{Binding SelectedNode.IsReferencePoint, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="84" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontFamily="{StaticResource UiFont}"
|
||||||
|
FontSize="11"
|
||||||
|
Text="标准差" />
|
||||||
|
<TextBox
|
||||||
|
Grid.Column="1"
|
||||||
|
Height="26"
|
||||||
|
Padding="6,3"
|
||||||
|
BorderBrush="#CFCFCF"
|
||||||
|
BorderThickness="1"
|
||||||
|
FontFamily="{StaticResource UiFont}"
|
||||||
|
FontSize="11"
|
||||||
|
Text="{Binding SelectedNode.Current, UpdateSourceTrigger=LostFocus}" />
|
||||||
|
</Grid>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<Border
|
||||||
|
Grid.Row="6"
|
||||||
|
Padding="8,4"
|
||||||
|
Background="{StaticResource HeaderBg}"
|
||||||
|
BorderBrush="{StaticResource SeparatorBrush}"
|
||||||
|
BorderThickness="0,1,0,0">
|
||||||
|
<TextBlock
|
||||||
|
FontFamily="{StaticResource UiFont}"
|
||||||
|
FontSize="10.5"
|
||||||
|
Foreground="#555555"
|
||||||
|
Text="Status: 编辑界面已更新为紧凑布局" />
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
Reference in New Issue
Block a user