Files
2025-07-28 09:52:29 +02:00

138 lines
4.5 KiB
C#

using System.Collections.ObjectModel;
using Microsoft.VisualBasic.Logging;
using System.Drawing.Drawing2D;
using OpenCvSharp.Extensions;
using VisionBuilder.UI.Common.ViewModel;
using VisionBuilder.UI.Common.ViewModel.Classes;
using System.Collections.Specialized;
namespace VisionBuilder.UI.Windows.Components
{
public partial class ErrorPreview : UserControl
{
private ErrorsVM _errorPreviewVM;
// Keep track of subscription to avoid duplicate handlers
private ObservableCollection<ErrorData> _subscribedErrors;
public void SetViewModel(ErrorsVM errorPreviewVm)
{
// Unsubscribe from previous Errors collection if needed
if (_subscribedErrors != null)
_subscribedErrors.CollectionChanged -= Errors_CollectionChanged;
_errorPreviewVM = errorPreviewVm;
if (_errorPreviewVM != null)
{
_subscribedErrors = _errorPreviewVM.Errors;
_subscribedErrors.CollectionChanged += Errors_CollectionChanged;
// Initial sync: clear and add all
flowLayoutPanel1.Controls.Clear();
foreach (var error in _subscribedErrors)
{
AddErrorPreviewInternal(error);
}
}
}
public ErrorPreview()
{
InitializeComponent();
}
private Font _numberedFont = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Regular);
private void AddErrorPreviewInternal(ErrorData errorData)
{
var pb = new PictureBox();
var width = 293 / 1.6f;
var height = 220 / 1.6f;
pb.Size = new Size((int)width, (int)height + 20);
pb.SizeMode = PictureBoxSizeMode.Zoom;
pb.Margin = new Padding(5,0,5,5);
var numberedImage = new Bitmap((int)width, (int)height + 20);
var text = errorData.Title;
using (Graphics g = Graphics.FromImage(numberedImage))
{
g.Clear(Color.White);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
try
{
g.DrawImage(errorData.ImageAnalysis.ToBitmap(), 0, 0, width, height);
}
catch (Exception ex)
{
}
var measure = g.MeasureString(text, _numberedFont);
g.TranslateTransform(width / 2 - measure.Width / 2, height);
g.DrawString(text, _numberedFont, Brushes.Black, 0, 0);
}
pb.Image = numberedImage;
pb.SizeMode = PictureBoxSizeMode.Zoom;
pb.Cursor = Cursors.Hand;
pb.Click += (sender, args) =>
{
_errorPreviewVM.ShowImage(errorData);
};
var tag = (errorData, text);
pb.Tag = tag;
flowLayoutPanel1.Controls.Add(pb);
flowLayoutPanel1.Controls.SetChildIndex(pb, 0);
try
{
flowLayoutPanel1.Refresh();
}
catch
{
}
}
private void Errors_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (InvokeRequired)
{
BeginInvoke(new NotifyCollectionChangedEventHandler(Errors_CollectionChanged), sender, e);
return;
}
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (ErrorData newError in e.NewItems)
{
AddErrorPreviewInternal(newError);
}
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
foreach (ErrorData oldError in e.OldItems)
{
// Remove the PictureBox whose Tag contains the oldError
foreach (Control ctrl in flowLayoutPanel1.Controls)
{
if (ctrl is PictureBox pb && pb.Tag is ValueTuple<ErrorData, string> tag && tag.Item1 == oldError)
{
flowLayoutPanel1.Controls.Remove(pb);
pb.Dispose();
break;
}
}
}
}
else if (e.Action == NotifyCollectionChangedAction.Reset)
{
flowLayoutPanel1.Controls.Clear();
}
}
}
}