From ed0fe92cbe1224a62a0ebd13931a1775b1236314 Mon Sep 17 00:00:00 2001 From: QI Mingxuan Date: Mon, 18 May 2026 14:41:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A2=E6=B5=8B=E5=99=A8=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E5=A2=9E=E5=8A=A0=E5=9B=BE=E5=83=8F=E7=81=B0?= =?UTF-8?q?=E5=BA=A6=E7=9B=B4=E6=96=B9=E5=9B=BE=EF=BC=8C=E7=94=A8=E4=BA=8E?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=AE=9E=E6=97=B6=E9=87=87=E9=9B=86=E5=9B=BE?= =?UTF-8?q?=E5=83=8F=E7=9A=84=E7=81=B0=E5=BA=A6=E4=BF=A1=E6=81=AF=EF=BC=8C?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=9B=BE=E5=83=8F=E7=81=B0=E5=BA=A6=E7=9B=B4?= =?UTF-8?q?=E6=96=B9=E5=9B=BE=E7=9A=84=E6=98=BE=E7=A4=BA=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=EF=BC=88=E6=97=A0=E5=9B=BE=E5=83=8F=E6=8F=90=E7=A4=BA=EF=BC=89?= =?UTF-8?q?=E5=92=8C=E4=BC=98=E5=8C=96=E8=B5=84=E6=BA=90=E9=87=8A=E6=94=BE?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ImageHistogram/ImageHistogramControl.xaml | 15 +++++ .../ImageHistogramControl.xaml.cs | 23 ++++++- XP.Common/Resources/Resources.en-US.resx | 4 ++ XP.Common/Resources/Resources.resx | 4 ++ XP.Common/Resources/Resources.zh-CN.resx | 4 ++ XP.Common/Resources/Resources.zh-TW.resx | 4 ++ .../Views/DetectorConfigView.xaml | 12 +++- .../Views/DetectorConfigView.xaml.cs | 67 +++++++++++++++++++ .../Views/DetectorConfigWindow.xaml | 4 +- 9 files changed, 131 insertions(+), 6 deletions(-) diff --git a/XP.Common/Controls/ImageHistogram/ImageHistogramControl.xaml b/XP.Common/Controls/ImageHistogram/ImageHistogramControl.xaml index 4000334..7d1f974 100644 --- a/XP.Common/Controls/ImageHistogram/ImageHistogramControl.xaml +++ b/XP.Common/Controls/ImageHistogram/ImageHistogramControl.xaml @@ -2,12 +2,18 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" + xmlns:loc="clr-namespace:XP.Common.Localization.Extensions" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="200" d:DesignWidth="400"> + + + + + + + + diff --git a/XP.Common/Controls/ImageHistogram/ImageHistogramControl.xaml.cs b/XP.Common/Controls/ImageHistogram/ImageHistogramControl.xaml.cs index a02cb15..ae98696 100644 --- a/XP.Common/Controls/ImageHistogram/ImageHistogramControl.xaml.cs +++ b/XP.Common/Controls/ImageHistogram/ImageHistogramControl.xaml.cs @@ -219,10 +219,24 @@ namespace XP.Common.Controls.ImageHistogram // 取消帧率限流器中的待处理任务 | Cancel pending tasks in throttler _frameThrottler.Cancel(); - // 清空图表 | Clear chart - if (_chartRenderer != null) + // 清空图表(捕获局部引用避免异步执行时为 null)| Clear chart (capture local ref to avoid null during async) + var renderer = _chartRenderer; + if (renderer != null) { - Dispatcher.InvokeAsync(() => _chartRenderer.Clear()); + Dispatcher.InvokeAsync(() => + { + try + { + renderer.Clear(); + + // 显示无数据提示 | Show no-data placeholder + NoDataPlaceholder.Visibility = Visibility.Visible; + } + catch + { + // 控件已卸载时忽略 | Ignore if control already unloaded + } + }); } } catch (Exception ex) @@ -259,6 +273,9 @@ namespace XP.Common.Controls.ImageHistogram { isLog = IsLogarithmic; _chartRenderer?.UpdateData(histogram, isLog); + + // 隐藏无数据提示 | Hide no-data placeholder + NoDataPlaceholder.Visibility = Visibility.Collapsed; } catch (Exception ex) { diff --git a/XP.Common/Resources/Resources.en-US.resx b/XP.Common/Resources/Resources.en-US.resx index 3154237..17c92be 100644 --- a/XP.Common/Resources/Resources.en-US.resx +++ b/XP.Common/Resources/Resources.en-US.resx @@ -1887,4 +1887,8 @@ Reprojection error: {1:F4} pixels Image{0}: {1:F4} pixels + + Histogram — No data + ImageHistogramControl - Placeholder text when no image data + \ No newline at end of file diff --git a/XP.Common/Resources/Resources.resx b/XP.Common/Resources/Resources.resx index 7f0cc41..81dfcef 100644 --- a/XP.Common/Resources/Resources.resx +++ b/XP.Common/Resources/Resources.resx @@ -1920,4 +1920,8 @@ 图像{0}: {1:F4} 像素 + + 直方图 — 暂无数据 + ImageHistogramControl - 无图像输入时的提示文本 | Placeholder text when no image data + \ No newline at end of file diff --git a/XP.Common/Resources/Resources.zh-CN.resx b/XP.Common/Resources/Resources.zh-CN.resx index 7dc08f9..e7ead9d 100644 --- a/XP.Common/Resources/Resources.zh-CN.resx +++ b/XP.Common/Resources/Resources.zh-CN.resx @@ -1881,4 +1881,8 @@ 图像{0}: {1:F4} 像素 + + 直方图 — 暂无数据 + ImageHistogramControl - 无图像输入时的提示文本 | Placeholder text when no image data + \ No newline at end of file diff --git a/XP.Common/Resources/Resources.zh-TW.resx b/XP.Common/Resources/Resources.zh-TW.resx index 946e1f5..630a189 100644 --- a/XP.Common/Resources/Resources.zh-TW.resx +++ b/XP.Common/Resources/Resources.zh-TW.resx @@ -1881,4 +1881,8 @@ 图像{0}: {1:F4} 像素 + + 直方圖 — 暫無資料 + ImageHistogramControl - 無圖像輸入時的提示文字 | Placeholder text when no image data + \ No newline at end of file diff --git a/XP.Hardware.Detector/Views/DetectorConfigView.xaml b/XP.Hardware.Detector/Views/DetectorConfigView.xaml index 0c7acd7..9944825 100644 --- a/XP.Hardware.Detector/Views/DetectorConfigView.xaml +++ b/XP.Hardware.Detector/Views/DetectorConfigView.xaml @@ -6,8 +6,9 @@ xmlns:prism="http://prismlibrary.com/" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" xmlns:loc="clr-namespace:XP.Common.Localization.Extensions;assembly=XP.Common" + xmlns:hist="clr-namespace:XP.Common.Controls.ImageHistogram;assembly=XP.Common" mc:Ignorable="d" - d:DesignWidth="420" d:DesignHeight="210" + d:DesignWidth="420" d:DesignHeight="360" prism:ViewModelLocator.AutoWireViewModel="True" Background="White"> @@ -22,6 +23,8 @@ + + @@ -136,5 +139,12 @@ + + + diff --git a/XP.Hardware.Detector/Views/DetectorConfigView.xaml.cs b/XP.Hardware.Detector/Views/DetectorConfigView.xaml.cs index 5485bc3..50d4eef 100644 --- a/XP.Hardware.Detector/Views/DetectorConfigView.xaml.cs +++ b/XP.Hardware.Detector/Views/DetectorConfigView.xaml.cs @@ -1,15 +1,82 @@ +using System; +using System.Windows; using System.Windows.Controls; +using Prism.Events; +using Prism.Ioc; +using XP.Hardware.Detector.Abstractions; +using XP.Hardware.Detector.Abstractions.Events; namespace XP.Hardware.Detector.Views { /// /// 面阵探测器配置视图 | Area detector configuration view + /// 订阅探测器图像采集事件,将图像数据传递给直方图控件 /// public partial class DetectorConfigView : UserControl { + private IEventAggregator _eventAggregator; + private SubscriptionToken _imageSubscriptionToken; + public DetectorConfigView() { InitializeComponent(); + Loaded += OnLoaded; + Unloaded += OnUnloaded; + } + + /// + /// 加载时订阅图像采集事件 | Subscribe to image captured event on load + /// + private void OnLoaded(object sender, RoutedEventArgs e) + { + try + { + _eventAggregator = ContainerLocator.Current?.Resolve(); + if (_eventAggregator != null) + { + _imageSubscriptionToken = _eventAggregator.GetEvent() + .Subscribe(OnImageCaptured, ThreadOption.BackgroundThread); + } + } + catch + { + // 事件聚合器不可用时静默降级 | Silent degradation when event aggregator unavailable + } + } + + /// + /// 卸载时取消订阅 | Unsubscribe on unload + /// + private void OnUnloaded(object sender, RoutedEventArgs e) + { + if (_eventAggregator != null && _imageSubscriptionToken != null) + { + _eventAggregator.GetEvent().Unsubscribe(_imageSubscriptionToken); + _imageSubscriptionToken = null; + } + } + + /// + /// 图像采集回调:将 ushort[] 转为 byte[] 后传给直方图控件 | Image captured callback + /// + private void OnImageCaptured(ImageCapturedEventArgs args) + { + if (args?.ImageData == null || args.Width == 0 || args.Height == 0) + return; + + try + { + // 将 ushort[] 转换为 little-endian byte[] | Convert ushort[] to little-endian byte[] + var rawBytes = new byte[args.ImageData.Length * 2]; + Buffer.BlockCopy(args.ImageData, 0, rawBytes, 0, rawBytes.Length); + + // 调用直方图控件更新(控件内部支持从非 UI 线程调用)| Update histogram control (supports non-UI thread calls) + HistogramControl?.UpdateImage(rawBytes, (int)args.Width, (int)args.Height, 16); + } + catch + { + // 异常不影响主流程 | Exception does not affect main flow + } } } } diff --git a/XP.Hardware.Detector/Views/DetectorConfigWindow.xaml b/XP.Hardware.Detector/Views/DetectorConfigWindow.xaml index 500ec99..2532120 100644 --- a/XP.Hardware.Detector/Views/DetectorConfigWindow.xaml +++ b/XP.Hardware.Detector/Views/DetectorConfigWindow.xaml @@ -4,8 +4,8 @@ xmlns:loc="clr-namespace:XP.Common.Localization.Extensions;assembly=XP.Common" xmlns:detectorViews="clr-namespace:XP.Hardware.Detector.Views" Title="{loc:Localization Detector_ConfigWindowTitle}" - Height="230" Width="400" - MinHeight="230" MinWidth="360" + Height="420" Width="400" + MinHeight="380" MinWidth="360" WindowStartupLocation="CenterOwner" ResizeMode="CanResize">