Files
XplorePlane/XP.ImageProcessing.RoiControl/ROISerializer.cs
T
XplorePlane Developer 957157ae80 fix: 修复编译错误、BGA向导预览、算子重复插入及状态栏消息
## Compilation fixes
- Fix XAML namespace reference XplorePlane.Converters → XplorePlane.Helpers (EventLogView, StateDisplayView)
- Add missing using for ISampleTypeRepository / JsonSampleTypeRepository in App.xaml.cs
- Fix ILoggerService.Warn() calls using Exception as first arg instead of message string
- Serialize CncProgram to JSON when passing to MatrixLayout (expects string, not CncProgram object)
- Suppress CS8632 nullable annotation warnings project-wide

## BGA wizard fixes
- Fix preview not showing on step 3: force RefreshBgaPreview() when entering final step
- Add step validation in CanNext() to prevent skipping to preview with invalid inputs
- Notify NextCommand.CanExecuteChanged when inputs change
- Fix RunProgress runtime binding error: set Mode=OneWay for ProgressBar.Value

## Operator toolbox: prevent duplicate insertion
- Add static OperatorTarget property for direct dispatch to active pipeline
- PipelineEditorView registers as toolbox target on load (floating window only)
- CNC page sets initial target; PipelineEditorWindow resets to CNC pipeline on close
- '+' button inserts only to the active pipeline instead of broadcasting to all subscribers

## Pipeline editor status bar messages
- Add StatusBarMessageEvent / StatusBarMessagePayload to CommonEvents.cs
- PipelineEditorViewModel publishes status on all ops (add/remove/reorder/save/execute)
- MainViewModel subscribes and displays on main window bottom status bar
- Auto-clear after timeout (3s info, 5s error)

## docs
- Merge three architecture docs into consolidated XplorePlane-架构与结构说明.md
2026-07-24 15:59:16 +08:00

133 lines
4.3 KiB
C#

using XP.ImageProcessing.RoiControl.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Windows;
namespace XP.ImageProcessing.RoiControl
{
/// <summary>
/// ROI序列化工具类
/// </summary>
public static class ROISerializer
{
private static readonly JsonSerializerOptions Options = new JsonSerializerOptions
{
WriteIndented = true,
Converters = { new PointConverter(), new ROIShapeConverter() }
};
/// <summary>
/// 保存ROI列表到JSON文件
/// </summary>
public static void SaveToFile(IEnumerable<ROIShape> roiList, string filePath)
{
var json = JsonSerializer.Serialize(roiList, Options);
File.WriteAllText(filePath, json);
}
/// <summary>
/// 从JSON文件加载ROI列表
/// </summary>
public static List<ROIShape> LoadFromFile(string filePath)
{
var json = File.ReadAllText(filePath);
return JsonSerializer.Deserialize<List<ROIShape>>(json, Options) ?? new List<ROIShape>();
}
/// <summary>
/// 序列化ROI列表为JSON字符串
/// </summary>
public static string Serialize(IEnumerable<ROIShape> roiList)
{
return JsonSerializer.Serialize(roiList, Options);
}
/// <summary>
/// 从JSON字符串反序列化ROI列表
/// </summary>
public static List<ROIShape> Deserialize(string json)
{
return JsonSerializer.Deserialize<List<ROIShape>>(json, Options) ?? new List<ROIShape>();
}
}
/// <summary>
/// Point类型的JSON转换器
/// </summary>
public class PointConverter : JsonConverter<Point>
{
public override Point Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
throw new JsonException();
double x = 0, y = 0;
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
return new Point(x, y);
if (reader.TokenType == JsonTokenType.PropertyName)
{
string? propertyName = reader.GetString();
reader.Read();
switch (propertyName)
{
case "X":
x = reader.GetDouble();
break;
case "Y":
y = reader.GetDouble();
break;
}
}
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, Point value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteNumber("X", value.X);
writer.WriteNumber("Y", value.Y);
writer.WriteEndObject();
}
}
/// <summary>
/// ROIShape多态类型的JSON转换器
/// </summary>
public class ROIShapeConverter : JsonConverter<ROIShape>
{
public override ROIShape? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
using (JsonDocument doc = JsonDocument.ParseValue(ref reader))
{
var root = doc.RootElement;
if (!root.TryGetProperty("ROIType", out var typeElement))
throw new JsonException("Missing ROIType property");
var roiType = (ROIType)typeElement.GetInt32();
return roiType switch
{
ROIType.Polygon => JsonSerializer.Deserialize<PolygonROI>(root.GetRawText(), options),
_ => throw new JsonException($"Unknown ROIType: {roiType}")
};
}
}
public override void Write(Utf8JsonWriter writer, ROIShape value, JsonSerializerOptions options)
{
JsonSerializer.Serialize(writer, value, value.GetType(), options);
}
}
}