Files
XplorePlane/XP.ImageProcessing.RoiControl/PolygonPointsBehavior.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

94 lines
3.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
namespace XP.ImageProcessing.RoiControl
{
/// <summary>
/// 多边形Points附加行为,支持ObservableCollection绑定
/// </summary>
public static class PolygonPointsBehavior
{
private static readonly Dictionary<Polygon, ObservableCollection<Point>> _attachedCollections
= new Dictionary<Polygon, ObservableCollection<Point>>();
public static ObservableCollection<Point> GetPointsSource(DependencyObject obj)
{
return (ObservableCollection<Point>)obj.GetValue(PointsSourceProperty);
}
public static void SetPointsSource(DependencyObject obj, ObservableCollection<Point> value)
{
obj.SetValue(PointsSourceProperty, value);
}
public static readonly DependencyProperty PointsSourceProperty =
DependencyProperty.RegisterAttached(
"PointsSource",
typeof(ObservableCollection<Point>),
typeof(PolygonPointsBehavior),
new PropertyMetadata(null, OnPointsSourceChanged));
private static void OnPointsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is Polygon polygon))
return;
// 清理旧的订阅
if (e.OldValue is ObservableCollection<Point> oldCollection)
{
oldCollection.CollectionChanged -= GetCollectionChangedHandler(polygon);
_attachedCollections.Remove(polygon);
}
// 设置新的订阅
if (e.NewValue is ObservableCollection<Point> newCollection)
{
// 初始化Points
UpdatePolygonPoints(polygon, newCollection);
// 监听集合变化
NotifyCollectionChangedEventHandler handler = (s, args) => UpdatePolygonPoints(polygon, newCollection);
newCollection.CollectionChanged += handler;
// 保存引用以便后续清理
_attachedCollections[polygon] = newCollection;
// 监听Polygon卸载事件以清理资源
polygon.Unloaded += (s, args) =>
{
if (_attachedCollections.TryGetValue(polygon, out var collection))
{
collection.CollectionChanged -= handler;
_attachedCollections.Remove(polygon);
}
};
}
}
private static NotifyCollectionChangedEventHandler GetCollectionChangedHandler(Polygon polygon)
{
return (s, args) =>
{
if (s is ObservableCollection<Point> collection)
{
UpdatePolygonPoints(polygon, collection);
}
};
}
private static void UpdatePolygonPoints(Polygon polygon, ObservableCollection<Point> points)
{
// 使用Dispatcher确保在UI线程更新
polygon.Dispatcher.BeginInvoke(new Action(() =>
{
// 创建新的PointCollection以触发UI更新
polygon.Points = new PointCollection(points);
}), System.Windows.Threading.DispatcherPriority.Render);
}
}
}