上传界面显示

This commit is contained in:
xhm\HP 2025-03-16 13:11:08 +08:00
parent ca6476b87c
commit c49c45d6e4
62 changed files with 9095 additions and 1204 deletions

View File

@ -0,0 +1,186 @@
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using DH.Commons.Enums;
using HalconDotNet;
using OpenCvSharp;
namespace DH.Devices.Devices
{
/// <summary>
/// 视觉处理引擎1.传统视觉 2.深度学习
/// CV深度学习 四大领域
/// Image Classification 图像分类:判别图中物体是什么,比如是猫还是狗;
/// Semantic Segmentation 语义分割:对图像进行像素级分类,预测每个像素属于的类别,不区分个体;
/// Object Detection 目标检测:寻找图像中的物体并进行定位;
/// Instance Segmentation 实例分割:定位图中每个物体,并进行像素级标注,区分不同个体;
/// </summary>
public abstract class VisionEngineBase
{
public List<DetectionConfig> DetectionConfigs = new List<DetectionConfig>();
#region event
public event Action<string, List<double>> OnCropParamsOutput;
public event Action<string, Bitmap, List<IShapeElement>> OnDetectionDone;
public event Action<string> OnDetectionWarningStop;//有无检测 需要报警停机
#endregion
//public VisionEngineInitialConfigBase IConfig
//{
// get => InitialConfig as VisionEngineInitialConfigBase;
//}
// public ImageSaveHelper ImageSaveHelper { get; set; } = new ImageSaveHelper();
public string BatchNO { get; set; }
public HTuple hv_ModelID;
public abstract DetectStationResult RunInference(Mat originImgSet, string detectionId = null);
//public abstract void SaveDetectResultAsync(DetectStationResult detectResult);
public virtual void DetectionDone(string detectionId, Bitmap image, List<IShapeElement> detectionResults)
{
OnDetectionDone?.Invoke(detectionId, image, detectionResults);
}
public virtual void DetectionWarningStop(string detectionDes)
{
OnDetectionWarningStop?.Invoke(detectionDes);
}
public virtual void SaveImageAsync(string fullname, Bitmap saveMap, ImageFormat imageFormat)
{
if (saveMap != null)
{
//ImageSaveSet imageSaveSet = new ImageSaveSet()
//{
// FullName = fullname,
// SaveImage = saveMap.CopyBitmap(),
// ImageFormat = imageFormat.DeepSerializeClone()
//};
//ImageSaveHelper.ImageSaveAsync(imageSaveSet);
}
}
}
public class CamModuleXY
{
[Category("图片行")]
[DisplayName("行")]
[Description("行")]
// [TypeConverter(typeof(DeviceIdSelectorConverter<CameraBase>))]
//[TypeConverter(typeof(CollectionCountConvert))]
public int PicRows { get; set; } = 1;
[Category("图片列")]
[DisplayName("列")]
[Description("列")]
// [TypeConverter(typeof(DeviceIdSelectorConverter<CameraBase>))]
//[TypeConverter(typeof(CollectionCountConvert))]
public int PicCols { get; set; } = 1;
public string GetDisplayText()
{
return "行:" + PicRows.ToString() + "列:" + PicCols.ToString();
}
}
//public class RelatedCamera
//{
// [Category("关联相机")]
// [DisplayName("关联相机")]
// [Description("关联相机描述")]
// //[TypeConverter(typeof(DeviceIdSelectorConverter<CameraBase>))]
// //[TypeConverter(typeof(CollectionCountConvert))]
// public string CameraSourceId { get; set; } = "";
// //public string GetDisplayText()
// //{
// // using (var scope = GlobalVar.Container.BeginLifetimeScope())
// // {
// // List<IDevice> deviceList = scope.Resolve<List<IDevice>>();
// // IDevice CameraDevice = deviceList.FirstOrDefault(dev => dev.Id.Equals(CameraSourceId));
// // if (CameraDevice != null && CameraDevice is CameraBase)
// // {
// // return CameraDevice.Name;
// // }
// // }
// // return CameraSourceId;
// //}
//}
public class VisionEngineInitialConfigBase //: InitialConfigBase
{
[Category("深度学习检测配置")]
[DisplayName("检测配置集合")]
[Description("检测配置集合")]
//[TypeConverter(typeof(CollectionCountConvert))]
//[Editor(typeof(ComplexCollectionEditor<DetectionConfig>), typeof(UITypeEditor))]
public List<DetectionConfig> DetectionConfigs { get; set; } = new List<DetectionConfig>();
[Category("深度学习检测配置")]
[DisplayName("标签分类")]
[Description("标签分类,A_NG,B_TBD...")]
// [TypeConverter(typeof(CollectionCountConvert))]
// [Editor(typeof(ComplexCollectionEditor<RecongnitionLabelCategory>), typeof(UITypeEditor))]
public List<RecongnitionLabelCategory> RecongnitionLabelCategoryList { get; set; } = new List<RecongnitionLabelCategory>();
[Category("深度学习检测配置")]
[DisplayName("检测标签定义集合")]
[Description("定义检测标签的集合例如Seg/Detection模式断裂、油污、划伤...Class模式ok、ng、上面、下面、套环、正常...")]
// [TypeConverter(typeof(CollectionCountConvert))]
// [Editor(typeof(ComplexCollectionEditor<RecongnitionLabel>), typeof(UITypeEditor))]
public List<RecongnitionLabel> RecongnitionLabelList { get; set; } = new List<RecongnitionLabel>();
[Category("深度学习检测配置")]
[DisplayName("标签置信度")]
[Description("标签置信度,过滤小于改置信度的标签,大于该设置的标签才能识别")]
public float Score { get; set; } = 0.5f;
[Category("深度学习检测配置")]
[DisplayName("CPU线程数量")]
[Description("用于深度学习的CPU线程数量不要设置太大会单独占用线程影响其他程序运行")]
public int CPUNums { get; set; } = 1;
//[Category("深度学习检测配置")]
//[DisplayName("检测项GPU指定")]
//[Description("将检测项指定到GPU")]
// [TypeConverter(typeof(CollectionCountConvert))]
// [Editor(typeof(ComplexCollectionEditor<DetectionGPUConfig>), typeof(UITypeEditor))]
// public List<DetectionGPUConfig> DetectionGPUList { get; set; } = new List<DetectionGPUConfig>();
// [Category("数据保存配置")]
//[DisplayName("是否保存检测明细CSV")]
//[Description("是否保存 检测明细CSV")]
//public override bool IsEnableCSV { get; set; } = true;
//[Category("数据保存配置")]
//[DisplayName("是否保存检测图片")]
//[Description("是否保存 检测图片,总开关")]
//public bool IsSaveImage { get; set; } = true;
//[Category("数据保存配置")]
//[Description("检测图片 保存文件夹")]
//[DisplayName("检测图片保存文件夹")]
//[Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))]
//public string ImageSaveDirectory { get; set; } = "D:\\PROJECTS\\X017\\Images";
//[Category("数据保存配置")]
//[Description("检测明细CSV文件夹")]
//[DisplayName("检测明细CSV文件夹")]
//[Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))]
//public string CSVDataPath { get; set; } = "D:\\PROJECTS\\X017\\Images";
}
}

View File

@ -1,11 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Platforms>AnyCPU;X64</Platforms>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<BaseOutputPath>..\</BaseOutputPath>
<AppendTargetFrameworkToOutputPath>output</AppendTargetFrameworkToOutputPath>
<UseWindowsForms>true</UseWindowsForms>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<ItemGroup>
@ -19,6 +22,10 @@
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.10.0.20241108" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DH.Commons\DH.Commons.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="halcondotnet">
<HintPath>..\x64\Debug\halcondotnet.dll</HintPath>

View File

@ -1,17 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Platforms>AnyCPU;X64</Platforms>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<BaseOutputPath>..\</BaseOutputPath>
<AppendTargetFrameworkToOutputPath>output</AppendTargetFrameworkToOutputPath>
<UseWindowsForms>true</UseWindowsForms>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<ItemGroup>
<Folder Include="Helper\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" />
<PackageReference Include="OpenCvSharp4.Extensions" Version="4.10.0.20241108" />

View File

@ -6,7 +6,7 @@ using System.Text.RegularExpressions;
using System.Text;
using System.Drawing.Design;
namespace DH.Devices.Vision
namespace DH.Commons.Enums
{
public enum MLModelType
{
@ -25,7 +25,9 @@ namespace DH.Devices.Vision
}
public class ModelLabel
{
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string LabelId { get; set; }
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
[Category("模型标签")]
@ -37,7 +39,9 @@ namespace DH.Devices.Vision
[Category("模型标签")]
[DisplayName("模型标签")]
[Description("模型识别的标签名称")]
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string LabelName { get; set; }
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
@ -57,7 +61,9 @@ namespace DH.Devices.Vision
public class MLRequest
{
public int ImageChannels = 3;
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public Mat mImage;
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public int ResizeWidth;
public int ResizeHeight;
@ -68,11 +74,17 @@ namespace DH.Devices.Vision
//public int ImageResizeCount;
public bool IsCLDetection;
public int ProCount;
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string in_node_name;
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string out_node_name;
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string in_lable_path;
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public int ResizeImageSize;
public int segmentWidth;
@ -81,7 +93,9 @@ namespace DH.Devices.Vision
// public List<labelStringBase> OkClassTxtList;
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public List<ModelLabel> LabelNames;
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
@ -113,16 +127,22 @@ namespace DH.Devices.Vision
/// </summary>
public class DetectionResultDetail
{
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string LabelBGR { get; set; }//识别到对象的标签BGR
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public int LabelNo { get; set; } // 识别到对象的标签索引
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string LabelName { get; set; }//识别到对象的标签名称
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public double Score { get; set; }//识别目标结果的可能性、得分
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string LabelDisplay { get; set; }//识别到对象的 显示信息
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public double Area { get; set; }//识别目标的区域面积
@ -141,8 +161,12 @@ namespace DH.Devices.Vision
public class MLResult
{
public bool IsSuccess = false;
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string ResultMessage;
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public Bitmap ResultMap;
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public List<DetectionResultDetail> ResultDetails = new List<DetectionResultDetail>();
}
public class MLInit
@ -164,7 +188,11 @@ namespace DH.Devices.Vision
public bool IsGPU;
public int GPUId;
public float Score_thre;
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public MLInit(string modelFile, bool isGPU, int gpuId, float score_thre)
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
{
ModelFile = modelFile;
IsGPU = isGPU;
@ -186,20 +214,27 @@ namespace DH.Devices.Vision
}
public class DetectStationResult
{
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string Pid { get; set; }
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string TempPid { get; set; }
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
/// <summary>
/// 检测工位名称
/// </summary>
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string DetectName { get; set; }
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
/// <summary>
/// 深度学习 检测结果
/// </summary>
public List<DetectionResultDetail> DetectDetails = new List<DetectionResultDetail>();
public List<IShapeElement> DetectionResultShapes = new List<IShapeElement>();
/// <summary>
@ -237,7 +272,9 @@ namespace DH.Devices.Vision
public int StationDetectElapsed { get; set; }
public static string NormalizeAndClean(string input)
{
#pragma warning disable CS8603 // 可能返回 null 引用。
if (input == null) return null;
#pragma warning restore CS8603 // 可能返回 null 引用。
// Step 1: 标准化字符编码为 Form C (规范组合)
string normalizedString = input.Normalize(NormalizationForm.FormC);
@ -274,6 +311,184 @@ namespace DH.Devices.Vision
CameraSourceId = cameraSourceId;
}
}
public class CustomizedPoint : INotifyPropertyChanged, IComparable<CustomizedPoint>
{
private double x = 0;
[Category("坐标设置")]
[Description("X坐标")]
public double X
{
get => x;
set
{
if (value != x)
{
x = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("X"));
}
}
}
private double y = 0;
[Category("坐标设置")]
[Description("Y坐标")]
public double Y
{
get => y;
set
{
if (value != y)
{
y = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Y"));
}
}
}
public CustomizedPoint() { }
public CustomizedPoint(double x, double y)
{
X = x;
Y = y;
}
//public CustomizedPoint(Point p)
//{
// X = p.X;
// Y = p.Y;
//}
public CustomizedPoint(PointF p)
{
X = p.X;
Y = p.Y;
}
public CustomizedPoint(CustomizedPoint p)
{
X = p.X;
Y = p.Y;
}
/// <summary>
/// 根据PLC的读取数值获取点位坐标
/// </summary>
/// <param name="plcValues">0X低位 1X高位 2Y低位 3Y高位</param>
//public CustomizedPoint(List<int> plcValues)
//{
// if (plcValues == null || plcValues.Count != 4)
// return;
// var list = plcValues.ParseUnsignShortListToInt();
// X = list[0];
// Y = list[1];
//}
public event PropertyChangedEventHandler PropertyChanged;
public static List<CustomizedPoint> GetPoints(List<double> Xs, List<double> Ys)
{
List<CustomizedPoint> points = new List<CustomizedPoint>();
for (int i = 0; i < Xs.Count && i < Ys.Count; i++)
{
points.Add(new CustomizedPoint(Xs[i], Ys[i]));
}
return points;
}
public static double GetDistance(CustomizedPoint p1, CustomizedPoint p2)
{
return Math.Sqrt(Math.Pow((p1.X - p2.X), 2) + Math.Pow((p1.Y - p2.Y), 2));
}
public override string ToString()
{
return GetDisplayText();
}
public virtual string GetDisplayText()
{
return string.Format("X:{0};Y:{1}", X, Y);
}
public virtual string GetCSVHead()
{
return "X,Y";
}
public virtual string GetCSVData()
{
return X.ToString("f3") + ";" + Y.ToString("f3");
}
//public static double GetCustomizedPointDistance(CustomizedPoint startPoint, CustomizedPoint endPoint)
//{
// return Math.Sqrt(Math.Pow(endPoint.X - startPoint.X, 2) + Math.Pow(endPoint.Y - startPoint.Y, 2));
//}
public CustomizedPoint OffsetClone(CustomizedPoint point)
{
return new CustomizedPoint(X + point.X, Y + point.Y);
}
public void Offset(CustomizedPoint point)
{
X += point.X;
Y += point.Y;
}
public int CompareTo(CustomizedPoint other)
{
return (X == other.X && Y == other.Y) ? 0 : 1;
}
public override int GetHashCode()
{
//return (int)(X * 10 + Y);
return (new Tuple<double, double>(X, Y)).GetHashCode();
}
public static CustomizedPoint operator -(CustomizedPoint p1, CustomizedPoint p2)
{
return new CustomizedPoint(p1.X - p2.X, p1.Y - p2.Y);
}
public static CustomizedPoint operator +(CustomizedPoint p1, CustomizedPoint p2)
{
return new CustomizedPoint(p1.X + p2.X, p1.Y + p2.Y);
}
}
public class PreTreatParam
{
/// <summary>
/// 参数名称
/// </summary>
///
[Category("预处理参数")]
[DisplayName("参数名称")]
[Description("参数名称")]
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string Name { get; set; }
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
/// <summary>
/// 参数值
/// </summary>
///
[Category("预处理参数")]
[DisplayName("参数值")]
[Description("参数值")]
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string Value { get; set; }
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
}
public class DetectionConfig
{
@ -403,9 +618,14 @@ namespace DH.Devices.Vision
//[Category("深度学习配置")]
//[DisplayName("检测配置标签")]
//[Description("检测配置标签关联")]
//public List<DetectConfigLabel> DetectConfigLabelList { get; set; } = new List<DetectConfigLabel>();
//public List<DetectConfigLabel> DetectConfigLabelList { get; set; } = new List<DetectConfigLabel>();
[Category("显示配置")]
[DisplayName("显示位置")]
[Description("检测信息显示位置。左上角为11向右向下为正方向")]
// [TypeConverter(typeof(ComplexObjectConvert))]
// [Editor(typeof(PropertyObjectEditor), typeof(UITypeEditor))]
public CustomizedPoint ShowLocation { get; set; } = new CustomizedPoint();
public DetectionConfig()
{
@ -413,7 +633,7 @@ namespace DH.Devices.Vision
}
public DetectionConfig(string name, MLModelType modelType, string modelPath, bool isEnableGPU,string sCameraSourceId)
{
{
ModelPath = modelPath ?? string.Empty;
Name = name;
ModelType = modelType;
@ -463,7 +683,9 @@ namespace DH.Devices.Vision
[DisplayName("检测项标签")]
[Description("检测标签Id")]
//[TypeConverter(typeof(DetectionLabelConverter))]
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string LabelId { get; set; }
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
[Browsable(false)]
//public string LabelName { get => GetLabelName(); }
@ -562,11 +784,13 @@ namespace DH.Devices.Vision
[DisplayName("检测标签")]
[Description("检测标签信息")]
//[TypeConverter(typeof(DetectionLabelConverter))]
public string LabelId { get; set; }
// [Browsable(false)]
public string LabelName { get; set; }
[Category("过滤器基础信息")]
[DisplayName("是否启用过滤器")]
[Description("是否启用过滤器")]

View File

@ -5,7 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XKRS.Common.Model.SolidMotionCard
namespace DH.Commons.Enums
{

View File

@ -1,6 +1,6 @@

namespace XKRS.Common.Model
namespace DH.Commons.Enums
{
public static class GlobalVar
{

View File

@ -0,0 +1,771 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
namespace DH.Commons.Enums
{
public static class EnumHelper
{
/// <summary>
/// 根据枚举的代码名称获取枚举列表信息
/// </summary>
/// <param name="enumName"></param>
/// <returns></returns>
public static List<dynamic> GetEnumListByName(string enumName, string assemblyName = "Common.Model.Helper.EnumHelper+")
{
List<dynamic> list = new List<dynamic>();
string fullName = assemblyName + enumName;
Type t = typeof(EnumHelper).Assembly.GetType(fullName);
t.GetEnumNames().ToList().ForEach(e =>
{
int value = Convert.ToInt32(Enum.Parse(t, e));
string desc = ((Enum)Enum.Parse(t, e)).GetEnumDescription();
var item = new { Value = value, Desc = desc, Code = e };
list.Add(item);
});
return list;
}
/// <summary>
/// 获取枚举的列表信息,一般供下拉列表使用
/// </summary>
/// <param name="enumType">枚举类型</param>
/// <returns>Desc中文描述 Value整形值 Code枚举值</returns>
public static List<dynamic> GetEnumListByType(Type enumType)
{
List<dynamic> list = new List<dynamic>();
enumType.GetEnumNames().ToList().ForEach(e =>
{
int value = Convert.ToInt32(Enum.Parse(enumType, e));
string desc = ((Enum)Enum.Parse(enumType, e)).GetEnumDescription();
var item = new { Value = value, Desc = desc, Code = e };
list.Add(item);
});
return list;
}
/// <summary>
/// 获取具体某一枚举的中文描述
/// </summary>
/// <param name="enumObj"></param>
/// <returns></returns>
public static string GetEnumDescription(this Enum enumObj)
{
Type t = enumObj.GetType();
FieldInfo f = t.GetField(enumObj.ToString());
if (f == null)
{
return enumObj.ToString();
}
DescriptionAttribute attr = f.GetCustomAttribute<DescriptionAttribute>();
if (attr != null)
{
return attr.Description;
}
else
{
return enumObj.ToString();
}
}
//public static System.Windows.Media.Color GetEnumSelectedMediaColor(this Enum enumObj)
//{
// Type t = enumObj.GetType();
// FieldInfo f = t.GetField(enumObj.ToString());
// ColorSelectAttribute attr = f.GetCustomAttribute<ColorSelectAttribute>();
// if (attr != null)
// {
// var prop = typeof(System.Windows.Media.Colors).GetProperties().FirstOrDefault(p => p.Name == attr.SelectedColor);
// if (prop != null)
// {
// return (System.Windows.Media.Color)prop.GetValue(null);
// }
// }
// return System.Windows.Media.Colors.Transparent;
//}
//public static System.Drawing.Color GetEnumSelectedColor(this Enum enumObj)
//{
// Type t = enumObj.GetType();
// FieldInfo f = t.GetField(enumObj.ToString());
// ColorSelectAttribute attr = f.GetCustomAttribute<ColorSelectAttribute>();
// if (attr != null)
// {
// return System.Drawing.Color.FromName(attr.SelectedColor);
// }
// else
// {
// return System.Drawing.Color.Transparent;
// }
//}
//public static System.Drawing.Color GetEnumSelectedFontColor(this Enum enumObj)
//{
// Type t = enumObj.GetType();
// FieldInfo f = t.GetField(enumObj.ToString());
// var attr = f.GetCustomAttribute<FontColorSelectAttribute>();
// if (attr != null)
// {
// return System.Drawing.Color.FromName(attr.SelectedColor);
// }
// else
// {
// return System.Drawing.Color.Transparent;
// }
//}
//public static string GetEnumSelectedColorString(this Enum enumObj)
//{
// Type t = enumObj.GetType();
// FieldInfo f = t.GetField(enumObj.ToString());
// ColorSelectAttribute attr = f.GetCustomAttribute<ColorSelectAttribute>();
// if (attr != null)
// {
// return attr.SelectedColor;
// }
// else
// {
// return "Transparent";
// }
//}
/// <summary>
/// 当枚举牵涉到状态变换,检查现状态是否满足待转换的状态的前置状态要求
/// </summary>
/// <param name="stateToBe"></param>
/// <param name="currentState"></param>
/// <returns></returns>
//public static bool CheckPreStateValid(this Enum stateToBe, int currentState)
//{
// Type t = stateToBe.GetType();
// FieldInfo f = t.GetField(stateToBe.ToString());
// PreStateAttribute attr = f.GetCustomAttribute<PreStateAttribute>();
// if (attr == null)
// {
// return true;
// }
// else
// {
// return attr.CheckPreStateValid(currentState);
// }
//}
/// <summary>
/// 设备状态定义
/// 未初始化和异常状态无前置状态要求
/// 初始化操作前置状态必须是未初始化、关闭状态和异常状态
/// 打开前置必须是初始化和暂停
/// 关闭前置必须是打开和暂停和异常
/// 暂停前置必须是打开
/// </summary>
//public enum DeviceState
//{
// TBD = -1,
// [ColorSelect("Gray")]
// [FontColorSelect("Black")]
// [Description("未初始化")]
// DSUninit = 1,
// [ColorSelect("Gold")]
// [FontColorSelect("White")]
// [PreState(1 + 2 + 4 + 8 + 32)]
// [Description("初始化")]
// DSInit = 2,
// [ColorSelect("Lime")]
// [FontColorSelect("Black")]
// [PreState(2 + 4 + 16)]
// [Description("运行中")]
// DSOpen = 4,
// [ColorSelect("Gray")]
// [FontColorSelect("White")]
// [PreState(1 + 4 + 8 + 16 + 32)]
// [Description("关闭")]
// DSClose = 8,
// [ColorSelect("Gold")]
// [FontColorSelect("White")]
// [PreState(4 + 16)]
// [Description("暂停")]
// DSPause = 16,
// [ColorSelect("Red")]
// [FontColorSelect("White")]
// [Description("异常")]
// DSExcept = 32
//}
///// <summary>
///// 工序状态
///// </summary>
//public enum RunState
//{
// [ColorSelect("Gold")]
// [Description("空闲")]
// Idle = 1,
// [ColorSelect("Lime")]
// [Description("运行中")]
// Running = 2,
// [ColorSelect("Gray")]
// [Description("停止")]
// Stop = 3,
// [ColorSelect("Red")]
// [Description("宕机")]
// Down = 99,
//}
[Flags]
public enum DeviceAttributeType
{
[Description("设备驱动")]
Device = 1,
[Description("初始配置")]
InitialConfig = 2,
[Description("操作配置")]
OperationConfig = 4,
[Description("设备配置")]
DeviceConfig = 8,
[Description("输入配置")]
InputConfig = 16,
[Description("初始配置控件")]
InitialConfigCtrl = 32,
[Description("操作配置控件")]
OperationConfigCtrl = 64,
[Description("设备配置控件")]
DeviceConfigCtrl = 128,
[Description("输入配置控件")]
InputConfigCtrl = 256,
[Description("运行控件")]
RunCtrl = 512,
[Description("操作配置面板")]
OperationConfigPanel = 1024,
}
public enum EnableState
{
[Description("启用")]
Enabled = 0,
[Description("禁用")]
Disabled = 1,
}
public enum EnableStateFilter
{
[Description("全部")]
All = -1,
[Description("启用")]
Enabled = 0,
[Description("禁用")]
Disabled = 1,
}
public enum OutputResult
{
[Description("OK")]
OK = 1,
[Description("NG")]
NG = 2,
}
/// <summary>
/// PLC项目的值的类型
/// </summary>
public enum PLCItemType
{
[Description("布尔类型")]
Bool = 0,
[Description("整型")]
Integer = 1,
[Description("字符串型")]
String = 2,
}
/// <summary>
/// 对PLC项目的操作类型
/// </summary>
public enum PLCOpType
{
[Description("读取")]
Read = 1,
[Description("写入")]
Write = 2,
[Description("监控")]
Monitor = 4,
/// <summary>
/// 报警监控 1+8
/// </summary>
[Description("报警监控")]
WarningMonitor = 9,
/// <summary>
/// CT监控 1+16
/// </summary>
[Description("CT监控")]
CTMonitor = 17,
}
/// <summary>
/// 相机运行模式
/// </summary>
public enum CameraOpMode
{
[Description("单次拍照")]
SingleSnapShot = 1,
[Description("连续模式")]
ContinuousMode = 2,
}
/// <summary>
/// 日志类型
/// </summary>
public enum LogType
{
[Description("警告信息")]
Exception_Warning = 1,
[Description("错误信息")]
Exception_Error = 2,
[Description("致命信息")]
Exception_Fatal = 3,
[Description("设备信息")]
Info_Device = 11,
[Description("工序信息")]
Info_Process = 12,
[Description("操作信息")]
Info_Operation = 13,
[Description("用户操作信息")]
User_Operation = 21,
[Description("测量结果")]
MeasureResult = 31,
}
//public enum CameraDriverType
//{
// Halcon,
// //HalconPlugIn,
// Hik,
//}
//public enum ImageType
//{
// Bmp,
// Png,
// Jpeg,
//}
//public enum ReplyValue
//{
// OK = 1,
// NG = -1,
// IGNORE = -999,
//}
public enum PriorityDirection
{
X,
Y,
}
public enum ElementState
{
New = 1,
MouseHover = 2,
MouseInSide = 3,
Selected = 4,
Moving = 5,
Editing = 6,
Normal = 11,
Measuring = 21,
MeasureDoneOK = 22,
MeasureDoneNG = 23,
CanStretchLeft = 41,
CanStretchRight = 42,
CanStretchTop = 43,
CanStretchBottom = 44,
CanStretchLeftUpperCorner = 45,
CanStretchLeftLowerCorner = 46,
CanStretchRightUpperCorner = 47,
CanStretchRightLowerCorner = 48,
StretchingLeft = 31,
StretchingRight = 32,
StretchingTop = 33,
StretchingBottom = 34,
StretchingLeftUpperCorner = 35,
StretchingLeftLowerCorner = 36,
StretchingRightUpperCorner = 37,
StretchingRightLowerCorner = 38,
}
public enum MouseState
{
Normal = 1,
HoverElement = 2,
InSideElement = 3,
MoveElement = 4,
StretchingLeft = 11,
StretchingRight = 12,
StretchingTop = 13,
StretchingBottom = 14,
StretchingLeftUpperCorner = 15,
StretchingLeftLowerCorner = 16,
StretchingRightUpperCorner = 17,
StretchingRightLowerCorner = 18,
New = 21,
Editing = 22,
//SelectedElement = 23,
MovingAll = 31,
SelectionZone = 41,
SelectionZoneDoing = 42,
}
public enum RunMode
{
[Description("正常运行模式")]
NormalMode = 1,
[Description("调试模式")]
DebugMode = 0,
[Description("模拟模式")]
DemoMode = 2,
}
public enum MoveType
{
[Description("绝对运动")]
AbsoluteMove = 1,
[Description("机器人坐标系相对运动")]
RobotRelativeMove = 2,
[Description("相对某个基准点位的相对运动")]
BasedPointRelativeMove = 3,
[Description("回原点")]
Origin = 4,
[Description("左侧姿势")]
LeftPose = 6,
[Description("右侧姿势")]
RightPose = 5,
[Description("前侧姿势")]
FrontPose = 7,
[Description("相机坐标系相对运动")]
CameraRelativeMove = 12,
}
/// <summary>
/// 马达/运动板卡运行模式
/// </summary>
public enum MotionMode
{
/// <summary>
/// 普通点位运动
/// </summary>
[Description("普通点位运动")]
P2P = 1,
/// <summary>
/// 找正限位运动
/// </summary>
[Description("找正限位运动")]
FindPositive = 4,
/// <summary>
/// 离开正限位
/// </summary>
[Description("离开正限位")]
LeavePositive = 5,
/// <summary>
/// 找负限位运动
/// </summary>
[Description("找负限位运动")]
FindNegative = 6,
/// <summary>
/// 离开负限位
/// </summary>
[Description("离开负限位")]
LeaveNegative = 7,
/// <summary>
/// 找原点运动
/// </summary>
[Description("回原点运动")]
GoHome = 8,
/// <summary>
/// Jog模式
/// </summary>
[Description("Jog模式")]
Jog = 9,
///// <summary>
///// 读数头找原点方式
///// </summary>
//[Description("找原点inde")]
//FindOriIndex = 10,
///// <summary>
///// 插补模式
///// </summary>
//[Description("插补模式")]
//Coordinate = 11
}
/// <summary>
/// IO预定义类型 主要针对输出
/// </summary>
public enum IOPrestatement
{
[Description("自定义")]
Customized = 0,
[Description("指示灯-黄")]
Light_Yellow = 1,
[Description("指示灯-绿")]
Light_Green = 2,
[Description("指示灯-红")]
Light_Red = 3,
[Description("蜂鸣器")]
Beep = 4,
[Description("照明灯")]
Light = 5,
[Description("急停")]
EmergencyStop = 99,
}
///// <summary>
///// GTS运动板卡控制返回控制码
///// </summary>
//public enum GTSRetCode
//{
// [Description("指令执行成功")]
// GRCRunOK = 0, // 指令执行成功
// [Description("指令执行错误")]
// GRCRunErr = 1, // 指令执行错误
// [Description("icense不支持")]
// GRCNotSupport = 2, // icense不支持
// [Description("指令参数错误")]
// GRCInvalidParam = 7, // 指令参数错误
// [Description("主机和运动控制器通讯失败")]
// GRCCommErr = -1, // 主机和运动控制器通讯失败
// [Description("打开控制器失败")]
// GRCOpenErr = -6, // 打开控制器失败
// [Description("运动控制器没有响应")]
// GRCNotAck = -7 // 运动控制器没有响应
//}
/// <summary>
/// 运动板卡 IO 类型IN OUT
/// </summary>
public enum IOType
{
[Description("INPUT")]
INPUT = 0,
[Description("OUTPUT")]
OUTPUT = 1
}
public enum IOValue
{
[Description("关闭")]
FALSE = 0,
[Description("开启")]
TRUE = 1,
[Description("反转")]
REVERSE = 2,
}
/// <summary>
/// PubSubCenter事件中心的消息类型
/// </summary>
public enum PubSubCenterMessageType
{
/// <summary>
/// 运行界面更新产品下拉
/// </summary>
[Description("更新产品下拉")]
UpdateProductionCodes,
/// <summary>
/// 流程是否关闭
/// </summary>
[Description("流程是否打开")]
IsProcessOpened,
/// <summary>
/// 清除数据
/// </summary>
[Description("清除数据")]
ClearData,
/// <summary>
/// 更新批次信息
/// </summary>
[Description("更新批次信息")]
UpdateBatchNO,
/// <summary>
/// 请求批次信息
/// </summary>
[Description("更新批次信息")]
RequestBatchNO,
/// <summary>
/// 模型检测异常
/// </summary>
[Description("模型检测异常")]
MLDetectException,
}
public enum SizeEnum
{
[Description("圆形测量")]
Circle = 1,
[Description("直线测量")]
Line = 2,
[Description("线线测量")]
LineLine = 3,
[Description("线圆测量")]
LineCircle = 4,
[Description("高度测量")]
Height = 5,
}
public enum MachineState
{
Unknown = 0,
Ready = 1,
Running = 2,
Alarm = 3,
Pause = 4,
Resetting = 5,
Closing = 6,
ClearProduct = 7,
Warning = 8,
}
public enum ResultState
{
[Description("NA")]
NA = -5,
[Description("尺寸NG")]
SizeNG = -4,
[Description("检测NG")]
DetectNG = -3,
//[Description("检测不足TBD")]
// ShortageTBD = -2,
[Description("检测结果TBD")]
ResultTBD = -1,
[Description("OK")]
OK = 1,
// [Description("NG")]
// NG = 2,
//统计结果
[Description("A类NG")]
A_NG = 25,
[Description("B类NG")]
B_NG = 26,
[Description("C类NG")]
C_NG = 27,
}
public enum HikCameraType
{
[Description("HikCamera-Gige")]
Gige = 0,
[Description("HikCamera-USB")]
USB = 1
}
/// <summary>
/// 光源操作
/// </summary>
public enum LightOperation
{
[Description("打开")]
Open = 1,
[Description("关闭")]
Close = 2,
[Description("写入")]
Write = 3,
[Description("读取")]
Read = 4,
[Description("频闪")]
Flash = 5,
}
/// <summary>
/// 监听反馈数据值
/// </summary>
public enum ReturnValue
{
OKVALUE = 1,
NGVALUE = -1,
EXCEPTIONVALUE = -2,
UNAUTHORIZATION = -10,
IGNORE = -999,
}
//public enum LogLevel
//{
// [Description("详细")]
// [ColorSelect("White")]
// [FontColorSelect("Green")]
// Detail = 2,
// [Description("信息")]
// [ColorSelect("White")]
// [FontColorSelect("Dark")]
// Information = 3,
// [Description("辅助")]
// [ColorSelect("White")]
// [FontColorSelect("Blue")]
// Assist = 4,
// [Description("动作")]
// [ColorSelect("DarkGreen")]
// [FontColorSelect("Yellow")]
// Action = 5,
// [Description("错误")]
// [ColorSelect("Orange")]
// [FontColorSelect("White")]
// Error = 6,
// [Description("警报")]
// [ColorSelect("Brown")]
// [FontColorSelect("White")]
// Warning = 7,
// [Description("异常")]
// [ColorSelect("Red")]
// [FontColorSelect("White")]
// Exception = 8,
//}
}
}

View File

@ -5,7 +5,7 @@ using System.Drawing.Imaging;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
namespace XKRS.Common.Model
namespace DH.Commons.Enums
{
public class HDevEngineTool : IDisposable
{

View File

@ -9,7 +9,7 @@ using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace XKRS.Common.Model
namespace DH.Commons.Enums
{
public class OpenCVEngineTool : IDisposable
{

View File

@ -0,0 +1,123 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace DH.Commons.Enums
{
public static class UIHelper
{
public static void SetCombo(ComboBox cbo, object dataSource, string display, string value)
{
cbo.DataSource = dataSource;
cbo.DisplayMember = display;
if (!string.IsNullOrWhiteSpace(value))
{
cbo.ValueMember = value;
}
}
public static void SetCombo(ToolStripComboBox cbo, object dataSource, string display, string value)
{
cbo.ComboBox.DataSource = dataSource;
cbo.ComboBox.DisplayMember = display;
if (!string.IsNullOrWhiteSpace(value))
{
cbo.ComboBox.ValueMember = value;
}
}
public static void SetCombo(DataGridViewComboBoxColumn cbo, object dataSource, string display, string value)
{
cbo.DataSource = dataSource;
cbo.DisplayMember = display;
if (!string.IsNullOrWhiteSpace(value))
{
cbo.ValueMember = value;
}
}
}
#region DataGridView设置列头为复选框
public class DataGridViewCheckboxHeaderEventArgs : EventArgs
{
private bool checkedState = false;
public bool CheckedState
{
get { return checkedState; }
set { checkedState = value; }
}
}
public delegate void DataGridViewCheckboxHeaderEventHander(object sender, DataGridViewCheckboxHeaderEventArgs e);
public class DataGridViewCheckboxHeaderCell : DataGridViewColumnHeaderCell
{
Point checkBoxLocation;
Size checkBoxSize;
bool _checked = false;
Point _cellLocation = new Point();
System.Windows.Forms.VisualStyles.CheckBoxState _cbState = System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal;
public event DataGridViewCheckboxHeaderEventHander OnCheckBoxClicked;
        //绘制列头checkbox
        protected override void Paint(System.Drawing.Graphics graphics,
System.Drawing.Rectangle clipBounds,
System.Drawing.Rectangle cellBounds,
int rowIndex,
DataGridViewElementStates dataGridViewElementState,
object value,
object formattedValue,
string errorText,
DataGridViewCellStyle cellStyle,
DataGridViewAdvancedBorderStyle advancedBorderStyle,
DataGridViewPaintParts paintParts)
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex,
dataGridViewElementState, value,
formattedValue, errorText, cellStyle,
advancedBorderStyle, paintParts);
Point p = new Point();
Size s = CheckBoxRenderer.GetGlyphSize(graphics, System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal);
p.X = cellBounds.Location.X + (cellBounds.Width / 2) - (s.Width / 2) - 1;   //列头checkbox的X坐标
            p.Y = cellBounds.Location.Y + (cellBounds.Height / 2) - (s.Height / 2);     //列头checkbox的Y坐标
            _cellLocation = cellBounds.Location;
checkBoxLocation = p;
checkBoxSize = s;
if (_checked)
_cbState = System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal;
else
_cbState = System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal;
CheckBoxRenderer.DrawCheckBox(graphics, checkBoxLocation, _cbState);
}
        ///
        /// 点击列头checkbox单击事件
        ///
        protected override void OnMouseClick(DataGridViewCellMouseEventArgs e)
{
Point p = new Point(e.X + _cellLocation.X, e.Y + _cellLocation.Y);
if (p.X >= checkBoxLocation.X && p.X <= checkBoxLocation.X + checkBoxSize.Width
&& p.Y >= checkBoxLocation.Y && p.Y <= checkBoxLocation.Y + checkBoxSize.Height)
{
_checked = !_checked;
                //获取列头checkbox的选择状态
                DataGridViewCheckboxHeaderEventArgs ex = new DataGridViewCheckboxHeaderEventArgs();
ex.CheckedState = _checked;
object sender = new object();//此处不代表选择的列头checkbox只是作为参数传递。因为列头checkbox是绘制出来的无法获得它的实例
                if (OnCheckBoxClicked != null)
{
OnCheckBoxClicked(sender, ex);//触发单击事件
                    DataGridView.InvalidateCell(this);
}
}
base.OnMouseClick(e);
}
}
#endregion
}

View File

@ -0,0 +1,39 @@
using System;
using System.ComponentModel;
using System.Drawing;
using static DH.Commons.Enums.EnumHelper;
namespace DH.Commons.Enums
{
public interface IShapeElement : INotifyPropertyChanged, ICloneable
{
string ID { get; set; }
int Index { get; set; }
int GroupIndex { get; set; }
string Name { get; set; }
void OnMouseDown(PointF point);
void OnMouseUp(PointF point);
void OnMouseMove(PointF point);
void OnMouseDoubleClick(PointF point);
bool IsIntersect(RectangleF rect);
bool IsEnabled { get; set; }
void Draw(Graphics g);
void Translate(float x, float y);
/// <summary>
/// WPF中标识该对象是否已经加入渲染需要显示
/// </summary>
bool IsShowing { get; set; }
void Initial();
bool IsCreatedDone();
ElementState State { get; set; }
}
}

View File

@ -1,15 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<BaseOutputPath>..\</BaseOutputPath>
<AppendTargetFrameworkToOutputPath>output</AppendTargetFrameworkToOutputPath>
<UseWindowsForms>true</UseWindowsForms>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<BaseOutputPath>..\</BaseOutputPath>
<AppendTargetFrameworkToOutputPath>output</AppendTargetFrameworkToOutputPath>
<UseWindowsForms>true</UseWindowsForms>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
@ -22,4 +22,24 @@
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.10.0.20241108" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DH.Commons.Devies\DH.Commons.Devies.csproj" />
<ProjectReference Include="..\DH.Commons\DH.Commons.csproj" />
<ProjectReference Include="..\DH.UI.Model.Winform\DH.UI.Model.Winform.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="halcondotnet">
<HintPath>..\x64\Debug\halcondotnet.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,10 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Usage", "CA2200:再次引发以保留堆栈详细信息", Justification = "<挂起>", Scope = "member", Target = "~M:DH.Devices.Vision.SimboDetection.Load(DH.Devices.Vision.MLInit)~System.Boolean")]
[assembly: SuppressMessage("Usage", "CA2200:再次引发以保留堆栈详细信息", Justification = "<挂起>", Scope = "member", Target = "~M:DH.Devices.Vision.SimboInstanceSegmentation.Load(DH.Devices.Vision.MLInit)~System.Boolean")]
[assembly: SuppressMessage("Usage", "CA2200:再次引发以保留堆栈详细信息", Justification = "<挂起>", Scope = "member", Target = "~M:DH.Devices.Vision.SimboObjectDetection.Load(DH.Devices.Vision.MLInit)~System.Boolean")]

View File

@ -1,4 +1,4 @@
#define USE_MULTI_THREAD
//#define USE_MULTI_THREAD
using OpenCvSharp;
using OpenCvSharp.Extensions;
@ -13,6 +13,7 @@ using System.Threading.Tasks;
using System.Security.Cryptography.Xml;
using System.Runtime.InteropServices;
using Newtonsoft.Json;
using DH.Commons.Enums;
@ -103,14 +104,18 @@ namespace DH.Devices.Vision
// json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}";
//
Console.WriteLine("检测结果JSON" + json);
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
HYoloResult detResult = JsonConvert.DeserializeObject<HYoloResult>(json);
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
if (detResult == null)
{
return;
}
int iNum = detResult.HYolo.Count;
#pragma warning disable CS0219 // 变量已被赋值,但从未使用过它的值
int IokNum = 0;
#pragma warning restore CS0219 // 变量已被赋值,但从未使用过它的值
for (int ix = 0; ix < iNum; ix++)
{
var det = detResult.HYolo[ix];
@ -140,6 +145,7 @@ namespace DH.Devices.Vision
Mat originMat = new Mat();
Mat detectMat = new Mat();
#pragma warning disable CS0168 // 声明了变量,但从未使用过
try
{
if (req.mImage == null)
@ -228,15 +234,20 @@ namespace DH.Devices.Vision
{
originMat?.Dispose();
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
originMat = null;
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
//maskMat?.Dispose();
// maskMat = null;
detectMat?.Dispose();
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
detectMat = null;
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
// maskWeighted?.Dispose();
// maskWeighted = null;
// GC.Collect();
}
#pragma warning restore CS0168 // 声明了变量,但从未使用过
}

View File

@ -12,6 +12,7 @@ using System.Threading;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using Newtonsoft.Json;
using DH.Commons.Enums;
namespace DH.Devices.Vision
@ -126,14 +127,18 @@ namespace DH.Devices.Vision
// json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}";
//
Console.WriteLine("检测结果JSON" + json);
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
SegResult detResult = JsonConvert.DeserializeObject<SegResult>(json);
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
if (detResult == null)
{
return;
}
int iNum = detResult.SegmentResult.Count;
#pragma warning disable CS0219 // 变量已被赋值,但从未使用过它的值
int IokNum = 0;
#pragma warning restore CS0219 // 变量已被赋值,但从未使用过它的值
for (int ix = 0; ix < iNum; ix++)
{
var det = detResult.SegmentResult[ix];
@ -166,6 +171,7 @@ namespace DH.Devices.Vision
Mat originMat = new Mat();
Mat detectMat = new Mat();
#pragma warning disable CS0168 // 声明了变量,但从未使用过
try
{
if (req.mImage == null)
@ -253,11 +259,14 @@ namespace DH.Devices.Vision
{
originMat?.Dispose();
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
originMat = null;
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
// GC.Collect();
}
#pragma warning restore CS0168 // 声明了变量,但从未使用过
}
}

View File

@ -13,6 +13,7 @@ using System.Threading.Tasks;
using System.Runtime.InteropServices;
using Newtonsoft.Json;
using System.Xml;
using DH.Commons.Enums;
namespace DH.Devices.Vision
@ -135,7 +136,9 @@ namespace DH.Devices.Vision
// json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}";
//
Console.WriteLine("检测结果JSON" + json);
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
SegResult detResult = JsonConvert.DeserializeObject<SegResult>(json);
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
if (detResult == null)
{
return;
@ -173,6 +176,7 @@ namespace DH.Devices.Vision
MLResult mlResult = new MLResult();
Mat originMat=new Mat() ;
Mat detectMat= new Mat();
#pragma warning disable CS0168 // 声明了变量,但从未使用过
try
{
if (req.mImage == null)
@ -263,19 +267,24 @@ namespace DH.Devices.Vision
if (detectMat != null)
{
detectMat.Dispose();
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
detectMat = null;
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
}
if (originMat != null)
{
originMat.Dispose();
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
originMat = null;
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。
}
// GC.Collect();
}
#pragma warning restore CS0168 // 声明了变量,但从未使用过
}

View File

@ -1,4 +1,9 @@
using OpenCvSharp;
using DH.Commons.Enums;
using DH.Devices.Devices;
using DH.UI.Model.Winform;
using HalconDotNet;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@ -6,13 +11,659 @@ using System.Linq;
using System.Runtime.ExceptionServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using XKRS.UI.Model.Winform;
using static DH.Commons.Enums.EnumHelper;
using ResultState = DH.Commons.Enums.ResultState;
namespace DH.Devices.Vision
{
public class SimboVisionDriver
public class SimboVisionDriver : VisionEngineBase
{
public Dictionary<string, HDevEngineTool> HalconToolDict = new Dictionary<string, HDevEngineTool>();
public List<SimboStationMLEngineSet> SimboStationMLEngineList = new List<SimboStationMLEngineSet>();
public void Init()
{
//InitialQueue();
InitialHalconTools();
InitialSimboMLEnginesAsync();
// ImageSaveHelper.OnImageSaveExceptionRaised -= ImageSaveHelper_OnImageSaveExceptionRaised;
// ImageSaveHelper.OnImageSaveExceptionRaised += ImageSaveHelper_OnImageSaveExceptionRaised;
// base.Init();
}
//private void ImageSaveHelper_OnImageSaveExceptionRaised(DateTime dt, string msg)
//{
// LogAsync(new LogMsg(dt, LogLevel.Error, msg));
//}
public override DetectStationResult RunInference(Mat originImgSet, string detectionId = null)
{
DetectStationResult detectResult = new DetectStationResult();
DetectionConfig detectConfig = null;
//找到对应的配置
if (!string.IsNullOrWhiteSpace(detectionId))
{
detectConfig = DetectionConfigs.FirstOrDefault(u => u.Id == detectionId);
}
else
{
//detectConfig = DetectionConfigs.FirstOrDefault(u => u.CameraSourceId == camera.CameraName);
}
if (detectConfig == null)
{
//未能获得检测配置
return detectResult;
}
#region 1.
using (Mat PreTMat = originImgSet.Clone())
{
PreTreated(detectConfig, detectResult, PreTMat);
}
#endregion
if (detectResult.IsPreTreatNG)
{
detectResult.ResultState = ResultState.DetectNG;
detectResult.IsPreTreatDone = true;
detectResult.IsMLDetectDone = false;
return detectResult;
}
if (!string.IsNullOrWhiteSpace(detectConfig.ModelPath) && detectConfig.IsEnabled)
{
SimboStationMLEngineSet mlSet = null;
mlSet = SimboStationMLEngineList.FirstOrDefault(t => t.DetectionId == detectConfig.Id);
if (mlSet == null)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"异常:{detectConfig.Name}未能获取对应配置的模型检测工具");
detectResult.IsMLDetectDone = false;
//HandleDetectDone(detectResult, detectConfig);
return detectResult;
}
#region 2.
//LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} 模型检测执行");
if (!string.IsNullOrWhiteSpace(detectConfig.ModelPath))
{
Stopwatch mlWatch = new Stopwatch();
var req = new MLRequest();
//之前的检测图片都是相机存储成HImage
req.ResizeWidth = (int)detectConfig.ModelWidth;
req.ResizeHeight = (int)detectConfig.ModelHeight;
// req.LabelNames = detectConfig.GetLabelNames();
// req.Score = IIConfig.Score;
req.mImage = originImgSet.Clone();
req.in_lable_path = detectConfig.in_lable_path;
req.confThreshold = detectConfig.ModelconfThreshold;
req.iouThreshold = 0.3f;
req.segmentWidth = 320;
req.out_node_name = "output0";
switch (detectConfig.ModelType)
{
case MLModelType.ImageClassification:
break;
case MLModelType.ObjectDetection:
break;
case MLModelType.SemanticSegmentation:
break;
case MLModelType.InstanceSegmentation:
break;
case MLModelType.ObjectGPUDetection:
break;
default:
break;
}
// LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} RunInference BEGIN");
mlWatch.Start();
//20230802改成多线程推理 RunInferenceFixed
var result = mlSet.StationMLEngine.RunInference(req);
// var result = mlSet.StationMLEngine.RunInferenceFixed(req);
mlWatch.Stop();
// LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} RunInference END");
// var req = new MLRequest();
//req.mImage = inferenceImage;
//req.ResizeWidth = detectConfig.ModelWidth;
//req.ResizeHeight = detectConfig.ModelHeight;
//req.confThreshold = detectConfig.ModelconfThreshold;
//req.iouThreshold = 0.3f;
//req.out_node_name = "output0";
//req.in_lable_path = detectConfig.in_lable_path;
//Stopwatch sw = Stopwatch.StartNew();
//var result = Dectection[detectionId].RunInference(req);
//sw.Stop();
//LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理进度1.1,产品{productNumber},耗时{sw.ElapsedMilliseconds}ms");
//this.BeginInvoke(new MethodInvoker(delegate ()
//{
// // pictureBox1.Image?.Dispose(); // 释放旧图像
// // pictureBox1.Image = result.ResultMap;
// richTextBox1.AppendText($"推理成功 {productNumber}, {result.IsSuccess}相机名字{camera.CameraName} 耗时 {mlWatch.ElapsedMilliseconds}ms\n");
//}));
//req.mImage?.Dispose();
if (result == null || (result != null && !result.IsSuccess))
{
detectResult.IsMLDetectDone = false;
}
if (result != null && result.IsSuccess)
{
detectResult.DetectDetails = result.ResultDetails;
if (detectResult.DetectDetails != null)
{
}
else
{
detectResult.IsMLDetectDone = false;
}
}
}
#endregion
#region 3.
#endregion
//根据那些得分大于阈值的推理结果,判断产品是否成功
#region 4.
detectResult.DetectDetails?.ForEach(d =>
{
//当前检测项的 过滤条件
//var conditionList = detectConfig.DetectionFilterList
// .Where(u => u.IsEnabled && u.LabelName == d.LabelName)
// .GroupBy(u => u.ResultState)
// .OrderBy(u => u.Key)
// .ToList();
//当前检测项的 过滤条件
var conditionList = detectConfig.DetectionFilterList
.Where(u => u.IsEnabled && u.LabelName == d.LabelName)
.GroupBy(u => u.ResultState)
.OrderBy(u => u.Key)
.ToList();
if (conditionList.Count == 0)
{
d.FinalResult = d.LabelName.ToLower() == "ok"
? ResultState.OK
: ResultState.DetectNG;
}
else
{
d.FinalResult = detectConfig.IsMixModel
? ResultState.A_NG
: ResultState.OK;
}
foreach (IGrouping<ResultState, DetectionFilter> group in conditionList)
{
//bool b = group.ToList().Any(f =>
//{
// return f.FilterOperation(d);
//});
//if (b)
//{
// d.FinalResult = group.Key;
// break;
//}
if (group.Any(f => f.FilterOperation(d)))
{
d.FinalResult = group.Key;
break;
}
//else
//{
// d.FinalResult = d.InferenceResult = ResultState.OK;
//}
}
});
#endregion
#region 5.NG
//if (detectResult.DetectDetails?.Count > 0)
//{
// detectResult.ResultState = detectResult.DetectDetails.GroupBy(u => u.FinalResult).OrderBy(u => u.Key).First().First().FinalResult;
// detectResult.ResultLabel = detectResult.ResultLabel;
// detectResult.ResultLabelCategoryId = detectResult.ResultLabel;//TODO:设置优先级
//}
detectResult.ResultState = detectResult.DetectDetails?
.GroupBy(u => u.FinalResult)
.OrderBy(u => u.Key)
.FirstOrDefault()?.Key ?? ResultState.OK;
detectResult.ResultLabel = detectResult.ResultLabel;
detectResult.ResultLabelCategoryId = detectResult.ResultLabel;//TODO:设置优先级
#endregion
DisplayDetectionResult(detectResult, originImgSet.Clone(), detectionId);
}
return detectResult;
}
/// <summary>
/// 初始化深度学习工具
/// </summary>
private bool InitialSimboMLEnginesAsync()
{
//深度学习 模型加载
var resultOK = MLLoadModel();
return resultOK;
}
/// <summary>
/// 深度学习 模型加载
/// </summary>
/// <returns></returns>
private bool MLLoadModel()
{
bool resultOK = false;
try
{
// SimboStationMLEngineList = new List<SimboStationMLEngineSet>();
// _cameraRelatedDetectionDict = IConfig.DetectionConfigs.Select(t => t.ModelPath).Distinct().ToList();
DetectionConfigs.ForEach(dc =>
//_cameraRelatedDetectionDict.ForEach(dc =>
{
if (dc.IsEnabled && !string.IsNullOrWhiteSpace(dc.ModelPath))
{
if (dc.IsEnableGPU)
{
//if (IIConfig.IsLockGPU)
//{
//foreach (var validGPU in ValidGPUList2)
//{
// if (validGPU.DetectionIds.Contains(dc.Id))
// {
var engine = SingleMLLoadModel(dc, true, 0);
SimboStationMLEngineList.Add(engine);
// }
//}
//}
//else
//{
// foreach (var validGPU in ValidGPUList)
// {
// //var validGPU = ValidGPUList.FirstOrDefault(u => u.DetectionIds.Contains(dc.Id));
// if (validGPU.DetectionId == dc.Id)
// {
// var engine = SingleMLLoadModel(dc, true, validGPU.GPUNo);
// SimboStationMLEngineList.Add(engine);
// }
// }
//}
}
else
{
//for (int i = 0; i < IConfig.CPUNums; i++)
for (int i = 0; i < 1; i++)
{
//var engine = SingleMLLoadModel(dc, false, i);
var engine = SingleMLLoadModel(dc, false, i);
SimboStationMLEngineList.Add(engine);
}
}
}
});
resultOK = true;
}
catch (Exception ex)
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"异常:模型并发加载异常:{ex.GetExceptionMessage()}");
resultOK = false;
}
return resultOK;
}
/// <summary>
/// 单个模型加载
/// </summary>
/// <param name="dc"></param>
/// <param name="gpuNum"></param>
/// <returns></returns>
private SimboStationMLEngineSet SingleMLLoadModel(DetectionConfig dc, bool isGPU, int coreInx)
{
SimboStationMLEngineSet mLEngineSet = new SimboStationMLEngineSet();
try
{
mLEngineSet.IsUseGPU = isGPU;
if (isGPU)
{
mLEngineSet.GPUNo = coreInx;
}
else
{
mLEngineSet.CPUNo = coreInx;
}
mLEngineSet.DetectionId = dc.Id;
mLEngineSet.DetectionName = dc.Name;
if (!string.IsNullOrWhiteSpace(dc.ModelPath))
{
// 根据算法类型创建不同的实例
switch (dc.ModelType)
{
case MLModelType.ImageClassification:
break;
case MLModelType.ObjectDetection:
mLEngineSet.StationMLEngine = new SimboObjectDetection();
break;
case MLModelType.SemanticSegmentation:
break;
case MLModelType.InstanceSegmentation:
mLEngineSet.StationMLEngine = new SimboInstanceSegmentation();
break;
case MLModelType.ObjectGPUDetection:
mLEngineSet.StationMLEngine = new SimboDetection();
break;
default:
break;
}
MLInit mLInit;
string inferenceDevice = "CPU";
if (dc.IsEnableGPU)
{
inferenceDevice = "GPU";
mLInit = new MLInit(dc.ModelPath, isGPU, coreInx, dc.ModelconfThreshold);
}
else
{
mLInit = new MLInit(dc.ModelPath, "images", inferenceDevice, (int)dc.ModelWidth, (int)dc.ModelHeight);
}
bool isSuccess = mLEngineSet.StationMLEngine.Load(mLInit);
if (!isSuccess)
{
// throw new ProcessException("异常:模型加载异常", null);
}
//LogAsync(DateTime.Now, LogLevel.Information, $"模型加载成功是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}" + $" {dc.ModelType.GetEnumDescription()}:{dc.ModelPath}");
}
}
catch (Exception ex)
{
//throw new ProcessException($"异常是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}模型加载异常:{ex.GetExceptionMessage()}");
}
return mLEngineSet;
}
private void InitialHalconTools()
{
HOperatorSet.SetSystem("parallelize_operators", "true");
HOperatorSet.SetSystem("reentrant", "true");
HOperatorSet.SetSystem("global_mem_cache", "exclusive");
HalconToolDict = new Dictionary<string, HDevEngineTool>();
DetectionConfigs.ForEach(c =>
{
if (!c.IsEnabled)
return;
if (c.HalconAlgorithemPath_Pre != null)
LoadHalconTool(c.HalconAlgorithemPath_Pre);
});
}
private void LoadHalconTool(string path)
{
if (!HalconToolDict.ContainsKey(path))
{
string algorithemPath = path;
if (string.IsNullOrWhiteSpace(algorithemPath))
return;
string directoryPath = Path.GetDirectoryName(algorithemPath);
string fileName = Path.GetFileNameWithoutExtension(algorithemPath);
HDevEngineTool tool = new HDevEngineTool(directoryPath);
tool.LoadProcedure(fileName);
HalconToolDict[path] = tool;
}
}
/// <summary>
/// 预处理
/// </summary>
/// <param name="detectConfig"></param>
/// <param name="detectResult"></param>
public void PreTreated(DetectionConfig detectConfig, DetectStationResult detectResult, Mat MhImage)
{
try
{
// detectResult.VisionImageSet.DetectionOriginImage = detectResult.VisionImageSet.HImage.ConvertHImageToBitmap();
//detectResult.VisionImageSet.PreTreatedBitmap = detectResult.VisionImageSet.HImage.ConvertHImageToBitmap();
//detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.PreTreatedBitmap?.CopyBitmap();
if (!string.IsNullOrWhiteSpace(detectConfig.HalconAlgorithemPath_Pre))
{
HObject obj = OpenCVHelper.MatToHImage(MhImage);
HImage hImage = HalconHelper.ConvertHObjectToHImage(obj);
string toolKey = detectConfig.HalconAlgorithemPath_Pre;
if (!HalconToolDict.ContainsKey(toolKey))
{
// LogAsync(DateTime.Now, LogLevel.Exception, $"{detectConfig.Name}未获取预处理算法");
return;
}
//Mean_Thre Deviation_Thre Mean_standard Deviation_standard
var tool = HalconToolDict[toolKey];
////tool.InputTupleDic["Mean_Thre"] = 123;
for (int i = 0; i < detectConfig.PreTreatParams.Count; i++)
{
var param = detectConfig.PreTreatParams[i];
tool.InputTupleDic[param.Name] = double.Parse(param.Value);
}
// tool.InputTupleDic["fCricularity"] = 200;
tool.InputImageDic["INPUT_Image"] = hImage;
if (!tool.RunProcedure(out string errorMsg, out _))
{
// detectResult.PreTreatedFlag = false;
detectResult.IsPreTreatDone = false;
return;
}
var preTreatRet = tool.GetResultTuple("OUTPUT_Flag").I;
//var fRCricularity = tool.GetResultTuple("fRCricularity");
// detectResult.IsPreTreatDone = detectResult.VisionImageSet.PreTreatedFlag = preTreatRet == 1;
//detectResult.IsPreTreatDone = detectResult.VisionImageSet.PreTreatedFlag = true;
// detectResult.VisionImageSet.PreTreatedTime = DateTime.Now;
for (int i = 0; i < detectConfig.OUTPreTreatParams.Count; i++)
{
var param = detectConfig.OUTPreTreatParams[i];
tool.InputTupleDic[param.Name] = double.Parse(param.Value);
}
// 2023/10/16 新增预处理结果反馈如果预处理结果为NG直接返回
if (preTreatRet != 0)
{
detectResult.ResultState = ResultState.DetectNG;
detectResult.IsPreTreatNG = true;
// if (detectResult.VisionImageSet.PreTreatedFlag)
{
//detectResult.VisionImageSet.MLImage = tool.GetResultObject("OUTPUT_PreTreatedImage");
//DetectionResultImage
// detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.MLImage.ConvertHImageToBitmap();
}
}
else
{
// detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.MLImage.ConvertHImageToBitmap();
}
}
}
catch (Exception ex)
{
}
finally
{
//detectResult.VisionImageSet.HImage?.Dispose();
//detectResult.VisionImageSet.HImage = null;
// MhImage?.Dispose();
//MhImage = null;
}
}
/// <summary>
/// 显示检测结果
/// </summary>
/// <param name="detectResult"></param>
private void DisplayDetectionResult(DetectStationResult detectResult,Mat result,string DetectionId)
{
//结果显示上传
Task.Run(() =>
{
try
{
string displayTxt = detectResult.ResultState.ToString() + "\r\n";
if (detectResult.DetectDetails != null && detectResult.DetectDetails?.Count > 0)
{
detectResult.DetectDetails.ForEach(d =>
{
displayTxt +=
$"{d.LabelName} score:{d.Score.ToString("f2")} area:{d.Area.ToString("f2")}\r\n";
});
}
//if (detectResult.realSpecs != null && detectResult.realSpecs?.Count > 0)
//{
// detectResult.realSpecs.ForEach(d =>
// {
// displayTxt +=
// $"{d.Code} :{d.ActualValue} \r\n";
// });
//}
Bitmap resultMask=result.ToBitmap();
//if (detectResult.VisionImageSet.DetectionResultImage == null && detectResult.VisionImageSet.SizeResultImage == null)
//{
// return;
//}
//else if (detectResult.VisionImageSet.DetectionResultImage == null && detectResult.VisionImageSet.SizeResultImage != null)
//{
// detectResult.VisionImageSet.DetectionResultImage = detectResult.VisionImageSet.SizeResultImage.CopyBitmap();
// resultMask = detectResult.VisionImageSet.DetectionResultImage.CopyBitmap();
//}
//else if (detectResult.VisionImageSet.DetectionResultImage != null && detectResult.VisionImageSet.SizeResultImage != null)
//{
// Mat img1 = ConvertBitmapToMat(detectResult.VisionImageSet.SizeResultImage.CopyBitmap()); // 第一张图片,已经带框
// Mat img2 = ConvertBitmapToMat(detectResult.VisionImageSet.DetectionResultImage.CopyBitmap()); // 第二张图片,已经带框
// // 合成两张图像:可以选择叠加或拼接
// Mat resultImg = new Mat();
// Cv2.AddWeighted(img1, 0.5, img2, 0.5, 0, resultImg); // 使用加权平均法合成图像
// resultMask = resultImg.ToBitmap();
//}
//else
//{
// resultMask = detectResult.VisionImageSet.DetectionResultImage.CopyBitmap();
//}
List<IShapeElement> detectionResultShapes =
new List<IShapeElement>(detectResult.DetectionResultShapes);
DetectResultDisplay resultDisplay = new DetectResultDisplay(detectResult, resultMask, displayTxt);
detectionResultShapes.Add(resultDisplay);
List<IShapeElement> detectionResultShapesClone = new List<IShapeElement>(detectionResultShapes);
DetectionDone(DetectionId, resultMask, detectionResultShapes);
//SaveDetectResultImageAsync(detectResult);
// SaveDetectResultCSVAsync(detectResult);
}
catch (Exception ex)
{
// LogAsync(DateTime.Now, LogLevel.Exception,
// $"{Name}显示{detectResult.DetectName}检测结果异常,{ex.GetExceptionMessage()}");
}
finally
{
}
});
}
}
}

View File

@ -1,4 +1,5 @@

using DH.Commons.Enums;
using OpenCvSharp;
using System;
using System.Collections.Generic;
@ -28,7 +29,7 @@ namespace DH.Devices.Vision
MLGPUEngine.FreePredictor(Model);
}
catch (Exception e) { }
// MLEngine.FreePredictor(Model);
// MLEngine.FreePredictor(Model);
}
public void Dispose2()
{
@ -41,7 +42,7 @@ namespace DH.Devices.Vision
}
public SimboVisionMLBase()
{
// ColorMap = OpenCVHelper.GetColorMap(256);//使用3个通道
ColorMap = OpenCVHelper.GetColorMap(256);//使用3个通道
// ColorLut = new Mat(1, 256, MatType.CV_8UC3, ColorMap);
}
}
@ -55,16 +56,22 @@ namespace DH.Devices.Vision
// "rect": [421, 823, 6, 8]
// }]
//}
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public List<Result> HYolo;
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public class Result
{
public double fScore;
public int classId;
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string classname;
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
//public double area;
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public List<int> rect;
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
}
@ -72,45 +79,28 @@ namespace DH.Devices.Vision
}
public class SegResult
{
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public List<Result> SegmentResult;
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public class Result
{
public double fScore;
public int classId;
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string classname;
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public double area;
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public List<int> rect;
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
}
}
public class PreTreatParam
{
/// <summary>
/// 参数名称
/// </summary>
///
[Category("预处理参数")]
[DisplayName("参数名称")]
[Description("参数名称")]
public string Name { get; set; }
/// <summary>
/// 参数值
/// </summary>
///
[Category("预处理参数")]
[DisplayName("参数值")]
[Description("参数值")]
public string Value { get; set; }
}
public static class MLGPUEngine
{

View File

@ -22,14 +22,20 @@ namespace DH.Devices.Vision
/// <summary>
/// 检测配置ID
/// </summary>
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string DetectionId { get; set; }
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public string DetectionName { get; set; }
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
/// <summary>
/// 深度学习模型
/// </summary>
#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
public SimboVisionMLBase StationMLEngine { get; set; }
#pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
}
}

599
DH.UI.Model.Winform/Canvas.Designer.cs generated Normal file
View File

@ -0,0 +1,599 @@
namespace DH.UI.Model.Winform
{
partial class Canvas
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Canvas));
this.ctmsElements = new System.Windows.Forms.ContextMenuStrip(this.components);
this.tsmiResort = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiInitialState = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiClearStandardValue = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiClearActualValue = new System.Windows.Forms.ToolStripMenuItem();
this.ctmsKeepElements = new System.Windows.Forms.ContextMenuStrip(this.components);
this.tsmiUnselectElements = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiKeepSelected = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiKeepUnselected = new System.Windows.Forms.ToolStripMenuItem();
this.BottomToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.TopToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.RightToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.LeftToolStripPanel = new System.Windows.Forms.ToolStripPanel();
this.ContentPanel = new System.Windows.Forms.ToolStripContentPanel();
this.scMain = new System.Windows.Forms.SplitContainer();
this.tsROIs = new System.Windows.Forms.ToolStrip();
this.tsTool = new System.Windows.Forms.ToolStrip();
this.tsBtnLoadImage = new System.Windows.Forms.ToolStripButton();
this.tsBtnSaveImage = new System.Windows.Forms.ToolStripButton();
this.tsBtnSaveImageWithElements = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
this.tsBtnMapSize = new System.Windows.Forms.ToolStripButton();
this.tsBtnScreenSize = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.tsBtnModeNormal = new System.Windows.Forms.ToolStripButton();
this.tsBtnModeSelection = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.chkShowChecked = new System.Windows.Forms.CheckBox();
this.dgElements = new System.Windows.Forms.DataGridView();
this.colEnableState = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.colId = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.colIndex = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.colName = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.propGridElement = new System.Windows.Forms.PropertyGrid();
this.miniToolStrip = new System.Windows.Forms.ToolStrip();
this.stsStatus = new System.Windows.Forms.StatusStrip();
this.tsslLocation = new System.Windows.Forms.ToolStripStatusLabel();
this.tsslMouseState = new System.Windows.Forms.ToolStripStatusLabel();
this.dataGridViewCheckBoxColumn1 = new System.Windows.Forms.DataGridViewCheckBoxColumn();
this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.ctmsElements.SuspendLayout();
this.ctmsKeepElements.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.scMain)).BeginInit();
this.scMain.Panel1.SuspendLayout();
this.scMain.Panel2.SuspendLayout();
this.scMain.SuspendLayout();
this.tsTool.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dgElements)).BeginInit();
this.stsStatus.SuspendLayout();
this.SuspendLayout();
//
// ctmsElements
//
this.ctmsElements.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsmiResort,
this.tsmiInitialState,
this.tsmiClearStandardValue,
this.tsmiClearActualValue});
this.ctmsElements.Name = "ctmsElements";
this.ctmsElements.Size = new System.Drawing.Size(137, 92);
//
// tsmiResort
//
this.tsmiResort.Name = "tsmiResort";
this.tsmiResort.Size = new System.Drawing.Size(136, 22);
this.tsmiResort.Text = "重新排序";
this.tsmiResort.Click += new System.EventHandler(this.tsmiResort_Click);
//
// tsmiInitialState
//
this.tsmiInitialState.Name = "tsmiInitialState";
this.tsmiInitialState.Size = new System.Drawing.Size(136, 22);
this.tsmiInitialState.Text = "初始化";
this.tsmiInitialState.Click += new System.EventHandler(this.tsmiInitialState_Click);
//
// tsmiClearStandardValue
//
this.tsmiClearStandardValue.Name = "tsmiClearStandardValue";
this.tsmiClearStandardValue.Size = new System.Drawing.Size(136, 22);
this.tsmiClearStandardValue.Text = "清空标准值";
this.tsmiClearStandardValue.Click += new System.EventHandler(this.tsmiClearStandardValue_Click);
//
// tsmiClearActualValue
//
this.tsmiClearActualValue.Name = "tsmiClearActualValue";
this.tsmiClearActualValue.Size = new System.Drawing.Size(136, 22);
this.tsmiClearActualValue.Text = "清空测量值";
this.tsmiClearActualValue.Click += new System.EventHandler(this.tsmiClearActualValue_Click);
//
// ctmsKeepElements
//
this.ctmsKeepElements.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsmiUnselectElements,
this.tsmiKeepSelected,
this.tsmiKeepUnselected});
this.ctmsKeepElements.Name = "ctmsKeepElements";
this.ctmsKeepElements.Size = new System.Drawing.Size(173, 70);
//
// tsmiUnselectElements
//
this.tsmiUnselectElements.Name = "tsmiUnselectElements";
this.tsmiUnselectElements.Size = new System.Drawing.Size(172, 22);
this.tsmiUnselectElements.Text = "取消全部基元选择";
this.tsmiUnselectElements.Click += new System.EventHandler(this.tsmiUnselectElements_Click);
//
// tsmiKeepSelected
//
this.tsmiKeepSelected.Name = "tsmiKeepSelected";
this.tsmiKeepSelected.Size = new System.Drawing.Size(172, 22);
this.tsmiKeepSelected.Text = "保留选中的基元";
this.tsmiKeepSelected.Click += new System.EventHandler(this.tsmiKeepSelected_Click);
//
// tsmiKeepUnselected
//
this.tsmiKeepUnselected.Name = "tsmiKeepUnselected";
this.tsmiKeepUnselected.Size = new System.Drawing.Size(172, 22);
this.tsmiKeepUnselected.Text = "保留未选中的基元";
this.tsmiKeepUnselected.Click += new System.EventHandler(this.tsmiKeepUnselected_Click);
//
// BottomToolStripPanel
//
this.BottomToolStripPanel.Location = new System.Drawing.Point(0, 0);
this.BottomToolStripPanel.Name = "BottomToolStripPanel";
this.BottomToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
this.BottomToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.BottomToolStripPanel.Size = new System.Drawing.Size(0, 0);
//
// TopToolStripPanel
//
this.TopToolStripPanel.Location = new System.Drawing.Point(0, 0);
this.TopToolStripPanel.Name = "TopToolStripPanel";
this.TopToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
this.TopToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.TopToolStripPanel.Size = new System.Drawing.Size(0, 0);
//
// RightToolStripPanel
//
this.RightToolStripPanel.Location = new System.Drawing.Point(0, 0);
this.RightToolStripPanel.Name = "RightToolStripPanel";
this.RightToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
this.RightToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.RightToolStripPanel.Size = new System.Drawing.Size(0, 0);
//
// LeftToolStripPanel
//
this.LeftToolStripPanel.Location = new System.Drawing.Point(0, 0);
this.LeftToolStripPanel.Name = "LeftToolStripPanel";
this.LeftToolStripPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
this.LeftToolStripPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.LeftToolStripPanel.Size = new System.Drawing.Size(0, 0);
//
// ContentPanel
//
this.ContentPanel.Size = new System.Drawing.Size(610, 417);
//
// scMain
//
this.scMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.scMain.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
this.scMain.Location = new System.Drawing.Point(0, 0);
this.scMain.Name = "scMain";
//
// scMain.Panel1
//
this.scMain.Panel1.Controls.Add(this.tsROIs);
this.scMain.Panel1.Controls.Add(this.tsTool);
//
// scMain.Panel2
//
this.scMain.Panel2.Controls.Add(this.splitContainer1);
this.scMain.Size = new System.Drawing.Size(635, 467);
this.scMain.SplitterDistance = 399;
this.scMain.TabIndex = 4;
//
// tsROIs
//
this.tsROIs.Location = new System.Drawing.Point(29, 0);
this.tsROIs.Name = "tsROIs";
this.tsROIs.Size = new System.Drawing.Size(370, 25);
this.tsROIs.TabIndex = 2;
this.tsROIs.Text = "toolStrip1";
this.tsROIs.Visible = false;
//
// tsTool
//
this.tsTool.Dock = System.Windows.Forms.DockStyle.Left;
this.tsTool.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
this.tsTool.ImageScalingSize = new System.Drawing.Size(24, 24);
this.tsTool.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsBtnLoadImage,
this.tsBtnSaveImage,
this.tsBtnSaveImageWithElements,
this.toolStripSeparator4,
this.tsBtnMapSize,
this.tsBtnScreenSize,
this.toolStripSeparator1,
this.tsBtnModeNormal,
this.tsBtnModeSelection,
this.toolStripSeparator2});
this.tsTool.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.VerticalStackWithOverflow;
this.tsTool.Location = new System.Drawing.Point(0, 0);
this.tsTool.Margin = new System.Windows.Forms.Padding(10, 0, 0, 0);
this.tsTool.Name = "tsTool";
this.tsTool.Size = new System.Drawing.Size(29, 467);
this.tsTool.TabIndex = 1;
this.tsTool.Text = "toolStrip1";
//
// tsBtnLoadImage
//
this.tsBtnLoadImage.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.tsBtnLoadImage.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnLoadImage.Image")));
this.tsBtnLoadImage.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsBtnLoadImage.Name = "tsBtnLoadImage";
this.tsBtnLoadImage.Size = new System.Drawing.Size(26, 28);
this.tsBtnLoadImage.Text = "LoadImage";
this.tsBtnLoadImage.ToolTipText = "Load Image";
this.tsBtnLoadImage.Click += new System.EventHandler(this.tsBtnLoadImage_Click);
//
// tsBtnSaveImage
//
this.tsBtnSaveImage.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.tsBtnSaveImage.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnSaveImage.Image")));
this.tsBtnSaveImage.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsBtnSaveImage.Name = "tsBtnSaveImage";
this.tsBtnSaveImage.Size = new System.Drawing.Size(26, 28);
this.tsBtnSaveImage.Text = "SaveImage";
this.tsBtnSaveImage.Click += new System.EventHandler(this.tsBtnSaveImage_Click);
//
// tsBtnSaveImageWithElements
//
this.tsBtnSaveImageWithElements.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.tsBtnSaveImageWithElements.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnSaveImageWithElements.Image")));
this.tsBtnSaveImageWithElements.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsBtnSaveImageWithElements.Name = "tsBtnSaveImageWithElements";
this.tsBtnSaveImageWithElements.Size = new System.Drawing.Size(26, 28);
this.tsBtnSaveImageWithElements.Text = "SaveImageWithElements";
this.tsBtnSaveImageWithElements.Click += new System.EventHandler(this.tsBtnSaveImageWithElements_Click);
//
// toolStripSeparator4
//
this.toolStripSeparator4.Name = "toolStripSeparator4";
this.toolStripSeparator4.Size = new System.Drawing.Size(26, 6);
//
// tsBtnMapSize
//
this.tsBtnMapSize.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.tsBtnMapSize.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnMapSize.Image")));
this.tsBtnMapSize.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsBtnMapSize.Name = "tsBtnMapSize";
this.tsBtnMapSize.Size = new System.Drawing.Size(26, 28);
this.tsBtnMapSize.Text = "Original";
this.tsBtnMapSize.ToolTipText = "Map Size";
this.tsBtnMapSize.Click += new System.EventHandler(this.tsBtnMapSize_Click);
//
// tsBtnScreenSize
//
this.tsBtnScreenSize.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.tsBtnScreenSize.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnScreenSize.Image")));
this.tsBtnScreenSize.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsBtnScreenSize.Name = "tsBtnScreenSize";
this.tsBtnScreenSize.Size = new System.Drawing.Size(26, 28);
this.tsBtnScreenSize.Text = "toolStripButton2";
this.tsBtnScreenSize.ToolTipText = "Screen Size";
this.tsBtnScreenSize.Click += new System.EventHandler(this.tsBtnScreenSize_Click);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(26, 6);
//
// tsBtnModeNormal
//
this.tsBtnModeNormal.CheckOnClick = true;
this.tsBtnModeNormal.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.tsBtnModeNormal.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnModeNormal.Image")));
this.tsBtnModeNormal.ImageTransparentColor = System.Drawing.SystemColors.Control;
this.tsBtnModeNormal.Name = "tsBtnModeNormal";
this.tsBtnModeNormal.Size = new System.Drawing.Size(26, 28);
this.tsBtnModeNormal.Text = "Normal Mode";
this.tsBtnModeNormal.ToolTipText = "Normal Mode";
this.tsBtnModeNormal.CheckedChanged += new System.EventHandler(this.tsBtnModeNormal_CheckedChanged);
//
// tsBtnModeSelection
//
this.tsBtnModeSelection.CheckOnClick = true;
this.tsBtnModeSelection.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.tsBtnModeSelection.Image = ((System.Drawing.Image)(resources.GetObject("tsBtnModeSelection.Image")));
this.tsBtnModeSelection.ImageTransparentColor = System.Drawing.Color.Magenta;
this.tsBtnModeSelection.Name = "tsBtnModeSelection";
this.tsBtnModeSelection.Size = new System.Drawing.Size(26, 28);
this.tsBtnModeSelection.Text = "Selection Mode";
this.tsBtnModeSelection.CheckedChanged += new System.EventHandler(this.tsBtnModeNormal_CheckedChanged);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(26, 6);
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(0, 0);
this.splitContainer1.Name = "splitContainer1";
this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.chkShowChecked);
this.splitContainer1.Panel1.Controls.Add(this.dgElements);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.propGridElement);
this.splitContainer1.Size = new System.Drawing.Size(232, 467);
this.splitContainer1.SplitterDistance = 215;
this.splitContainer1.TabIndex = 2;
//
// chkShowChecked
//
this.chkShowChecked.AutoSize = true;
this.chkShowChecked.Location = new System.Drawing.Point(14, 8);
this.chkShowChecked.Name = "chkShowChecked";
this.chkShowChecked.Size = new System.Drawing.Size(110, 17);
this.chkShowChecked.TabIndex = 1;
this.chkShowChecked.Text = "仅显示选中项目";
this.chkShowChecked.UseVisualStyleBackColor = true;
this.chkShowChecked.CheckedChanged += new System.EventHandler(this.chkShowChecked_CheckedChanged);
//
// dgElements
//
this.dgElements.AllowUserToAddRows = false;
this.dgElements.AllowUserToDeleteRows = false;
this.dgElements.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.dgElements.BackgroundColor = System.Drawing.SystemColors.GradientInactiveCaption;
this.dgElements.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dgElements.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.colEnableState,
this.colId,
this.colIndex,
this.colName});
this.dgElements.Location = new System.Drawing.Point(0, 30);
this.dgElements.MultiSelect = false;
this.dgElements.Name = "dgElements";
this.dgElements.RowTemplate.Height = 23;
this.dgElements.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this.dgElements.Size = new System.Drawing.Size(232, 185);
this.dgElements.TabIndex = 0;
this.dgElements.CellMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dgElements_CellMouseDoubleClick);
this.dgElements.SelectionChanged += new System.EventHandler(this.dgElements_SelectionChanged);
//
// colEnableState
//
this.colEnableState.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.colEnableState.DataPropertyName = "IsEnabled";
this.colEnableState.FillWeight = 41.95804F;
this.colEnableState.HeaderText = "";
this.colEnableState.MinimumWidth = 30;
this.colEnableState.Name = "colEnableState";
this.colEnableState.Resizable = System.Windows.Forms.DataGridViewTriState.True;
//
// colId
//
this.colId.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.colId.DataPropertyName = "ID";
this.colId.HeaderText = "ID";
this.colId.MinimumWidth = 30;
this.colId.Name = "colId";
this.colId.ReadOnly = true;
this.colId.Visible = false;
//
// colIndex
//
this.colIndex.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
this.colIndex.DataPropertyName = "Index";
this.colIndex.HeaderText = "序号";
this.colIndex.MinimumWidth = 40;
this.colIndex.Name = "colIndex";
this.colIndex.ReadOnly = true;
this.colIndex.Width = 56;
//
// colName
//
this.colName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.colName.DataPropertyName = "Name";
this.colName.FillWeight = 158.042F;
this.colName.HeaderText = "名称";
this.colName.MinimumWidth = 60;
this.colName.Name = "colName";
this.colName.ReadOnly = true;
//
// propGridElement
//
this.propGridElement.Dock = System.Windows.Forms.DockStyle.Fill;
this.propGridElement.LargeButtons = true;
this.propGridElement.LineColor = System.Drawing.SystemColors.ControlDark;
this.propGridElement.Location = new System.Drawing.Point(0, 0);
this.propGridElement.Margin = new System.Windows.Forms.Padding(3, 3, 3, 50);
this.propGridElement.Name = "propGridElement";
this.propGridElement.Size = new System.Drawing.Size(232, 248);
this.propGridElement.TabIndex = 0;
this.propGridElement.ToolbarVisible = false;
this.propGridElement.SelectedObjectsChanged += new System.EventHandler(this.propGridElement_SelectedObjectsChanged);
//
// miniToolStrip
//
this.miniToolStrip.AccessibleName = "新项选择";
this.miniToolStrip.AccessibleRole = System.Windows.Forms.AccessibleRole.ButtonDropDown;
this.miniToolStrip.AutoSize = false;
this.miniToolStrip.CanOverflow = false;
this.miniToolStrip.Dock = System.Windows.Forms.DockStyle.None;
this.miniToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
this.miniToolStrip.ImageScalingSize = new System.Drawing.Size(24, 24);
this.miniToolStrip.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.VerticalStackWithOverflow;
this.miniToolStrip.Location = new System.Drawing.Point(0, 235);
this.miniToolStrip.Margin = new System.Windows.Forms.Padding(10, 0, 0, 0);
this.miniToolStrip.Name = "miniToolStrip";
this.miniToolStrip.Size = new System.Drawing.Size(29, 237);
this.miniToolStrip.TabIndex = 1;
//
// stsStatus
//
this.stsStatus.BackColor = System.Drawing.Color.Transparent;
this.stsStatus.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsslLocation,
this.tsslMouseState});
this.stsStatus.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.Flow;
this.stsStatus.Location = new System.Drawing.Point(0, 445);
this.stsStatus.Name = "stsStatus";
this.stsStatus.Size = new System.Drawing.Size(635, 22);
this.stsStatus.TabIndex = 0;
this.stsStatus.Text = "statusStrip1";
//
// tsslLocation
//
this.tsslLocation.Name = "tsslLocation";
this.tsslLocation.Size = new System.Drawing.Size(24, 17);
this.tsslLocation.Text = " ";
//
// tsslMouseState
//
this.tsslMouseState.Name = "tsslMouseState";
this.tsslMouseState.Size = new System.Drawing.Size(52, 17);
this.tsslMouseState.Text = " ";
//
// dataGridViewCheckBoxColumn1
//
this.dataGridViewCheckBoxColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.dataGridViewCheckBoxColumn1.DataPropertyName = "IsEnabled";
this.dataGridViewCheckBoxColumn1.FillWeight = 41.95804F;
this.dataGridViewCheckBoxColumn1.HeaderText = "";
this.dataGridViewCheckBoxColumn1.MinimumWidth = 30;
this.dataGridViewCheckBoxColumn1.Name = "dataGridViewCheckBoxColumn1";
this.dataGridViewCheckBoxColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.True;
//
// dataGridViewTextBoxColumn1
//
this.dataGridViewTextBoxColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.dataGridViewTextBoxColumn1.DataPropertyName = "Id";
this.dataGridViewTextBoxColumn1.HeaderText = "ID";
this.dataGridViewTextBoxColumn1.MinimumWidth = 30;
this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1";
this.dataGridViewTextBoxColumn1.ReadOnly = true;
this.dataGridViewTextBoxColumn1.Visible = false;
//
// dataGridViewTextBoxColumn2
//
this.dataGridViewTextBoxColumn2.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader;
this.dataGridViewTextBoxColumn2.DataPropertyName = "Index";
this.dataGridViewTextBoxColumn2.HeaderText = "序号";
this.dataGridViewTextBoxColumn2.MinimumWidth = 40;
this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2";
this.dataGridViewTextBoxColumn2.ReadOnly = true;
//
// dataGridViewTextBoxColumn3
//
this.dataGridViewTextBoxColumn3.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCellsExceptHeader;
this.dataGridViewTextBoxColumn3.DataPropertyName = "Name";
this.dataGridViewTextBoxColumn3.FillWeight = 158.042F;
this.dataGridViewTextBoxColumn3.HeaderText = "名称";
this.dataGridViewTextBoxColumn3.MinimumWidth = 80;
this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3";
this.dataGridViewTextBoxColumn3.ReadOnly = true;
//
// Canvas
//
this.Controls.Add(this.stsStatus);
this.Controls.Add(this.scMain);
this.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, ((byte)(134)));
this.Name = "Canvas";
this.Size = new System.Drawing.Size(635, 467);
this.ctmsElements.ResumeLayout(false);
this.ctmsKeepElements.ResumeLayout(false);
this.scMain.Panel1.ResumeLayout(false);
this.scMain.Panel1.PerformLayout();
this.scMain.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.scMain)).EndInit();
this.scMain.ResumeLayout(false);
this.tsTool.ResumeLayout(false);
this.tsTool.PerformLayout();
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel1.PerformLayout();
this.splitContainer1.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.dgElements)).EndInit();
this.stsStatus.ResumeLayout(false);
this.stsStatus.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1;
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2;
private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3;
private System.Windows.Forms.ContextMenuStrip ctmsElements;
private System.Windows.Forms.ToolStripMenuItem tsmiResort;
private System.Windows.Forms.ToolStripMenuItem tsmiInitialState;
private System.Windows.Forms.ToolStripMenuItem tsmiClearStandardValue;
private System.Windows.Forms.ToolStripMenuItem tsmiClearActualValue;
private System.Windows.Forms.DataGridViewCheckBoxColumn dataGridViewCheckBoxColumn1;
private System.Windows.Forms.ContextMenuStrip ctmsKeepElements;
private System.Windows.Forms.ToolStripMenuItem tsmiKeepSelected;
private System.Windows.Forms.ToolStripMenuItem tsmiKeepUnselected;
private System.Windows.Forms.ToolStripMenuItem tsmiUnselectElements;
private System.Windows.Forms.ToolStripPanel BottomToolStripPanel;
private System.Windows.Forms.ToolStripPanel TopToolStripPanel;
private System.Windows.Forms.ToolStripPanel RightToolStripPanel;
private System.Windows.Forms.ToolStripPanel LeftToolStripPanel;
private System.Windows.Forms.ToolStripContentPanel ContentPanel;
private System.Windows.Forms.SplitContainer scMain;
private System.Windows.Forms.StatusStrip stsStatus;
private System.Windows.Forms.ToolStripStatusLabel tsslLocation;
private System.Windows.Forms.ToolStripStatusLabel tsslMouseState;
private System.Windows.Forms.ToolStrip tsTool;
private System.Windows.Forms.ToolStripButton tsBtnLoadImage;
private System.Windows.Forms.ToolStripButton tsBtnSaveImage;
private System.Windows.Forms.ToolStripButton tsBtnSaveImageWithElements;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
private System.Windows.Forms.ToolStripButton tsBtnMapSize;
private System.Windows.Forms.ToolStripButton tsBtnScreenSize;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.ToolStripButton tsBtnModeNormal;
private System.Windows.Forms.ToolStripButton tsBtnModeSelection;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.CheckBox chkShowChecked;
private System.Windows.Forms.DataGridView dgElements;
private System.Windows.Forms.DataGridViewCheckBoxColumn colEnableState;
private System.Windows.Forms.DataGridViewTextBoxColumn colId;
private System.Windows.Forms.DataGridViewTextBoxColumn colIndex;
private System.Windows.Forms.DataGridViewTextBoxColumn colName;
private System.Windows.Forms.PropertyGrid propGridElement;
private System.Windows.Forms.ToolStrip miniToolStrip;
private System.Windows.Forms.ToolStrip tsROIs;
}
}

View File

@ -0,0 +1,629 @@

using DH.Commons.Enums;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static DH.Commons.Enums.EnumHelper;
namespace DH.UI.Model.Winform
{
public partial class Canvas : UserControl
{
readonly CanvasImage cvImage = new CanvasImage();
#region Grid
readonly GridCtrl gridCtrl = new GridCtrl();
private void GridValueChanged(int gridValue)
{
cvImage.GridValue = gridValue;
}
private void ShowGridChanged(bool isShowGrid)
{
cvImage.ShowGrid = isShowGrid;
}
private void GridColorChanged(Color obj)
{
cvImage.Pen_Grid.Color = obj;
}
#endregion
public Canvas()
{
InitializeComponent();
DoubleBuffered = true;
SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw |
ControlStyles.AllPaintingInWmPaint, true);
cvImage.Dock = DockStyle.Fill;
scMain.Panel1.Controls.Add(cvImage);
dgElements.AutoGenerateColumns = false;
var checkHead = new DataGridViewCheckboxHeaderCell();
checkHead.OnCheckBoxClicked += CheckHead_OnCheckBoxClicked;
dgElements.Columns[0].HeaderCell = checkHead;
dgElements.Columns[0].HeaderCell.Value = string.Empty;
Elements.CollectionChanged += Elements_CollectionChanged;
cvImage.OnMouseLocationUpdated = OnMouseLocationUpdated;
cvImage.OnMouseStateChanged += OnMouseStateChanged;
gridCtrl.IsShowGridChanged = ShowGridChanged;
gridCtrl.GridValueChanged = GridValueChanged;
gridCtrl.GridColorChanged = GridColorChanged;
gridCtrl.Padding = new Padding(0, 5, 0, 5);
tsTool.Items.Add(new GridCtrlHost(gridCtrl));
tsTool.Invalidate();
_eleCollectionChangedTimer = new System.Threading.Timer(OnElementCollectionChangedBufferTimer, null, -1, -1);
//tsmiShowStatusBar.Checked = tsmiShowToolBar.Checked = IsShowElementList = IsShowROITool = IsShowStatusBar = IsShowToolBar = false;
}
private void OnMouseStateChanged(MouseState ms)
{
if (ms != MouseState.SelectionZone && ms != MouseState.SelectionZoneDoing)
{
if (this.IsHandleCreated)
{
this.Invoke(new Action(() =>
{
tsBtnModeSelection.Checked = false;
tsBtnModeNormal.Checked = true;
}));
}
}
}
#region
public bool IsShowStatusBar
{
get => stsStatus.Visible;
set => stsStatus.Visible = value;
}
private void OnMouseLocationUpdated(Point screenPoint, PointF imagePoint, string colorDesc)
{
//await Task.Run(() => tsslLocation.Text = $"屏幕坐标X{screenPoint.X}Y{screenPoint.Y} 图片坐标X{imagePoint.X}Y{imagePoint.Y} 颜色:{colorDesc}");
this.Invoke(new Action(() =>
{
tsslLocation.Text = $"屏幕坐标X{screenPoint.X}Y{screenPoint.Y} 图片坐标X{imagePoint.X.ToString("f2")}Y{imagePoint.Y.ToString("f2")} 颜色:{colorDesc}";
}));
}
//private void MouseLocationUpdated(Point screenPoint, Point imagePoint, string colorDesc)
//{
// if (InvokeRequired)
// {
// Invoke(new Action<Point, Point, string>(MouseLocationUpdated), screenPoint, imagePoint);
// }
// else
// {
// tsslLocation.Text = $"屏幕坐标X{screenPoint.X}Y{screenPoint.Y} 图片坐标X{imagePoint.X}Y{imagePoint.Y} 颜色:{colorDesc}";
// }
//}
#endregion
#region
#region CanvasImage相关
//private MouseState mouseState = MouseState.Normal;
//public MouseState MouseState
//{
// get
// {
// return mouseState;
// }
// set
// {
// if (mouseState != value)
// {
// mouseState = value;
// tsslMouseState.Text = mouseState.ToString();
// if (mouseState >= MouseState.SelectionZone)
// {
// tsBtnModeSelection.Checked = true;
// }
// else
// {
// tsBtnModeNormal.Checked = true;
// }
// }
// }
//}
public string ImageFilePath { get; set; }
public Bitmap MAP
{
get => cvImage.MAP;
set => cvImage.MAP = value;
}
public Matrix Matrix
{
get => cvImage.Matrix;
set => cvImage.Matrix = value;
}
public MouseState MouseState
{
get => cvImage.MouseState;
set => cvImage.MouseState = value;
}
public ObservableCollection<IShapeElement> Elements
{
get => cvImage.Elements;
}
#endregion
private bool isShowElementList = false;
public bool IsShowElementList
{
get => isShowElementList;
set
{
//if (isShowElementList != value)
{
isShowElementList = value;
scMain.Panel2Collapsed = !value;
}
}
}
private bool isShowROITool = false;
public bool IsShowROITool
{
get => isShowROITool;
set
{
tsROIs.Visible = isShowROITool = value;
}
}
#endregion
#region
/// <summary>
/// 载入图片
/// </summary>
/// <param name="map"></param>
public void LoadImage(Bitmap map)
{
cvImage.LoadImage(map);
OnImageChanged?.Invoke();
}
public void Clear()
{
cvImage.Clear();
}
/// <summary>
/// 设置图片为原始尺寸
/// </summary>
public void SetMapSize()
{
cvImage.SetMapSize();
}
/// <summary>
/// 设置图片为适配尺寸
/// </summary>
public void SetScreenSize()
{
cvImage.SetScreenSize();
}
#endregion
#region
private void chkShowChecked_CheckedChanged(object sender, EventArgs e)
{
dgElements.DataSource = null;
if (Elements != null && Elements.Count > 0)
{
if (chkShowChecked.Checked)
{
dgElements.DataSource = Elements.Where(u => u.IsEnabled && u.IsShowing).ToList();
}
else
{
dgElements.DataSource = Elements.Where(u => u.IsShowing).ToList();
}
}
}
private void CheckHead_OnCheckBoxClicked(object sender, DataGridViewCheckboxHeaderEventArgs e)
{
//foreach (IShapeElement ele in Elements)
//{
// ele.IsEnabled = e.CheckedState;
//}
for (int i = 0; i < Elements.Count; i++)
{
Elements[i].IsEnabled = e.CheckedState;
}
OnElementChanged(null);
}
private void dgElements_SelectionChanged(object sender, EventArgs e)
{
if (dgElements.SelectedRows.Count > 0)
{
var ele = Elements.FirstOrDefault(u => u.ID == dgElements.SelectedRows[0].Cells["colID"].Value.ToString());
propGridElement.SelectedObject = ele;
}
}
private void dgElements_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (dgElements.SelectedRows.Count > 0)
{
var ele = Elements.FirstOrDefault(u => u.ID == dgElements.SelectedRows[0].Cells["colID"].Value.ToString());
for (int i = 0; i < Elements.Count; i++)
{
Elements[i].State = ElementState.Normal;
}
ele.State = ElementState.Selected;
SetDeviceByElement?.Invoke(ele);
Invalidate();
}
}
System.Threading.Timer _eleCollectionChangedTimer = null;
private void OnElementCollectionChangedBufferTimer(object state)
{
OnElementChanged(null);
for (int i = 0; i < Elements.Count; i++)
{
Elements[i].PropertyChanged -= Ele_PropertyChanged;
Elements[i].PropertyChanged += Ele_PropertyChanged;
}
//foreach (IShapeElement ele in Elements)
//{
// ele.PropertyChanged -= Ele_PropertyChanged;
// ele.PropertyChanged += Ele_PropertyChanged;
//}
}
private void Elements_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
//_eleCollectionChangedTimer?.Change(200, -1);
OnElementChanged(null);
for (int i = 0; i < Elements.Count; i++)
{
Elements[i].PropertyChanged -= Ele_PropertyChanged;
Elements[i].PropertyChanged += Ele_PropertyChanged;
}
}
private void Ele_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsEnabled")
{
OnElementChanged(sender as IShapeElement);
}
else
{
Invoke(new Action(() =>
{
cvImage.Invalidate();
}));
}
}
private void OnElementChanged(IShapeElement ele)
{
if (ele != null)
OnElementChangedHandle?.Invoke(ele);
if (InvokeRequired)
{
Invoke(new Action(() => OnElementChanged(ele)));
}
else
{
if (isShowElementList)
{
dgElements.DataSource = null;
if (Elements != null && Elements.Count > 0)
{
if (chkShowChecked.Checked)
{
dgElements.DataSource = Elements.ToList().Where(u => u.IsEnabled && u.IsShowing).ToList();
}
else
{
dgElements.DataSource = Elements.ToList().Where(u => u.IsShowing).ToList();
}
}
Invalidate();
}
}
}
private void propGridElement_SelectedObjectsChanged(object sender, EventArgs e)
{
propGridElement.ExpandAllGridItems();
}
#region
private void tsmiResort_Click(object sender, EventArgs e)
{
//Elements.Sort();
}
private void tsmiClearActualValue_Click(object sender, EventArgs e)
{
//foreach (IShapeElement ele in Elements)
//{
// if (ele.IsEnabled)
// {
// ele.SetActualValue(0.0);
// }
//}
}
private void tsmiInitialState_Click(object sender, EventArgs e)
{
//foreach (IShapeElement ele in Elements)
//{
// if (ele.IsEnabled)
// {
// ele.State = ElementState.Normal;
// ele.InitialMeasureResult();
// }
//}
}
private void tsmiClearStandardValue_Click(object sender, EventArgs e)
{
//foreach (IShapeElement ele in Elements)
//{
// if (ele.IsEnabled)
// {
// ele.SetStandardValue(0.0);
// }
//}
}
#endregion
#endregion
#region
private void tsmiKeepUnselected_Click(object sender, EventArgs e)
{
KeepElements(false);
}
private void tsmiKeepSelected_Click(object sender, EventArgs e)
{
KeepElements(true);
}
private void KeepElements(bool isKeepSelected)
{
for (int i = 0; i < Elements.Count; i++)
{
var ele = Elements[i];
if (ele.IsEnabled)
{
if (ele.State == ElementState.Selected)
{
ele.IsEnabled = isKeepSelected;
}
else
{
ele.IsEnabled = !isKeepSelected;
}
}
}
}
private void tsmiUnselectElements_Click(object sender, EventArgs e)
{
//if (MouseState == MouseState.SelectedElement)
//{
// MouseState = MouseState.Normal;
// //Elements.ForEach(ele =>
// foreach (IShapeElement ele in Elements)
// {
// ele.State = ElementState.Normal;
// }
// //);
//}
}
#endregion
#region
public Action<IShapeElement> SetElementDevicePara;
public Action<IShapeElement> SetDeviceByElement;
#endregion
#region
public bool IsShowToolBar
{
get => tsTool.Visible;
set => tsTool.Visible = value;
}
private void tsBtnLoadImage_Click(object sender, EventArgs e)
{
Thread InvokeThread = new Thread(new ThreadStart(OpenLoadImage));
InvokeThread.SetApartmentState(ApartmentState.STA);
InvokeThread.Start();
InvokeThread.Join();
}
private void OpenLoadImage()
{
ImageFilePath = "";
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
ImageFilePath = ofd.FileName;
LoadImage((Bitmap)Bitmap.FromFile(ImageFilePath));
}
}
private void tsBtnSaveImage_Click(object sender, EventArgs e)
{
if (MAP == null)
return;
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "JPG文件|*.jpg|BMP文件|*.bmp";
if (sfd.ShowDialog() == DialogResult.OK)
{
string filePath = sfd.FileName;
if (filePath.EndsWith("bmp"))
{
MAP.Save(filePath, ImageFormat.Bmp);
}
else
{
MAP.Save(filePath, ImageFormat.Jpeg);
}
MessageBox.Show("图片保存成功!");
}
}
private void tsBtnSaveImageWithElements_Click(object sender, EventArgs e)
{
if (MAP == null)
return;
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "JPG文件|*.jpg|BMP文件|*.bmp";
if (sfd.ShowDialog() == DialogResult.OK)
{
string filePath = sfd.FileName;
Bitmap bmp = new Bitmap(MAP.Width, MAP.Height, PixelFormat.Format32bppArgb);
//Bitmap bmp = new Bitmap(MAP.Width, MAP.Height, MAP.PixelFormat);
//Bitmap bmp = new Bitmap(MAP.Width, MAP.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.DrawImage(MAP, 0, 0);
for (int i = 0; i < Elements.Count; i++)
{
var ele = Elements[i];
if (ele.IsEnabled)
ele.Draw(g);
}
}
if (filePath.EndsWith("bmp"))
{
bmp.Save(filePath, ImageFormat.Bmp);
}
else
{
bmp.Save(filePath, ImageFormat.Jpeg);
}
MessageBox.Show("带基元图片保存成功!");
}
}
private void tsBtnMapSize_Click(object sender, EventArgs e)
{
SetMapSize();
}
private void tsBtnModeNormal_CheckedChanged(object sender, EventArgs e)
{
var btn = sender as ToolStripButton;
if (btn.Checked)
{
btn.BackColor = SystemColors.ActiveCaption;
foreach (ToolStripItem c in tsTool.Items)
{
if (c is ToolStripButton)
{
if (c.Name.StartsWith("tsBtnMode") && c.Name != btn.Name)
{
var temp = c as ToolStripButton;
temp.Checked = false;
temp.BackColor = SystemColors.Control;
}
}
}
switch (btn.Name)
{
case "tsBtnModeNormal":
MouseState = MouseState.Normal;
break;
case "tsBtnModeSelection":
MouseState = MouseState.SelectionZone;
break;
}
}
}
private void tsBtnScreenSize_Click(object sender, EventArgs e)
{
SetScreenSize();
}
#endregion
#region
//private void LoadElementTools()
//{
// var eleDict = ElementFactory.GetAllElementsInfo();
// foreach (KeyValuePair<ElementAttribute, Type> pair in eleDict)
// {
// }
//}
public void SetNewROIType(IShapeElement element)
{
cvImage.DrawTemplate = element;
}
#endregion
#region
public event Action<IShapeElement> OnElementChangedHandle;
public event Action OnImageChanged;
#endregion
#region /
private void tsmiShowToolBar_CheckedChanged(object sender, EventArgs e)
{
//IsShowToolBar = tsmiShowToolBar.Checked;
}
private void tsmiShowStatusBar_CheckedChanged(object sender, EventArgs e)
{
//IsShowStatusBar = tsmiShowStatusBar.Checked;
}
#endregion
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,33 @@
namespace DH.UI.Model.Winform
{
partial class CanvasImage
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// CanvasImage
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.Name = "CanvasImage";
this.Size = new System.Drawing.Size(575, 472);
this.ResumeLayout(false);
}
#endregion
}
}

View File

@ -0,0 +1,943 @@

using DH.Commons.Enums;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using static DH.Commons.Enums.EnumHelper;
namespace DH.UI.Model.Winform
{
public partial class CanvasImage : UserControl
{
public CanvasImage()
{
InitializeComponent();
DoubleBuffered = true;
SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.ResizeRedraw |
ControlStyles.AllPaintingInWmPaint, true);
MouseWheel += Canvas_MouseWheel;
KeyDown += OnCanvasKeyDown;
KeyPress += OnCanvasKeyPressed;
MouseDoubleClick += Canvas_MouseDoubleClick;
MouseDown += Canvas_MouseDown;
MouseMove += Canvas_MouseMove;
MouseUp += Canvas_MouseUp;
// EventRouter.ChangeElementsMouseState -= OnElementChangeMouseState;
// EventRouter.ChangeElementsMouseState += OnElementChangeMouseState;
//Elements.CollectionChanged += Elements_CollectionChanged;
}
private void Elements_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
//this.Invoke(new Action(() =>
//{
// this.Invalidate();
//}));
}
#region Event
public Action<MouseState> OnMouseStateChanged;
public Action<IShapeElement> DrawTemplateChanged = null;
public Action<Point, PointF, string> OnMouseLocationUpdated;
#endregion
private MouseState mouseState = MouseState.Normal;
public MouseState MouseState
{
get
{
return mouseState;
}
set
{
if (mouseState != value)
{
mouseState = value;
// OnMouseStateChanged?.BeginInvoke(value, null, null);
Task.Run(() => OnMouseStateChanged.Invoke(value));
}
}
}
#region
//private Bitmap map = new Bitmap(10, 10);
//public Bitmap MAP
//{
// get
// {
// _mapLoadHandler.WaitOne();
// return map;
// }
// set
// {
// map = value;
// }
//}
public Bitmap MAP { get; set; } = new Bitmap(10, 10);
public Matrix Matrix { get; set; } = new Matrix();
public ObservableCollection<IShapeElement> Elements { get; set; } = new ObservableCollection<IShapeElement>();
RectangleF _selectionRect = new RectangleF();
#endregion
#region
protected override void OnPaint(PaintEventArgs e)
{
try
{
//lock (_mapLoadLock)
//{ }
Rectangle rect = ClientRectangle;
Graphics originG = e.Graphics;
BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current;
BufferedGraphics myBuffer = currentContext.Allocate(originG, rect);
Graphics g = myBuffer.Graphics;
g.SmoothingMode = SmoothingMode.HighSpeed;
g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.Clear(BackColor);
g.MultiplyTransform(Matrix);
if (MAP != null)
{
try
{
g.DrawImage(MAP, 0, 0, MAP.Width, MAP.Height);
}
catch (Exception ex)
{
}
}
else
{
g.Clear(BackColor);
}
DrawTemplate?.Draw(g);
foreach (IShapeElement ele in Elements)
{
if (ele.IsEnabled && ele.IsShowing)
{
ele.Draw(g);
}
}
#region Grid
if (MAP != null)
{
if (ShowGrid)
{
int baseX = MAP.Width / 2;
int baseY = MAP.Height / 2;
Point[] xPoint = new Point[] { new Point(0, baseY), new Point(MAP.Width, baseY) };
Point[] yPoint = new Point[] { new Point(baseX, 0), new Point(baseX, MAP.Height) };
g.DrawLine(new Pen(Pen_Grid.Color, 5.0f), xPoint[0], xPoint[1]);
g.DrawLine(new Pen(Pen_Grid.Color, 5.0f), yPoint[0], yPoint[1]);
if (GridValue > 0)
{
int stepX = MAP.Width / 2 / (GridValue * MAP.Width / 2 / _minGridStep / 10);
int stepY = MAP.Height / 2 / (GridValue * MAP.Height / 2 / _minGridStep / 10);
//int stepX = _minGridStep + (10 - GridValue) * (MAP.Width / 2 - _minGridStep) / 10;
//int stepY = _minGridStep + (10 - GridValue) * (MAP.Height / 2 - _minGridStep) / 10;
int yPositive = baseY;
do
{
xPoint = new Point[] { new Point(0, yPositive), new Point(MAP.Width, yPositive) };
g.DrawLine(Pen_Grid, xPoint[0], xPoint[1]);
yPositive -= stepY;
} while (yPositive > 0);
int yNegative = baseY;
do
{
xPoint = new Point[] { new Point(0, yNegative), new Point(MAP.Width, yNegative) };
g.DrawLine(Pen_Grid, xPoint[0], xPoint[1]);
yNegative += stepY;
} while (yNegative < MAP.Height);
int xPositive = baseX;
do
{
yPoint = new Point[] { new Point(xPositive, 0), new Point(xPositive, MAP.Height) };
g.DrawLine(Pen_Grid, yPoint[0], yPoint[1]);
xPositive -= stepX;
} while (xPositive > 0);
int xNegative = baseX;
do
{
yPoint = new Point[] { new Point(xNegative, 0), new Point(xNegative, MAP.Height) };
g.DrawLine(Pen_Grid, yPoint[0], yPoint[1]);
xNegative += stepX;
} while (xNegative < MAP.Width);
}
}
}
#endregion
if (MouseState == MouseState.SelectionZoneDoing)
{
g.DrawRectangle(Pens.AliceBlue, _selectionRect.X, _selectionRect.Y, _selectionRect.Width, _selectionRect.Height);
g.FillRectangle(new SolidBrush(Color.FromArgb(40, 0, 0, 255)), _selectionRect);
}
myBuffer.Render(originG);
g.Dispose();
myBuffer.Dispose();//释放资源
}
catch (Exception)
{
}
}
private void halfTransparent()
{
}
#endregion
#region
private IShapeElement drawTemplate = null;
public IShapeElement DrawTemplate
{
get
{
return drawTemplate;
}
set
{
if (drawTemplate != value)
{
drawTemplate = value;
//DrawTemplateChanged?.BeginInvoke(value, null, null);
Task.Run(() => DrawTemplateChanged.Invoke(value));
if (value == null)
{
MouseState = MouseState.Normal;
return;
}
MouseState = MouseState.New;
var existed = Elements.FirstOrDefault(e => e.ID == value.ID);
if (existed != null)
{
Elements.Remove(existed);
}
//if (DrawTemplate != null)
//{
// DrawTemplate.OnDrawDone += OnElementDrawDone;
//}
}
}
}
string currentElementId = "";
string CurrentElementId
{
get
{
return currentElementId;
}
set
{
if (currentElementId != value)
{
currentElementId = value;
}
}
}
private void OnElementDrawDone(IShapeElement ele)
{
//int maxIndex = 1;
//if (Elements.Count > 0)
//{
// maxIndex = Elements.Max(u => u.Index) + 1;
//}
//ele.Index = maxIndex;
//ele.Name = maxIndex.ToString();
//#region 获取基元的设备属性,目前包括运动坐标和相机参数
//SetElementDevicePara?.Invoke(ele);
//#endregion
//Elements.Add(ele);
//DrawTemplate = DrawTemplate?.Clone() as IShapeElement;
}
#endregion
#region
private void OnElementChangeMouseState(IShapeElement ele, ElementState preState, ElementState curState)
{
if (curState != ElementState.Normal)
{
switch (curState)
{
case ElementState.New:
MouseState = MouseState.New;
break;
case ElementState.Selected:
CurrentElementId = ele.ID;
Cursor = Cursors.Default;
break;
case ElementState.Moving:
MouseState = MouseState.MoveElement;
Cursor = Cursors.NoMove2D;
break;
case ElementState.Editing:
MouseState = MouseState.Editing;
Cursor = Cursors.Hand;
break;
case ElementState.MouseInSide:
MouseState = MouseState.InSideElement;
break;
case ElementState.MouseHover:
MouseState = MouseState.HoverElement;
break;
case ElementState.CanStretchLeft:
Cursor = Cursors.SizeWE;
break;
case ElementState.StretchingLeft:
MouseState = MouseState.StretchingLeft;
Cursor = Cursors.SizeWE;
break;
case ElementState.CanStretchBottom:
Cursor = Cursors.SizeNS;
break;
case ElementState.StretchingBottom:
MouseState = MouseState.StretchingBottom;
Cursor = Cursors.SizeNS;
break;
case ElementState.CanStretchRight:
Cursor = Cursors.SizeWE;
break;
case ElementState.StretchingRight:
MouseState = MouseState.StretchingRight;
Cursor = Cursors.SizeWE;
break;
case ElementState.CanStretchTop:
Cursor = Cursors.SizeNS;
break;
case ElementState.StretchingTop:
MouseState = MouseState.StretchingTop;
Cursor = Cursors.SizeNS;
break;
case ElementState.CanStretchLeftLowerCorner:
Cursor = Cursors.SizeNESW;
break;
case ElementState.StretchingLeftLowerCorner:
MouseState = MouseState.StretchingLeftLowerCorner;
Cursor = Cursors.SizeNESW;
break;
case ElementState.CanStretchLeftUpperCorner:
Cursor = Cursors.SizeNWSE;
break;
case ElementState.StretchingLeftUpperCorner:
MouseState = MouseState.StretchingLeftUpperCorner;
Cursor = Cursors.SizeNWSE;
break;
case ElementState.CanStretchRightLowerCorner:
Cursor = Cursors.SizeNWSE;
break;
case ElementState.StretchingRightLowerCorner:
MouseState = MouseState.StretchingRightLowerCorner;
Cursor = Cursors.SizeNWSE;
break;
case ElementState.CanStretchRightUpperCorner:
Cursor = Cursors.SizeNESW;
break;
case ElementState.StretchingRightUpperCorner:
MouseState = MouseState.StretchingRightUpperCorner;
Cursor = Cursors.SizeNESW;
break;
default:
//MouseState = MouseState.Normal;
break;
}
}
else
{
if (Elements.All(e => e.State == ElementState.Normal))
{
CurrentElementId = null;
if (preState == ElementState.Selected)
{
DrawTemplate = null;
}
else if (DrawTemplate != null)
{
MouseState = MouseState.New;
return;
}
//MouseState = MouseState.Normal;
}
}
this.Invalidate();
}
#endregion
#region
private void Canvas_MouseWheel(object sender, MouseEventArgs e)
{
PointF prePoint = ToMapPoint(e.Location);
//先缩放
if (e.Delta > 0)
{
Matrix.Scale((float)1.1, (float)1.1);
}
else
{
Matrix.Scale((float)0.9, (float)0.9);
}
PointF afterPoint = ToMapPoint(e.Location);
//后平移
Matrix.Translate(afterPoint.X - prePoint.X, afterPoint.Y - prePoint.Y);
Invalidate();
}
PointF startPoint, currentPoint;
bool _isMouseBtnPressing = false;
private void Canvas_MouseDown(object sender, MouseEventArgs e)
{
PointF p = ToMapPoint(e.Location);
if (e.Button == MouseButtons.Left)
{
_isMouseBtnPressing = true;
switch (MouseState)
{
case MouseState.Normal:
startPoint = e.Location;
break;
case MouseState.StretchingLeft:
break;
case MouseState.StretchingRight:
break;
case MouseState.StretchingTop:
break;
case MouseState.StretchingBottom:
break;
case MouseState.MoveElement:
break;
case MouseState.HoverElement:
case MouseState.InSideElement:
case MouseState.New:
DrawTemplate?.OnMouseDown(p);
break;
case MouseState.Editing:
break;
case MouseState.SelectionZone:
MouseState = MouseState.SelectionZoneDoing;
startPoint = p;
break;
}
foreach (IShapeElement ele in Elements)
{
ele.OnMouseDown(p);
}
}
else if (e.Button == MouseButtons.Right)
{
if (DrawTemplate != null && DrawTemplate.State == ElementState.New && DrawTemplate.IsCreatedDone())
{
IShapeElement ele = DrawTemplate.Clone() as IShapeElement;
ele.State = ElementState.Normal;
Elements.Add(ele);
// (DrawTemplate as ElementBase).Initial();
}
}
}
private void Canvas_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left)
return;
_isMouseBtnPressing = false;
switch (MouseState)
{
case MouseState.Normal:
break;
case MouseState.HoverElement:
break;
case MouseState.InSideElement:
break;
case MouseState.StretchingLeft:
break;
case MouseState.StretchingRight:
break;
case MouseState.StretchingTop:
break;
case MouseState.StretchingBottom:
break;
case MouseState.MoveElement:
//MouseState = MouseState.SelectedElement;
break;
case MouseState.New:
break;
case MouseState.Editing:
break;
case MouseState.MovingAll:
MouseState = MouseState.Normal;
break;
case MouseState.SelectionZone:
break;
case MouseState.SelectionZoneDoing:
MouseState = MouseState.SelectionZone;
foreach (IShapeElement ele in Elements)
{
ele.State = ElementState.Normal;
if (ele.IsIntersect(_selectionRect))
{
ele.State = ElementState.Selected;
}
}
break;
}
Cursor = Cursors.Default;
if (MouseState != MouseState.SelectionZone)
{
PointF p = ToMapPoint(e.Location);
DrawTemplate?.OnMouseUp(p);
foreach (IShapeElement ele in Elements)
{
ele.OnMouseUp(p);
}
}
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
PointF p = ToMapPoint(e.Location);
switch (MouseState)
{
case MouseState.Normal:
{
if (_isMouseBtnPressing)
{
currentPoint = e.Location;
PointF p1 = ToMapPoint(startPoint);
PointF p2 = ToMapPoint(currentPoint);
Matrix.Translate(p2.X - p1.X, p2.Y - p1.Y);
startPoint = e.Location;
}
}
break;
case MouseState.StretchingLeft:
break;
case MouseState.StretchingRight:
break;
case MouseState.StretchingTop:
break;
case MouseState.StretchingBottom:
break;
case MouseState.MoveElement:
break;
case MouseState.HoverElement:
case MouseState.InSideElement:
case MouseState.New:
DrawTemplate?.OnMouseMove(p);
break;
case MouseState.Editing:
break;
case MouseState.MovingAll:
break;
case MouseState.SelectionZoneDoing:
{
currentPoint = p;
float[] x2 = new float[2] { startPoint.X, currentPoint.X };
float[] y2 = new float[2] { startPoint.Y, currentPoint.Y };
float xMin = x2.Min();
float xMax = x2.Max();
float yMin = y2.Min();
float yMax = y2.Max();
_selectionRect = new RectangleF(xMin, yMin, xMax - xMin, yMax - yMin);
}
break;
}
PointF mapPoint = ToMapPoint(e.Location);
Color color = Color.Transparent;
if (MAP != null && mapPoint.X > 0 && mapPoint.X < MAP.Width && mapPoint.Y > 0 && mapPoint.Y < MAP.Height)
{
color = MAP.GetPixel((int)mapPoint.X, (int)mapPoint.Y);
}
// OnMouseLocationUpdated?.BeginInvoke(e.Location, mapPoint, color.Name, null, null);
Task.Run(() => OnMouseLocationUpdated?.Invoke(e.Location, mapPoint, color.Name));
if (MouseState != MouseState.SelectionZoneDoing)
{
Elements.ToList().ForEach(ele => ele?.OnMouseMove(p));
}
Invalidate();
}
private void Canvas_MouseDoubleClick(object sender, MouseEventArgs e)
{
PointF p = ToMapPoint(e.Location);
if (e.Button == MouseButtons.Left)
{
switch (MouseState)
{
//case MouseState.SelectedElement:
case MouseState.HoverElement:
case MouseState.InSideElement:
case MouseState.MoveElement:
case MouseState.Normal:
//Elements.ForEach(ele =>
foreach (IShapeElement ele in Elements)
{
ele.OnMouseDoubleClick(p);
}
//);
break;
default:
break;
}
}
else
{
//if (MouseState == MouseState.SelectedElement)
{
MouseState = MouseState.Normal;
//Elements.ForEach(ele =>
foreach (IShapeElement ele in Elements)
{
ele.State = ElementState.Normal;
}
//);
}
}
}
#endregion
#region
bool _firstLoad = true;
object _mapLoadLock = new object();
ManualResetEvent _mapLoadHandler = new ManualResetEvent(true);
ManualResetEvent _mapUsingHandler = new ManualResetEvent(false);
/// <summary>
/// 载入图片
/// </summary>
/// <param name="bitmap"></param>
public void LoadImage(Bitmap bitmap)
{
if (bitmap == null)
return;
////lock (_mapLoadLock)
////_mapUsingHandler.WaitOne();
//_mapLoadHandler.Reset();
//{
// map?.Dispose();
// map = null;
// map = bitmap;
//}
//_mapLoadHandler.Set();
MAP = bitmap;
if (_firstLoad)
{
SetScreenSize();
_firstLoad = false;
}
Invalidate();
}
public void Clear()
{
MAP = null;
Elements.Clear();
Invalidate();
}
/// <summary>
/// 设置图片为原始尺寸
/// </summary>
public void SetMapSize()
{
Matrix = new Matrix();
Invalidate();
}
/// <summary>
/// 设置图片为适配尺寸
/// </summary>
public void SetScreenSize()
{
try
{
if (MAP == null)
return;
Matrix = new Matrix();
//先缩放
List<float> ratios = new List<float>() { MAP.Width / (float)Width, MAP.Height / (float)Height };
float ratio = 1 / ratios.Max();
Matrix.Scale(ratio, ratio);
//再平移
//将plMain的中心转换为图片坐标
PointF screenCenter = new PointF(Width / 2.0f, Height / 2.0f);
PointF mapPoint = ToMapPoint(screenCenter);
//目标坐标减去当前坐标
Matrix.Translate(-MAP.Width / 2.0f + mapPoint.X, -MAP.Height / 2.0f + mapPoint.Y);
Invalidate();
}
catch (Exception ex)
{
//Trace.TraceError(ex.GetExceptionMessage());
}
}
#endregion
#region
//private void DisplayMouseLocation(Point location)
//{
// string screenPoint = string.Format("屏幕坐标X{0}Y{1}", location.X, location.Y);
// Point mapPoint = ToMapPoint(location);
// string mapPointStr = string.Format("图片坐标X{0}Y{1}", mapPoint.X, mapPoint.Y);
// tsslLocation.Text = screenPoint + " " + mapPointStr;
//}
private PointF ToMapPoint(PointF p)
{
PointF[] ps = new PointF[] { p };
Matrix invertMatrix = Matrix.Clone();
invertMatrix.Invert();
invertMatrix.TransformPoints(ps);
return ps[0];
}
private Point ToScreenPoint(Point p)
{
Point[] ps = new Point[] { p };
Matrix.TransformPoints(ps);
return ps[0];
}
#endregion
#region
public void OnCanvasKeyPressed(object sender, KeyPressEventArgs e)
{
//if (e.KeyChar == 27) //Esc
//{
// //if (MouseState == MouseState.SelectedElement)
// {
// MouseState = MouseState.Normal;
// //Elements.ForEach(ele =>
// foreach (IShapeElement ele in Elements)
// {
// ele.State = ElementState.Normal;
// }
// //);
// }
//}
//Invalidate();
}
public void OnCanvasKeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete) //delete键
{
Elements.Remove(Elements.FirstOrDefault(u => u.ID == CurrentElementId));
}
if (e.KeyData == Keys.Escape) //Esc
{
if (DrawTemplate != null /*&& (DrawTemplate as ElementBase).CreatePoints.Count > 0*/)
{
DrawTemplate.Initial();
}
else
{
DrawTemplate = null;
if (MouseState != MouseState.Normal)
{
MouseState = MouseState.Normal;
}
else
{
Elements.ToList().ForEach(u => u.State = ElementState.Normal);
}
}
}
//if (e.KeyData == Keys.Up)
//{
// Elements.ToList().ForEach(u =>
// {
// if (u.State == ElementState.Selected)
// {
// u.Translate(0, -1);
// }
// });
//}
//if (e.KeyData == Keys.Down)
//{
// Elements.ToList().ForEach(u =>
// {
// if (u.State == ElementState.Selected)
// {
// u.Translate(0, 1);
// }
// });
//}
//if (e.KeyData == Keys.Left)
//{
// Elements.ToList().ForEach(u =>
// {
// if (u.State == ElementState.Selected)
// {
// u.Translate(-1, 0);
// }
// });
//}
//if (e.KeyData == Keys.Right)
//{
// Elements.ToList().ForEach(u =>
// {
// if (u.State == ElementState.Selected)
// {
// u.Translate(1, 0);
// }
// });
//}
Invalidate();
}
#endregion
#region
public Action<IShapeElement> SetElementDevicePara;
public Action<IShapeElement> SetDeviceByElement;
#endregion
#region Grid
private bool showGrid = false;
public bool ShowGrid
{
get => showGrid;
set
{
showGrid = value;
Invalidate();
}
}
private int gridValue = 0;
public int GridValue
{
get => gridValue;
set
{
gridValue = value;
Invalidate();
}
}
private Pen penGrid = new Pen(Color.FromArgb(120, Color.Red), 1.0f);
public Pen Pen_Grid
{
get => penGrid;
set
{
penGrid = value;
Invalidate();
}
}
readonly int _minGridStep = 10;
#endregion
#region Dispose
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
MAP?.Dispose();
Matrix?.Dispose();
penGrid?.Dispose();
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#endregion
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,109 @@
namespace DH.UI.Model.Winform
{
partial class GridCtrl
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.chkShowGrid = new System.Windows.Forms.CheckBox();
this.tbGridValue = new System.Windows.Forms.TrackBar();
this.panel1 = new System.Windows.Forms.Panel();
this.colorDialog1 = new System.Windows.Forms.ColorDialog();
this.btnColor = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.tbGridValue)).BeginInit();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// chkShowGrid
//
this.chkShowGrid.Appearance = System.Windows.Forms.Appearance.Button;
//this.chkShowGrid.BackgroundImage = global::XKRS.UI.Model.Winform.Properties.Resources.grid;
this.chkShowGrid.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.chkShowGrid.Dock = System.Windows.Forms.DockStyle.Top;
this.chkShowGrid.Location = new System.Drawing.Point(0, 0);
this.chkShowGrid.Name = "chkShowGrid";
this.chkShowGrid.Size = new System.Drawing.Size(32, 30);
this.chkShowGrid.TabIndex = 0;
this.chkShowGrid.UseVisualStyleBackColor = true;
this.chkShowGrid.CheckedChanged += new System.EventHandler(this.chkShowGrid_CheckedChanged);
//
// tbGridValue
//
this.tbGridValue.AutoSize = false;
this.tbGridValue.Dock = System.Windows.Forms.DockStyle.Bottom;
this.tbGridValue.Location = new System.Drawing.Point(0, 21);
this.tbGridValue.Name = "tbGridValue";
this.tbGridValue.Orientation = System.Windows.Forms.Orientation.Vertical;
this.tbGridValue.Size = new System.Drawing.Size(32, 121);
this.tbGridValue.TabIndex = 1;
this.tbGridValue.TickStyle = System.Windows.Forms.TickStyle.Both;
this.tbGridValue.ValueChanged += new System.EventHandler(this.tbGridValue_ValueChanged);
//
// panel1
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.Controls.Add(this.chkShowGrid);
this.panel1.Controls.Add(this.tbGridValue);
this.panel1.Location = new System.Drawing.Point(1, 1);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(32, 142);
this.panel1.TabIndex = 2;
//
// btnColor
//
this.btnColor.BackColor = System.Drawing.Color.Red;
this.btnColor.Location = new System.Drawing.Point(4, 150);
this.btnColor.Name = "btnColor";
this.btnColor.Size = new System.Drawing.Size(25, 23);
this.btnColor.TabIndex = 3;
this.btnColor.Text = " ";
this.btnColor.UseVisualStyleBackColor = false;
this.btnColor.Click += new System.EventHandler(this.btnColor_Click);
//
// GridCtrl
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
this.Controls.Add(this.btnColor);
this.Controls.Add(this.panel1);
this.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, ((byte)(134)));
this.Name = "GridCtrl";
this.Size = new System.Drawing.Size(32, 192);
((System.ComponentModel.ISupportInitialize)(this.tbGridValue)).EndInit();
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.CheckBox chkShowGrid;
private System.Windows.Forms.TrackBar tbGridValue;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.ColorDialog colorDialog1;
private System.Windows.Forms.Button btnColor;
}
}

View File

@ -0,0 +1,74 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace DH.UI.Model.Winform
{
public partial class GridCtrl : UserControl
{
public Action<bool> IsShowGridChanged { get; set; }
public Action<int> GridValueChanged { get; set; }
public Action<Color> GridColorChanged { get; set; }
public GridCtrl()
{
InitializeComponent();
IsChecked = chkShowGrid.Checked;
GridValue = tbGridValue.Value;
}
bool isChecked = false;
bool IsChecked
{
get => isChecked;
set
{
if (isChecked != value)
{
// IsShowGridChanged?.BeginInvoke(value, null, null);
Task.Run(() => IsShowGridChanged.Invoke(value));
}
isChecked = value;
}
}
int gridValue = 0;
int GridValue
{
get => gridValue;
set
{
if (gridValue != value)
{
// GridValueChanged?.BeginInvoke(value, null, null);
Task.Run(() => GridValueChanged.Invoke(value));
}
gridValue = value;
}
}
private void chkShowGrid_CheckedChanged(object sender, EventArgs e)
{
IsChecked = chkShowGrid.Checked;
}
private void tbGridValue_ValueChanged(object sender, EventArgs e)
{
GridValue = tbGridValue.Value;
}
private void btnColor_Click(object sender, EventArgs e)
{
if (colorDialog1.ShowDialog() == DialogResult.OK)
{
btnColor.BackColor = colorDialog1.Color;
// GridColorChanged?.BeginInvoke(btnColor.BackColor, null, null);
Task.Run(() => GridColorChanged.Invoke(btnColor.BackColor));
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,12 @@
using System.Windows.Forms;
namespace DH.UI.Model.Winform
{
public class GridCtrlHost : ToolStripControlHost
{
public GridCtrlHost(GridCtrl grid) : base(grid)
{
//Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, 134);
}
}
}

View File

@ -0,0 +1,78 @@
namespace DH.UI.Model.Winform
{
partial class IOIndicatorCtrl
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
plStatus = new Panel();
lblDesc = new Label();
SuspendLayout();
//
// plStatus
//
plStatus.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left;
plStatus.Location = new Point(0, 0);
plStatus.Margin = new Padding(4);
plStatus.Name = "plStatus";
plStatus.Size = new Size(28, 34);
plStatus.TabIndex = 0;
plStatus.Paint += plStatus_Paint;
plStatus.DoubleClick += plStatus_DoubleClick;
//
// lblDesc
//
lblDesc.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
lblDesc.AutoSize = true;
lblDesc.Font = new Font("Tahoma", 11F, FontStyle.Regular, GraphicsUnit.World);
lblDesc.Location = new Point(36, 11);
lblDesc.Margin = new Padding(4, 0, 4, 0);
lblDesc.Name = "lblDesc";
lblDesc.Size = new Size(31, 13);
lblDesc.TabIndex = 1;
lblDesc.Text = "XXXX";
lblDesc.TextAlign = ContentAlignment.MiddleLeft;
lblDesc.DoubleClick += lblDesc_DoubleClick;
//
// IOIndicatorCtrl
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(lblDesc);
Controls.Add(plStatus);
Margin = new Padding(4);
Name = "IOIndicatorCtrl";
Size = new Size(138, 34);
ResumeLayout(false);
PerformLayout();
}
#endregion
private Panel plStatus;
private Label lblDesc;
}
}

View File

@ -0,0 +1,126 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace DH.UI.Model.Winform
{
public partial class IOIndicatorCtrl : UserControl
{
public IOIndicatorCtrl()
{
InitializeComponent();
}
private bool isON = false;
public bool IsOn
{
get => isON;
set
{
bool? temp = isON;
isON = value;
if (temp != isON)
{
RefreshStatus();
}
}
}
private void RefreshStatus()
{
if (InvokeRequired)
{
Invoke(new Action(() => RefreshStatus()));
}
else
{
plStatus.Invalidate();
}
}
private string desc = "";
public string Desc
{
get => desc;
set
{
desc = value;
DisplayDesc();
}
}
public int Index { get; set; }
private void DisplayDesc()
{
if (InvokeRequired)
{
Invoke(new Action(() => DisplayDesc()));
}
else
{
lblDesc.Text = Desc;
}
}
readonly PointF[] regionBlink = new PointF[]
{
new PointF(5,10),
new PointF(10,13),
new PointF(12,7),
new PointF(10,5)
};
public IOIndicatorCtrl(bool _isOn, string _desc, int index = 0)
{
InitializeComponent();
IsOn = _isOn;
Desc = _desc;
Index = index;
}
/// <summary>
/// 更新绘制图标
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void plStatus_Paint(object sender, PaintEventArgs e)
{
Panel pl = sender as Panel;
Graphics g = e.Graphics;
g.Clear(SystemColors.Control);
if (IsOn)
{
g.FillEllipse(Brushes.LightGreen, pl.ClientRectangle);
}
else
{
g.FillEllipse(Brushes.Gray, pl.ClientRectangle);
}
g.FillPolygon(Brushes.White, regionBlink);
}
public event Action<string, bool, int> OnIODoubleClick;
private void lblDesc_DoubleClick(object sender, EventArgs e)
{
OnIODoubleClick?.Invoke(Name, IsOn, Index);
}
private void plStatus_DoubleClick(object sender, EventArgs e)
{
OnIODoubleClick?.Invoke(Name, IsOn, Index);
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,48 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<BaseOutputPath>..\</BaseOutputPath>
<AppendTargetFrameworkToOutputPath>output</AppendTargetFrameworkToOutputPath>
<UseWindowsForms>true</UseWindowsForms>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DH.Commons\DH.Commons.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
<AutoGen>True</AutoGen>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
<Generator>SettingsSingleFileGenerator</Generator>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,199 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using static DH.Commons.Enums.EnumHelper;
namespace DH.UI.Model.Winform
{
//public static class AOIEnumHelper
//{
// public enum ElementState
// {
// New = 1,
// MouseHover = 2,
// MouseInSide = 3,
// Selected = 4,
// Moving = 5,
// Normal = 11,
// Measuring = 21,
// MeasureDoneOK = 22,
// MeasureDoneNG = 23,
// }
// public enum MouseState
// {
// Normal = 1,
// HoverElement = 2,
// InSideElement = 3,
// StretchingLeft = 11,
// StretchingRight = 12,
// StretchingUp = 13,
// StretchingDown = 14,
// MoveElement = 15,
// New = 21,
// Editing = 22,
// SelectedElement = 23,
// MovingAll = 31,
// SelectionZone = 41,
// SelectionZoneDoing = 42,
// }
// public enum RunMode
// {
// [Description("设置模式")]
// SetMode = 0,
// [Description("运行模式")]
// RunMode = 1,
// }
//}
public static class EventRouter
{
/// <summary>
/// ElementBase 基元
/// 1st MouseState 初始状态
/// 2nd MouseState 变化状态
/// </summary>
public static event Action<ElementBase, ElementState, ElementState> ChangeElementsMouseState;
public static void TriggerElementsMouseStateChanged(ElementBase ele, ElementState preState, ElementState curState)
{
ChangeElementsMouseState?.Invoke(ele, preState, curState);
}
}
public class NoticedPoints : List<PointF>
{
public Action OnItemChanged;
public NoticedPoints() { }
public NoticedPoints(List<PointF> points)
{
AddRange(points);
}
public new PointF this[int index]
{
get
{
if (index >= 0 && index < Count)
{
return base[index];
}
else
{
return new Point();
}
}
set
{
if (base[index] != value)
{
base[index] = value;
OnItemChanged?.Invoke();
}
}
}
public new void Add(PointF item)
{
lock (this)
{
base.Add(item);
OnItemChanged?.Invoke();
}
}
public new void AddRange(IEnumerable<PointF> collection)
{
lock (this)
{
base.AddRange(collection);
OnItemChanged?.Invoke();
}
}
public new void Clear()
{
lock (this)
{
base.Clear();
OnItemChanged?.Invoke();
}
}
public new void Insert(int index, PointF item)
{
lock (this)
{
base.Insert(index, item);
OnItemChanged?.Invoke();
}
}
public new void InsertRange(int index, IEnumerable<PointF> collection)
{
lock (this)
{
base.InsertRange(index, collection);
OnItemChanged?.Invoke();
}
}
public new bool Remove(PointF item)
{
lock (this)
{
bool flag = base.Remove(item);
if (flag)
{
OnItemChanged?.Invoke();
}
return flag;
}
}
public new int RemoveAll(Predicate<PointF> match)
{
lock (this)
{
int i = base.RemoveAll(match);
if (i > 0)
{
OnItemChanged?.Invoke();
}
return i;
}
}
public new void RemoveAt(int index)
{
lock (this)
{
base.RemoveAt(index);
OnItemChanged?.Invoke();
}
}
public new void RemoveRange(int index, int count)
{
lock (this)
{
base.RemoveRange(index, count);
OnItemChanged?.Invoke();
}
}
}
}

View File

@ -0,0 +1,980 @@

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.Json.Serialization;
using DH.Commons.Enums;
using static DH.Commons.Enums.EnumHelper;
namespace DH.UI.Model.Winform
{
[Serializable]
public abstract class ElementBase : IShapeElement, IEventHandle, ICloneable, IComparable<ElementBase>, IDisposable
{
#region
protected int _mouseIntersectDistance = 4;
#endregion
#region
/// <summary>
/// ID采用GUID
/// </summary>
[ReadOnly(true)]
[Category("\t通用标识")]
[Description("GUID")]
public virtual string ID { get; set; } = Guid.NewGuid().ToString().ToUpper();
/// <summary>
/// 序号
/// </summary>
[Category("\t通用标识")]
[Description("序号")]
public virtual int Index { get; set; } = 0;
[Browsable(false)]
public virtual int GroupIndex { get; set; } = 0;
private string name = "";
/// <summary>
/// 名称
/// </summary>
[Category("\t通用标识")]
[Description("名称")]
public virtual string Name
{
get
{
if (string.IsNullOrWhiteSpace(name))
{
return GetDisplayText();
}
else
{
return name;
}
}
set => name = value;
}
#endregion
#region
private bool isEnabled = true;
//[Browsable(false)]
public virtual bool IsEnabled
{
get
{
return isEnabled;
}
set
{
//if (isEnabled != value)
//{
// isEnabled = value;
// PropertyChanged?.BeginInvoke(this, new PropertyChangedEventArgs("IsEnabled"), null, null);
//}
Set(ref isEnabled, value);
}
}
[Browsable(false)]
public virtual bool IsShowing { get; set; } = true;
private bool showList = true;
[Browsable(false)]
public virtual bool ShowList
{
get => showList;
set => Set(ref showList, value);
}
#endregion
#region
[JsonIgnore]
protected PointF _startPoint, _currentPoint;
#endregion
#region
[Browsable(false)]
public NoticedPoints CreatePoints { get; set; } = new NoticedPoints();
public virtual bool IsCreatedDone()
{
return CreatePoints.Count >= 2;
}
//protected Region Region { get; set; }
#region
#region
[JsonIgnore]
[Browsable(false)]
protected Pen Pen { get; set; } = new Pen(Color.Red, 1);
protected virtual void SetNewStatePen()
{
Pen = new Pen(Color.Red, 3);
}
protected virtual void SetNormalPen()
{
Pen = new Pen(Color.Red, 1);
}
protected virtual void SetHoverPen()
{
Pen = new Pen(Color.BlueViolet, 3);
}
protected virtual void SetInSidePen()
{
Pen = new Pen(Color.YellowGreen, 3);
}
protected virtual void SetSelectedPen()
{
Pen = new Pen(Color.Pink, 3);
}
protected virtual void SetMeasureDoneOKPen()
{
Pen = new Pen(Color.Green, 2);
}
protected virtual void SetMeasureDoneNGPen()
{
Pen = new Pen(Color.Red, 2);
}
protected virtual void SetMeasuringPen()
{
Pen = new Pen(Color.Yellow, 3);
}
#endregion
#region
//[JsonIgnore]
//protected Pen PenText = new Pen(Color.Black, 1);
//[JsonIgnore]
//protected Pen PenTextOK = new Pen(Color.Green, 1.5f);
//[JsonIgnore]
//protected Pen PenTextNG = new Pen(Color.Red, 2);
///// <summary>
///// 字体大小
///// </summary>
//[Category("显示属性")]
//[Description("字体大小")]
////[Browsable(false)]
//public virtual float FontSize { get; set; } = 15;
/// <summary>
/// 字体大小
/// </summary>
[Category("显示属性")]
[Description("字体设置")]
[Browsable(false)]
public virtual Font Font { get; set; } = new Font(new FontFamily("Tahoma"), 15, GraphicsUnit.World);
/// <summary>
/// 字体和基元的距离
/// </summary>
[Category("显示属性")]
[Description("字体和基元的距离")]
[Browsable(false)]
public virtual int FontDistance { get; set; } = 15;
[Category("显示属性")]
[Description("显示字符说明")]
[Browsable(false)]
public virtual bool IsShowRemark { get; set; } = true;
#endregion
#endregion
//public Graphics Graphics { get; set; }
public abstract void Draw(Graphics g);
protected abstract void DrawResult(Graphics g);
#endregion
#region
private ElementState state = ElementState.New;
[JsonIgnore]
[Browsable(false)]
public ElementState State
{
get
{
return state;
}
set
{
if (state != value)
{
ElementState preState = state;
Set(ref state, value);
EventRouter.TriggerElementsMouseStateChanged(this, preState, state);
switch (state)
{
case ElementState.MouseHover:
SetHoverPen();
break;
case ElementState.MouseInSide:
SetInSidePen();
break;
case ElementState.Selected:
SetSelectedPen();
break;
case ElementState.Normal:
SetNormalPen();
break;
case ElementState.Measuring:
SetMeasuringPen();
break;
case ElementState.MeasureDoneOK:
SetMeasureDoneOKPen();
break;
case ElementState.MeasureDoneNG:
SetMeasureDoneNGPen();
break;
case ElementState.New:
SetNewStatePen();
break;
}
}
}
}
/// <summary>
/// 是否是运行模式
/// </summary>
[Browsable(false)]
public RunMode RunMode { get; set; } = RunMode.NormalMode;
#endregion
#region
public abstract object Clone();
public virtual void Initial()
{
State = ElementState.New;
CreatePoints = new NoticedPoints();
}
#endregion
#region IMouseEvent
public virtual void OnMouseDoubleClick(PointF p)
{
if (State == ElementState.MeasureDoneNG || State == ElementState.MeasureDoneOK)
return;
//if (State == ElementState.MouseInSide)
//{
// State = ElementState.Selected;
//}
//else if (State == ElementState.Selected || State == ElementState.Moving)
//{
// if (IsMouseInSide(p))
// {
// State = ElementState.MouseInSide;
// }
//}
if (IsMouseInSide(p))
{
State = ElementState.Selected;
}
}
public abstract void OnKeyDown(object sender, KeyEventArgs e);
public abstract void OnKeyUp(object sender, KeyEventArgs e);
public virtual void OnMouseDown(PointF p)
{
//switch (State)
//{
// case ElementState.New:
// OnMouseDownWhenNew(p);
// break;
// case ElementState.MouseHover:
// break;
// case ElementState.MouseInSide:
// State = ElementState.Selected;
// break;
// case ElementState.Selected:
// _startPoint = p;
// State = ElementState.Moving;
// break;
// case ElementState.Normal:
// break;
//}
if (State == ElementState.New)
{
OnMouseDownWhenNew(p);
}
else if (IsMouseCanMoveElement(p) && State == ElementState.Selected)
{
State = ElementState.Moving;
}
else if (IsMouseCanStretchBottom(p) && State == ElementState.CanStretchBottom)
{
State = ElementState.StretchingBottom;
}
else if (IsMouseCanStretchTop(p) && State == ElementState.CanStretchTop)
{
State = ElementState.StretchingTop;
}
else if (IsMouseCanStretchLeft(p) && State == ElementState.CanStretchLeft)
{
State = ElementState.StretchingLeft;
}
else if (IsMouseCanStretchRight(p) && State == ElementState.CanStretchRight)
{
State = ElementState.StretchingRight;
}
else if (IsMouseCanStretchLeftLowerCorner(p) && State == ElementState.CanStretchLeftLowerCorner)
{
State = ElementState.StretchingLeftLowerCorner;
}
else if (IsMouseCanStretchLeftUpperCorner(p) && State == ElementState.CanStretchLeftUpperCorner)
{
State = ElementState.StretchingLeftUpperCorner;
}
else if (IsMouseCanStretchRightLowerCorner(p) && State == ElementState.CanStretchRightLowerCorner)
{
State = ElementState.StretchingRightLowerCorner;
}
else if (IsMouseCanStretchRightUpperCorner(p) && State == ElementState.CanStretchRightUpperCorner)
{
State = ElementState.StretchingRightUpperCorner;
}
}
public virtual void OnMouseMove(PointF p)
{
switch (State)
{
case ElementState.New:
OnMouseMoveWhenNew(p);
break;
case ElementState.Selected:
{
if (IsMouseCanStretchLeft(p))
{
State = ElementState.CanStretchLeft;
}
else if (IsMouseCanStretchRight(p))
{
State = ElementState.CanStretchRight;
}
else if (IsMouseCanStretchTop(p))
{
State = ElementState.CanStretchTop;
}
else if (IsMouseCanStretchBottom(p))
{
State = ElementState.CanStretchBottom;
}
else if (IsMouseCanStretchLeftLowerCorner(p))
{
State = ElementState.CanStretchLeftLowerCorner;
}
else if (IsMouseCanStretchLeftUpperCorner(p))
{
State = ElementState.CanStretchLeftUpperCorner;
}
else if (IsMouseCanStretchRightLowerCorner(p))
{
State = ElementState.CanStretchRightLowerCorner;
}
else if (IsMouseCanStretchRightUpperCorner(p))
{
State = ElementState.CanStretchRightUpperCorner;
}
break;
}
case ElementState.Moving:
_currentPoint = p;
//Translate(_currentPoint.X - _startPoint.X, _currentPoint.Y - _startPoint.Y);
//_startPoint = _currentPoint;
Relocate(p);
break;
case ElementState.MouseHover:
case ElementState.MouseInSide:
case ElementState.Normal:
//if (IsMouseInSide(p))
//{
// State = ElementState.MouseInSide;
//}
//else if (IsMouseHover(p))
//{
// State = ElementState.MouseHover;
//}
//else
//{
// State = ElementState.Normal;
//}
break;
case ElementState.CanStretchBottom:
if (!IsMouseCanStretchBottom(p))
{
State = ElementState.Selected;
}
break;
case ElementState.CanStretchTop:
if (!IsMouseCanStretchTop(p))
{
State = ElementState.Selected;
}
break;
case ElementState.CanStretchLeft:
if (!IsMouseCanStretchLeft(p))
{
State = ElementState.Selected;
}
break;
case ElementState.CanStretchRight:
if (!IsMouseCanStretchRight(p))
{
State = ElementState.Selected;
}
break;
case ElementState.CanStretchLeftUpperCorner:
if (!IsMouseCanStretchLeftUpperCorner(p))
{
State = ElementState.Selected;
}
break;
case ElementState.CanStretchLeftLowerCorner:
if (!IsMouseCanStretchLeftLowerCorner(p))
{
State = ElementState.Selected;
}
break;
case ElementState.CanStretchRightLowerCorner:
if (!IsMouseCanStretchRightLowerCorner(p))
{
State = ElementState.Selected;
}
break;
case ElementState.CanStretchRightUpperCorner:
if (!IsMouseCanStretchRightUpperCorner(p))
{
State = ElementState.Selected;
}
break;
case ElementState.StretchingTop:
StretchTop(p);
break;
case ElementState.StretchingBottom:
StretchBottom(p);
break;
case ElementState.StretchingLeft:
StretchLeft(p);
break;
case ElementState.StretchingRight:
StretchRight(p);
break;
case ElementState.StretchingLeftLowerCorner:
StretchLeftLowerCorner(p);
break;
case ElementState.StretchingLeftUpperCorner:
StretchLeftUpperCorner(p);
break;
case ElementState.StretchingRightLowerCorner:
StretchRightLowerCorner(p);
break;
case ElementState.StretchingRightUpperCorner:
StretchRightUpperCorner(p);
break;
}
}
public virtual void OnMouseUp(PointF p)
{
switch (State)
{
case ElementState.New:
OnMouseUpWhenNew(p);
break;
case ElementState.Moving:
State = ElementState.Selected;
break;
case ElementState.Selected:
if (!IsMouseInSide(p))
{
State = ElementState.Normal;
}
break;
case ElementState.StretchingBottom:
State = ElementState.CanStretchBottom;
break;
case ElementState.StretchingLeft:
State = ElementState.CanStretchLeft;
break;
case ElementState.StretchingRight:
State = ElementState.CanStretchRight;
break;
case ElementState.StretchingTop:
State = ElementState.CanStretchTop;
break;
case ElementState.StretchingLeftLowerCorner:
State = ElementState.CanStretchLeftLowerCorner;
break;
case ElementState.StretchingLeftUpperCorner:
State = ElementState.CanStretchLeftUpperCorner;
break;
case ElementState.StretchingRightUpperCorner:
State = ElementState.CanStretchRightUpperCorner;
break;
case ElementState.StretchingRightLowerCorner:
State = ElementState.CanStretchRightLowerCorner;
break;
default:
State = ElementState.Normal;
break;
}
AfterTranformOp();
}
public virtual void AfterTranformOp()
{
}
#region
/// <summary>
/// 当状态为New时的鼠标按下操作
/// </summary>
/// <param name="p"></param>
public abstract void OnMouseDownWhenNew(PointF p);
public abstract void OnMouseMoveWhenNew(PointF p);
public abstract void OnMouseUpWhenNew(PointF p);
#endregion
#endregion
#region
[JsonIgnore]
public Action<ElementBase> OnDrawDone;
[JsonIgnore]
public Action<ElementBase> OnMeasureDone;
[JsonIgnore]
public Action<ElementBase> OnElementEnableChanged;
#endregion
#region
/// <summary>
/// 基类基础的Rectangle 用于计算MouseHover和Inside等
/// </summary>
[Browsable(false)]
public Rectangle BaseRectangle { get; set; }
EnumHelper.ElementState IShapeElement.State { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public abstract bool IsMouseHover(PointF p);
public abstract bool IsMouseInSide(PointF p);
public abstract bool IsIntersect(RectangleF rect);
#region Move & Stretch & Move Anchor
public virtual bool IsMouseCanMoveElement(PointF p)
{
return false;
}
public virtual bool IsMouseCanStretchLeft(PointF p)
{
return false;
}
public virtual bool IsMouseCanStretchRight(PointF p)
{
return false;
}
public virtual bool IsMouseCanStretchTop(PointF p)
{
return false;
}
public virtual bool IsMouseCanStretchBottom(PointF p)
{
return false;
}
public virtual void StretchLeft(PointF p)
{
}
public virtual void StretchRight(PointF p)
{
}
public virtual void StretchTop(PointF p)
{
}
public virtual void StretchBottom(PointF p)
{
}
public virtual bool IsMouseCanStretchLeftUpperCorner(PointF p)
{
return false;
}
public virtual bool IsMouseCanStretchRightUpperCorner(PointF p)
{
return false;
}
public virtual bool IsMouseCanStretchLeftLowerCorner(PointF p)
{
return false;
}
public virtual bool IsMouseCanStretchRightLowerCorner(PointF p)
{
return false;
}
public virtual void StretchLeftUpperCorner(PointF p)
{
}
public virtual void StretchRightUpperCorner(PointF p)
{
}
public virtual void StretchLeftLowerCorner(PointF p)
{
}
public virtual void StretchRightLowerCorner(PointF p)
{
}
public virtual bool IsMouseCanMoveAnchor(PointF p)
{
return false;
}
#endregion
#endregion
#region
public abstract void Translate(float x, float y);
public virtual void Relocate(PointF point) { }
//public abstract void RotateAt(int x, int y, float degree);
#endregion
#region
//[Browsable(false)]
//public PlanPoint MovePoint { get; set; }
#endregion
#region
//[Browsable(false)]
//public CameraOperationConfigBase CameraOpConfig { get; set; }
#endregion
#region
#endregion
#region
/// <summary>
/// 算法
/// </summary>
/// <param name="paras">计算参数</param>
public virtual void Calculate(Bitmap image) { }
public virtual void Calculate(IntPtr imagePtr, int ptrSize, int imageWidth, int imageHeight) { }
public virtual void Calculate(string imagePath) { }
#endregion
#region
//[Description("图片保存方式")]
//public ImageSaveMode ImageSaveMode { get; set; } = ImageSaveMode.NoSave;
//public virtual void SaveImage(Bitmap image)
//{
// if (string.IsNullOrWhiteSpace(AOIMeasure.GlobalVar.ImageSaveDirectory) || ImageSaveMode == ImageSaveMode.NoSave)
// {
// return;
// }
// DirectoryInfo dir = new DirectoryInfo(GlobalVar.ImageSaveDirectory);
// if (!dir.Exists)
// {
// dir.Create();
// }
// string imgPath = Path.Combine(AOIMeasure.GlobalVar.ImageSaveDirectory, Name + "_" + DateTime.Now.ToString("MMdd_HHmmss") + ".bmp");
// switch (ImageSaveMode)
// {
// case ImageSaveMode.SaveImage:
// image.Save(imgPath);
// break;
// case ImageSaveMode.SaveImageWithElement:
// Bitmap bmp = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb);
// using (Graphics g = Graphics.FromImage(bmp))
// {
// g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
// g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
// g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
// g.DrawImage(image, 0, 0, image.Width, image.Height);
// Draw(g);
// }
// bmp.Save(imgPath);
// break;
// }
//}
//public virtual void SaveImage(IntPtr imagePtr, int ptrSize)
//{
// Bitmap map = null;
// unsafe
// {
// byte* pArray = (byte*)imagePtr;
// byte[] array = new byte[ptrSize];
// Marshal.Copy(imagePtr, array, 0, ptrSize);
// using (MemoryStream ms = new MemoryStream(array))
// {
// map = (Bitmap)Image.FromStream(ms);
// }
// }
// SaveImage(map);
//}
//public virtual void SaveImage(string imagePath)
//{
// using (Bitmap map = Image.FromFile(imagePath) as Bitmap)
// {
// SaveImage(map);
// }
//}
#endregion
#region
public virtual void InitialMeasureResult()
{
//PropertyInfo[] prop = this.GetType().GetProperties();
//Array.ForEach(prop, p =>
//{
// if ((p.PropertyType.Name == typeof(MeasureSpec).Name) && p.CanRead && p.CanWrite)
// {
// MeasureSpec spec = p.GetValue(this) as MeasureSpec;
// spec.Result = MeasureResult.NotYet;
// p.SetValue(this, spec);
// }
//});
}
public virtual void SetActualValue(double v)
{
//PropertyInfo[] prop = this.GetType().GetProperties();
//Array.ForEach(prop, p =>
// {
// if ((p.PropertyType.Name == typeof(MeasureSpec).Name) && p.CanRead && p.CanWrite)
// {
// MeasureSpec spec = p.GetValue(this) as MeasureSpec;
// spec.ActualValue = (float)v;
// p.SetValue(this, spec);
// }
// });
}
public virtual void SetStandardValue(double v)
{
//PropertyInfo[] prop = this.GetType().GetProperties();
//Array.ForEach(prop, p =>
//{
// if ((p.PropertyType.Name == typeof(MeasureSpec).Name) && p.CanRead && p.CanWrite)
// {
// MeasureSpec spec = p.GetValue(this) as MeasureSpec;
// spec.StandardValue = (float)v;
// p.SetValue(this, spec);
// }
//});
}
#endregion
#region IPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
public virtual void Set<T>(ref T field, T newValue, [CallerMemberName] string propName = null)
{
if (!field.Equals(newValue))
{
field = newValue;
//PropertyChanged?.BeginInvoke(this, new PropertyChangedEventArgs(propName), null, null);
RaisePropertyChanged(propName);
}
}
public virtual void RaisePropertyChanged(string propName = "")
{
//PropertyChanged?.BeginInvoke(this, new PropertyChangedEventArgs(propName), null, null);
//Task.Run(() =>
//{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
//});
}
#endregion
public override string ToString()
{
return GetDisplayText();
}
public abstract string GetDisplayText();
#region IComparable
public virtual int CompareTo(ElementBase other)
{
//throw new NotImplementedException();
return Index - other.Index;
}
#endregion
#region IDisposable Support
private bool disposedValue = false; // 要检测冗余调用
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// 释放托管状态(托管对象)。
Pen?.Dispose();
}
// TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。
// TODO: 将大型字段设置为 null。
disposedValue = true;
}
}
// TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。
// ~ElementBase()
// {
// // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
// Dispose(false);
// }
// 添加此代码以正确实现可处置模式。
public void Dispose()
{
// 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
Dispose(true);
// TODO: 如果在以上内容中替代了终结器,则取消注释以下行。
// GC.SuppressFinalize(this);
}
#endregion
}
[Serializable]
public abstract class DisplayElementBase : ElementBase
{
//public override object Clone()
//{
// throw new NotImplementedException();
//}
//public override void Draw(Graphics g)
//{
// throw new NotImplementedException();
//}
//public override string GetDisplayText()
//{
// throw new NotImplementedException();
//}
//public override bool IsIntersect(Rectangle rect)
//{
// throw new NotImplementedException();
//}
public override bool IsMouseHover(PointF p)
{
return false;
}
//public override bool IsMouseInSide(Point p)
//{
// throw new NotImplementedException();
//}
public override void OnKeyDown(object sender, KeyEventArgs e)
{
}
public override void OnKeyUp(object sender, KeyEventArgs e)
{
}
public override void OnMouseDownWhenNew(PointF p)
{
}
public override void OnMouseMoveWhenNew(PointF p)
{
}
public override void OnMouseUpWhenNew(PointF p)
{
}
public override void Translate(float x, float y)
{
}
protected override void DrawResult(Graphics g)
{
}
}
public interface IEventHandle
{
void OnMouseMove(PointF p);
void OnMouseDown(PointF p);
void OnMouseUp(PointF p);
void OnMouseDoubleClick(PointF p);
void OnKeyDown(object sender, KeyEventArgs e);
void OnKeyUp(object sender, KeyEventArgs e);
}
public class ElementIndexCompare : IComparer<ElementBase>
{
public int Compare(ElementBase x, ElementBase y)
{
return x.Index - y.Index;
}
}
}

View File

@ -0,0 +1,325 @@

using DH.Commons.Enums;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DH.UI.Model.Winform
{
public class DetectResultDisplay : ElementBase
{
//深度学习 显示结果
private List<DetectionResultDetail> mlResultList = null;
public List<DetectionResultDetail> MLResultList
{
get => mlResultList;
set
{
if (mlResultList != value)
{
mlResultList = value;
}
}
}
//测量结果
//private List<IndexedSpec> specResultList = null;
//public List<IndexedSpec> SpecResultList
//{
// get => specResultList;
// set
// {
// if (specResultList != value)
// {
// specResultList = value;
// string specDisplay = "";
// if (specResultList != null && specResultList.Count > 0)
// {
// specResultList.ForEach(s =>
// {
// specDisplay += $"{s.Code}:{(s.ActualValue ?? 0).ToString("f2")}\r\n";
// });
// }
// if (!string.IsNullOrWhiteSpace(specDisplay))
// {
// DisplayTxt += specDisplay;
// }
// }
// }
//}
ResultState ResultState = ResultState.DetectNG;
string DisplayTxt = "";
Bitmap ResultImage = null;
PointF StartPoint = new PointF();
Brush FontBrush = new SolidBrush(Color.Green);
Pen DetectResultRectPen = new Pen(new SolidBrush(Color.Green));
Font DetectResultFont = new Font(new FontFamily("Tahoma"), 15, GraphicsUnit.World);
public int ImageWidth { get; set; }
public int ImageHeight { get; set; }
public DetectResultDisplay() { }
//public DetectResultDisplay(NetResult result, List<IndexedSpec> specs, ResultState resultState, int imageWidth)
//{
// ImageWidth = imageWidth;
// ResultState = resultState;
// displayTxt = resultState.ToString() + "\r\n";
// if (resultState != ResultState.OK)
// {
// fontBrush = new SolidBrush(Color.Red);
// }
// NetResult = result;
// SpecList = specs;
// Font = new Font(new FontFamily("Tahoma"), 35 * ImageWidth / 1400, GraphicsUnit.World);
// startPoint = new PointF(150 * ImageWidth / 1400, 150 * ImageWidth / 1400);
//}
public DetectResultDisplay(DetectStationResult detectResult, Bitmap resultImage, string displayTxt)
{
ImageWidth = resultImage.Width;
ImageHeight = resultImage.Height;
var longSide = ImageWidth > ImageHeight ? ImageWidth : ImageHeight;
MLResultList = detectResult.DetectDetails;
// SpecResultList = detectResult.Specs;
ResultState = detectResult.ResultState;
ResultImage = resultImage;
DisplayTxt = displayTxt;
if (ResultState != ResultState.OK)
{
FontBrush = new SolidBrush(Color.Red);
DetectResultRectPen = new Pen(new SolidBrush(Color.Red));
}
Font = new Font(new FontFamily("Tahoma"), 35 * longSide / 1400, GraphicsUnit.World);
DetectResultFont = new Font(new FontFamily("Tahoma"), 25 * longSide / 1400, GraphicsUnit.World);
StartPoint = new PointF(100 * ImageWidth / 1400, 100 * ImageHeight / 1400);
}
public override object Clone()
{
return null;
}
public override void Draw(Graphics g)
{
//画检测结果图
if (ResultImage != null && ResultState != ResultState.OK)
{
g.DrawImage(ResultImage, new Point(0, 0));
}
//画文字
if (!string.IsNullOrWhiteSpace(DisplayTxt))
{
g.DrawString(DisplayTxt, Font, FontBrush, StartPoint);
}
//画外接矩形+label 深度学习
if (MLResultList != null && MLResultList.Count > 0)
{
MLResultList.ForEach(d =>
{
g.DrawRectangle(DetectResultRectPen, d.Rect);
string locationTxt = $"{d.LabelDisplay}";
var locationX = d.Rect.X;
var locationY = d.Rect.Y <= 20 ? d.Rect.Y + 20 : d.Rect.Y - 20;
g.DrawString(locationTxt, DetectResultFont, FontBrush, locationX, locationY);
});
}
//画spec信息
//if (DetectResult != null && DetectResult.NetResult?.DetectDetails?.Count > 0)
//{
// DetectResult.NetResult?.DetectDetails.ForEach(d =>
// {
// g.DrawRectangle(defectRectPen, d.Rect);
// string locationTxt = $"{d.Rect.X},{d.Rect.Y}";
// g.DrawString(locationTxt, defectFont, fontBrush, d.Rect.X, d.Rect.Y - 5);
// });
//}
//float fontHeight = g.MeasureString(displayTxt, Font).Height;
//startPoint.Y += fontHeight * 1.2f;
//var defects = DetectResult.NetResult?.DetectDetails;
//if (defects != null && defects.Count > 0)
//{
// defects.ForEach(d =>
// {
// g.DrawString($"{d.ClassName} X:{d.Rect.X.ToString("f2")} Y:{d.Rect.Y.ToString("f2")} S:{d.Area}", Font, d.FinalResult == EnumHelper.ResultState.OK ? fontBrushOK : fontBrushNG, startPoint);
// startPoint.Y += fontHeight;
// });
//}
//DetectResult.Specs.ForEach(s =>
//{
// g.DrawString($"{s.Code}:{(s.ActualValue ?? 0).ToString("f2")}", Font, s.MeasureResult ?? false == true ? fontBrushOK : fontBrushNG, startPoint);
// startPoint.Y += fontHeight;
//});
}
public override string GetDisplayText()
{
return "";
}
public override bool IsIntersect(RectangleF rect)
{
return false;
}
public override bool IsMouseHover(PointF p)
{
return false;
}
public override bool IsMouseInSide(PointF p)
{
return false;
}
public override void OnKeyDown(object sender, KeyEventArgs e)
{
}
public override void OnKeyUp(object sender, KeyEventArgs e)
{
}
protected override void DrawResult(Graphics g)
{
}
public override void OnMouseDownWhenNew(PointF p)
{
}
public override void OnMouseMoveWhenNew(PointF p)
{
}
public override void OnMouseUpWhenNew(PointF p)
{
}
public override void Translate(float x, float y)
{
}
}
public class RectResultDisplay : ElementBase
{
ResultState ResultState = ResultState.DetectNG;
public string DisplayTxt = "";
Color FillColor = Color.Lime;
int FontSize = 15;
RectangleF Rect = new RectangleF();
bool IsFilled = false;
public RectResultDisplay() { }
public RectResultDisplay(ResultState _resultState, RectangleF _rect, string _displayTxt, Color _fillColor, bool _isFilled, int _fontSize)
{
ResultState = _resultState;
Rect = _rect;
DisplayTxt = _displayTxt;
FillColor = _fillColor;
IsFilled = _isFilled;
FontSize = _fontSize;
}
public override object Clone()
{
RectResultDisplay rect = new RectResultDisplay();
rect.ResultState = ResultState;
rect.Rect = Rect;
rect.DisplayTxt = DisplayTxt;
rect.FillColor = FillColor;
rect.FontSize = FontSize;
rect.IsFilled = IsFilled;
return rect;
}
public override void Draw(Graphics g)
{
g.DrawRectangle(new Pen(FillColor, 1), Rect.X, Rect.Y, Rect.Width, Rect.Height);
if (IsFilled)
{
g.FillRectangle(new SolidBrush(Color.FromArgb(20, FillColor)), Rect);
}
Font font = new Font("Tahoma", FontSize);
var txtSize = g.MeasureString(DisplayTxt, font);
g.DrawString(DisplayTxt, font, new SolidBrush(FillColor), (float)(Rect.X + Rect.Width / 2.0 - txtSize.Width / 2.0), Rect.Y + Rect.Height + 5);
}
public override string GetDisplayText()
{
return $"{ResultState} {DisplayTxt} ({Rect.X},{Rect.Y},{Rect.Width},{Rect.Height})";
}
public override bool IsIntersect(RectangleF rect)
{
return rect.IntersectsWith(Rect);
}
public override bool IsMouseHover(PointF p)
{
return false;
}
public override bool IsMouseInSide(PointF p)
{
return Rect.Contains(p);
}
public override void OnKeyDown(object sender, KeyEventArgs e)
{
}
public override void OnKeyUp(object sender, KeyEventArgs e)
{
}
public override void OnMouseDownWhenNew(PointF p)
{
}
public override void OnMouseMoveWhenNew(PointF p)
{
}
public override void OnMouseUpWhenNew(PointF p)
{
}
public override void Translate(float x, float y)
{
Rect.Offset(new PointF(x, y));
}
protected override void DrawResult(Graphics g)
{
}
}
}

109
DH.UI.Model.Winform/GridCtrl.Designer.cs generated Normal file
View File

@ -0,0 +1,109 @@
namespace XKRS.UI.Model.Winform
{
partial class GridCtrl
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.chkShowGrid = new System.Windows.Forms.CheckBox();
this.tbGridValue = new System.Windows.Forms.TrackBar();
this.panel1 = new System.Windows.Forms.Panel();
this.colorDialog1 = new System.Windows.Forms.ColorDialog();
this.btnColor = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.tbGridValue)).BeginInit();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// chkShowGrid
//
this.chkShowGrid.Appearance = System.Windows.Forms.Appearance.Button;
// this.chkShowGrid.BackgroundImage = global::XKRS.UI.Model.Winform.Properties.Resources.grid;
this.chkShowGrid.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.chkShowGrid.Dock = System.Windows.Forms.DockStyle.Top;
this.chkShowGrid.Location = new System.Drawing.Point(0, 0);
this.chkShowGrid.Name = "chkShowGrid";
this.chkShowGrid.Size = new System.Drawing.Size(32, 30);
this.chkShowGrid.TabIndex = 0;
this.chkShowGrid.UseVisualStyleBackColor = true;
this.chkShowGrid.CheckedChanged += new System.EventHandler(this.chkShowGrid_CheckedChanged);
//
// tbGridValue
//
this.tbGridValue.AutoSize = false;
this.tbGridValue.Dock = System.Windows.Forms.DockStyle.Bottom;
this.tbGridValue.Location = new System.Drawing.Point(0, 21);
this.tbGridValue.Name = "tbGridValue";
this.tbGridValue.Orientation = System.Windows.Forms.Orientation.Vertical;
this.tbGridValue.Size = new System.Drawing.Size(32, 121);
this.tbGridValue.TabIndex = 1;
this.tbGridValue.TickStyle = System.Windows.Forms.TickStyle.Both;
this.tbGridValue.ValueChanged += new System.EventHandler(this.tbGridValue_ValueChanged);
//
// panel1
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.Controls.Add(this.chkShowGrid);
this.panel1.Controls.Add(this.tbGridValue);
this.panel1.Location = new System.Drawing.Point(1, 1);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(32, 142);
this.panel1.TabIndex = 2;
//
// btnColor
//
this.btnColor.BackColor = System.Drawing.Color.Red;
this.btnColor.Location = new System.Drawing.Point(4, 150);
this.btnColor.Name = "btnColor";
this.btnColor.Size = new System.Drawing.Size(25, 23);
this.btnColor.TabIndex = 3;
this.btnColor.Text = " ";
this.btnColor.UseVisualStyleBackColor = false;
this.btnColor.Click += new System.EventHandler(this.btnColor_Click);
//
// GridCtrl
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
this.Controls.Add(this.btnColor);
this.Controls.Add(this.panel1);
this.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, ((byte)(134)));
this.Name = "GridCtrl";
this.Size = new System.Drawing.Size(32, 192);
((System.ComponentModel.ISupportInitialize)(this.tbGridValue)).EndInit();
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.CheckBox chkShowGrid;
private System.Windows.Forms.TrackBar tbGridValue;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.ColorDialog colorDialog1;
private System.Windows.Forms.Button btnColor;
}
}

View File

@ -0,0 +1,74 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace XKRS.UI.Model.Winform
{
public partial class GridCtrl : UserControl
{
public Action<bool> IsShowGridChanged { get; set; }
public Action<int> GridValueChanged { get; set; }
public Action<Color> GridColorChanged { get; set; }
public GridCtrl()
{
InitializeComponent();
IsChecked = chkShowGrid.Checked;
GridValue = tbGridValue.Value;
}
bool isChecked = false;
bool IsChecked
{
get => isChecked;
set
{
if (isChecked != value)
{
// IsShowGridChanged?.BeginInvoke(value, null, null);
Task.Run(() => IsShowGridChanged.Invoke(value));
}
isChecked = value;
}
}
int gridValue = 0;
int GridValue
{
get => gridValue;
set
{
if (gridValue != value)
{
// GridValueChanged?.BeginInvoke(value, null, null);
Task.Run(() => GridValueChanged.Invoke(value));
}
gridValue = value;
}
}
private void chkShowGrid_CheckedChanged(object sender, EventArgs e)
{
IsChecked = chkShowGrid.Checked;
}
private void tbGridValue_ValueChanged(object sender, EventArgs e)
{
GridValue = tbGridValue.Value;
}
private void btnColor_Click(object sender, EventArgs e)
{
if (colorDialog1.ShowDialog() == DialogResult.OK)
{
btnColor.BackColor = colorDialog1.Color;
// GridColorChanged?.BeginInvoke(btnColor.BackColor, null, null);
Task.Run(() => GridColorChanged.Invoke(btnColor.BackColor));
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,12 @@
using System.Windows.Forms;
namespace XKRS.UI.Model.Winform
{
public class GridCtrlHost : ToolStripControlHost
{
public GridCtrlHost(GridCtrl grid) : base(grid)
{
//Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World, 134);
}
}
}

View File

@ -0,0 +1,78 @@
namespace XKRS.UI.Model.Winform
{
partial class IOIndicatorCtrl
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
plStatus = new Panel();
lblDesc = new Label();
SuspendLayout();
//
// plStatus
//
plStatus.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left;
plStatus.Location = new Point(0, 0);
plStatus.Margin = new Padding(4);
plStatus.Name = "plStatus";
plStatus.Size = new Size(28, 34);
plStatus.TabIndex = 0;
plStatus.Paint += plStatus_Paint;
plStatus.DoubleClick += plStatus_DoubleClick;
//
// lblDesc
//
lblDesc.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
lblDesc.AutoSize = true;
lblDesc.Font = new Font("Tahoma", 11F, FontStyle.Regular, GraphicsUnit.World);
lblDesc.Location = new Point(36, 11);
lblDesc.Margin = new Padding(4, 0, 4, 0);
lblDesc.Name = "lblDesc";
lblDesc.Size = new Size(31, 13);
lblDesc.TabIndex = 1;
lblDesc.Text = "XXXX";
lblDesc.TextAlign = ContentAlignment.MiddleLeft;
lblDesc.DoubleClick += lblDesc_DoubleClick;
//
// IOIndicatorCtrl
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(lblDesc);
Controls.Add(plStatus);
Margin = new Padding(4);
Name = "IOIndicatorCtrl";
Size = new Size(138, 34);
ResumeLayout(false);
PerformLayout();
}
#endregion
private Panel plStatus;
private Label lblDesc;
}
}

View File

@ -0,0 +1,126 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace XKRS.UI.Model.Winform
{
public partial class IOIndicatorCtrl : UserControl
{
public IOIndicatorCtrl()
{
InitializeComponent();
}
private bool isON = false;
public bool IsOn
{
get => isON;
set
{
bool? temp = isON;
isON = value;
if (temp != isON)
{
RefreshStatus();
}
}
}
private void RefreshStatus()
{
if (InvokeRequired)
{
Invoke(new Action(() => RefreshStatus()));
}
else
{
plStatus.Invalidate();
}
}
private string desc = "";
public string Desc
{
get => desc;
set
{
desc = value;
DisplayDesc();
}
}
public int Index { get; set; }
private void DisplayDesc()
{
if (InvokeRequired)
{
Invoke(new Action(() => DisplayDesc()));
}
else
{
lblDesc.Text = Desc;
}
}
readonly PointF[] regionBlink = new PointF[]
{
new PointF(5,10),
new PointF(10,13),
new PointF(12,7),
new PointF(10,5)
};
public IOIndicatorCtrl(bool _isOn, string _desc, int index = 0)
{
InitializeComponent();
IsOn = _isOn;
Desc = _desc;
Index = index;
}
/// <summary>
/// 更新绘制图标
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void plStatus_Paint(object sender, PaintEventArgs e)
{
Panel pl = sender as Panel;
Graphics g = e.Graphics;
g.Clear(SystemColors.Control);
if (IsOn)
{
g.FillEllipse(Brushes.LightGreen, pl.ClientRectangle);
}
else
{
g.FillEllipse(Brushes.Gray, pl.ClientRectangle);
}
g.FillPolygon(Brushes.White, regionBlink);
}
public event Action<string, bool, int> OnIODoubleClick;
private void lblDesc_DoubleClick(object sender, EventArgs e)
{
OnIODoubleClick?.Invoke(Name, IsOn, Index);
}
private void plStatus_DoubleClick(object sender, EventArgs e)
{
OnIODoubleClick?.Invoke(Name, IsOn, Index);
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -17,8 +17,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Commons", "Commons", "{0AB4
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Commons", "DH.Commons\DH.Commons.csproj", "{027373EC-C5CB-4161-8D43-AB6009371FDE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Devices.Vision", "DH.Devices.Vision\DH.Devices.Vision.csproj", "{97B55FCF-54A3-449E-8437-735E65C35291}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Devices.Camera", "DH.Devices.Camera\DH.Devices.Camera.csproj", "{1378A932-1C25-40EF-BA31-A3463B23F4E5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Devices.PLC", "DH.Devices.PLC\DH.Devices.PLC.csproj", "{458B2CF6-6F1B-4B8B-BB85-C6FD7F453A5D}"
@ -29,6 +27,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Devices.Motion", "DH.Dev
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Commons.Devies", "DH.Commons.Devies\DH.Commons.Devies.csproj", "{A33108B6-2740-4D28-AD22-B280372980BE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UI", "UI", "{3EAF3D9C-D3F9-4B6E-89DE-58F129CD1F4C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.UI.Model.Winform", "DH.UI.Model.Winform\DH.UI.Model.Winform.csproj", "{12CB9041-B1B1-41AE-B308-AABDACAA580E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DH.Devices.Vision", "DH.Devices.Vision\DH.Devices.Vision.csproj", "{5AD3A29E-149A-4C37-9548-7638A36C8175}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -53,14 +57,6 @@ Global
{027373EC-C5CB-4161-8D43-AB6009371FDE}.Release|Any CPU.Build.0 = Release|Any CPU
{027373EC-C5CB-4161-8D43-AB6009371FDE}.Release|x64.ActiveCfg = Release|x64
{027373EC-C5CB-4161-8D43-AB6009371FDE}.Release|x64.Build.0 = Release|x64
{97B55FCF-54A3-449E-8437-735E65C35291}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{97B55FCF-54A3-449E-8437-735E65C35291}.Debug|Any CPU.Build.0 = Debug|Any CPU
{97B55FCF-54A3-449E-8437-735E65C35291}.Debug|x64.ActiveCfg = Debug|x64
{97B55FCF-54A3-449E-8437-735E65C35291}.Debug|x64.Build.0 = Debug|x64
{97B55FCF-54A3-449E-8437-735E65C35291}.Release|Any CPU.ActiveCfg = Release|Any CPU
{97B55FCF-54A3-449E-8437-735E65C35291}.Release|Any CPU.Build.0 = Release|Any CPU
{97B55FCF-54A3-449E-8437-735E65C35291}.Release|x64.ActiveCfg = Release|x64
{97B55FCF-54A3-449E-8437-735E65C35291}.Release|x64.Build.0 = Release|x64
{1378A932-1C25-40EF-BA31-A3463B23F4E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1378A932-1C25-40EF-BA31-A3463B23F4E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1378A932-1C25-40EF-BA31-A3463B23F4E5}.Debug|x64.ActiveCfg = Debug|x64
@ -93,6 +89,22 @@ Global
{A33108B6-2740-4D28-AD22-B280372980BE}.Release|Any CPU.Build.0 = Release|Any CPU
{A33108B6-2740-4D28-AD22-B280372980BE}.Release|x64.ActiveCfg = Release|X64
{A33108B6-2740-4D28-AD22-B280372980BE}.Release|x64.Build.0 = Release|X64
{12CB9041-B1B1-41AE-B308-AABDACAA580E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{12CB9041-B1B1-41AE-B308-AABDACAA580E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{12CB9041-B1B1-41AE-B308-AABDACAA580E}.Debug|x64.ActiveCfg = Debug|Any CPU
{12CB9041-B1B1-41AE-B308-AABDACAA580E}.Debug|x64.Build.0 = Debug|Any CPU
{12CB9041-B1B1-41AE-B308-AABDACAA580E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{12CB9041-B1B1-41AE-B308-AABDACAA580E}.Release|Any CPU.Build.0 = Release|Any CPU
{12CB9041-B1B1-41AE-B308-AABDACAA580E}.Release|x64.ActiveCfg = Release|Any CPU
{12CB9041-B1B1-41AE-B308-AABDACAA580E}.Release|x64.Build.0 = Release|Any CPU
{5AD3A29E-149A-4C37-9548-7638A36C8175}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5AD3A29E-149A-4C37-9548-7638A36C8175}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5AD3A29E-149A-4C37-9548-7638A36C8175}.Debug|x64.ActiveCfg = Debug|x64
{5AD3A29E-149A-4C37-9548-7638A36C8175}.Debug|x64.Build.0 = Debug|x64
{5AD3A29E-149A-4C37-9548-7638A36C8175}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5AD3A29E-149A-4C37-9548-7638A36C8175}.Release|Any CPU.Build.0 = Release|Any CPU
{5AD3A29E-149A-4C37-9548-7638A36C8175}.Release|x64.ActiveCfg = Release|x64
{5AD3A29E-149A-4C37-9548-7638A36C8175}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -102,12 +114,13 @@ Global
{1591B03B-0015-42FC-B784-0D9F740E2A23} = {8EC33C16-65CE-4C12-9C8D-DB2425F9F7C0}
{F77AF94C-280D-44C5-B7C0-FC86AA9EC504} = {8EC33C16-65CE-4C12-9C8D-DB2425F9F7C0}
{027373EC-C5CB-4161-8D43-AB6009371FDE} = {0AB4BB9A-A861-4F80-B549-CD331490942B}
{97B55FCF-54A3-449E-8437-735E65C35291} = {F77AF94C-280D-44C5-B7C0-FC86AA9EC504}
{1378A932-1C25-40EF-BA31-A3463B23F4E5} = {1591B03B-0015-42FC-B784-0D9F740E2A23}
{458B2CF6-6F1B-4B8B-BB85-C6FD7F453A5D} = {2560C5A5-0CA2-48AD-B606-6C55BEFD8109}
{5C8472C6-EB6A-4D89-B519-7073BBF6A5D2} = {8EC33C16-65CE-4C12-9C8D-DB2425F9F7C0}
{144E3775-0BD7-4528-9FB0-A0F4ADC74313} = {5C8472C6-EB6A-4D89-B519-7073BBF6A5D2}
{A33108B6-2740-4D28-AD22-B280372980BE} = {0AB4BB9A-A861-4F80-B549-CD331490942B}
{12CB9041-B1B1-41AE-B308-AABDACAA580E} = {3EAF3D9C-D3F9-4B6E-89DE-58F129CD1F4C}
{5AD3A29E-149A-4C37-9548-7638A36C8175} = {F77AF94C-280D-44C5-B7C0-FC86AA9EC504}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6FC1A8DF-636E-434C-981E-10F20FAD723B}

View File

@ -21,6 +21,7 @@
<ItemGroup>
<PackageReference Include="AntdUI" Version="1.9.3" />
<PackageReference Include="System.IO.Ports" Version="9.0.2" />
@ -31,6 +32,7 @@
<ProjectReference Include="..\DH.Devices.Motion\DH.Devices.Motion.csproj" />
<ProjectReference Include="..\DH.Devices.PLC\DH.Devices.PLC.csproj" />
<ProjectReference Include="..\DH.Devices.Vision\DH.Devices.Vision.csproj" />
<ProjectReference Include="..\DH.UI.Model.Winform\DH.UI.Model.Winform.csproj" />
</ItemGroup>
<ItemGroup>

View File

@ -50,7 +50,7 @@
splitContainer1 = new SplitContainer();
splitContainer2 = new SplitContainer();
tabImgDisplay = new AntdUI.Tabs();
tabPage1 = new AntdUI.TabPage();
tabMain = new AntdUI.TabPage();
tabsStas = new AntdUI.Tabs();
tabPage3 = new AntdUI.TabPage();
richTextBox1 = new RichTextBox();
@ -124,6 +124,7 @@
buttonSZ.Radius = 0;
buttonSZ.Size = new Size(50, 40);
buttonSZ.TabIndex = 0;
buttonSZ.Visible = false;
buttonSZ.WaveSize = 0;
//
// pageHeader1
@ -142,7 +143,7 @@
// label1
//
label1.AutoSize = true;
label1.Location = new Point(709, 10);
label1.Location = new Point(979, 10);
label1.Name = "label1";
label1.Size = new Size(64, 21);
label1.TabIndex = 1;
@ -240,23 +241,23 @@
//
// tabImgDisplay
//
tabImgDisplay.Controls.Add(tabPage1);
tabImgDisplay.Controls.Add(tabMain);
tabImgDisplay.Dock = DockStyle.Fill;
tabImgDisplay.Location = new Point(0, 0);
tabImgDisplay.Name = "tabImgDisplay";
tabImgDisplay.Pages.Add(tabPage1);
tabImgDisplay.Pages.Add(tabMain);
tabImgDisplay.Size = new Size(580, 320);
tabImgDisplay.Style = styleCard1;
tabImgDisplay.TabIndex = 1;
tabImgDisplay.Text = "tabs1";
//
// tabPage1
// tabMain
//
tabPage1.Location = new Point(3, 28);
tabPage1.Name = "tabPage1";
tabPage1.Size = new Size(574, 289);
tabPage1.TabIndex = 0;
tabPage1.Text = "检测";
tabMain.Location = new Point(3, 28);
tabMain.Name = "tabMain";
tabMain.Size = new Size(574, 289);
tabMain.TabIndex = 0;
tabMain.Text = "检测";
//
// tabsStas
//
@ -452,7 +453,7 @@
private SplitContainer splitContainer1;
private SplitContainer splitContainer2;
private AntdUI.Tabs tabImgDisplay;
private AntdUI.TabPage tabPage1;
private AntdUI.TabPage tabMain;
private AntdUI.Tabs tabsStas;
private AntdUI.TabPage tabPage3;
private RichTextBox richTextBox1;

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Microsoft ResX Schema
Version 2.0
@ -48,7 +48,7 @@
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter

View File

@ -0,0 +1,196 @@
namespace XKRS.UI.Device.Winform
{
partial class CtrlVisionDisplay
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.ctmsVisibleControl = new System.Windows.Forms.ContextMenuStrip(this.components);
this.tsmiShowToolBar = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiShowImageSwitch = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiShowStatusBar = new System.Windows.Forms.ToolStripMenuItem();
this.tsmiShowOpConfig = new System.Windows.Forms.ToolStripMenuItem();
this.gBox = new System.Windows.Forms.GroupBox();
this.tscImageSwitch = new System.Windows.Forms.ToolStripContainer();
this.chkShowDefect = new System.Windows.Forms.CheckBox();
this.chkShowOrigin = new System.Windows.Forms.CheckBox();
this.plMain = new System.Windows.Forms.Panel();
this.ctmsVisibleControl.SuspendLayout();
this.gBox.SuspendLayout();
this.tscImageSwitch.ContentPanel.SuspendLayout();
this.tscImageSwitch.SuspendLayout();
this.SuspendLayout();
//
// ctmsVisibleControl
//
this.ctmsVisibleControl.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.tsmiShowToolBar,
this.tsmiShowImageSwitch,
this.tsmiShowStatusBar,
this.tsmiShowOpConfig});
this.ctmsVisibleControl.Name = "ctmsVisibleControl";
this.ctmsVisibleControl.Size = new System.Drawing.Size(149, 92);
//
// tsmiShowToolBar
//
this.tsmiShowToolBar.CheckOnClick = true;
this.tsmiShowToolBar.Name = "tsmiShowToolBar";
this.tsmiShowToolBar.Size = new System.Drawing.Size(148, 22);
this.tsmiShowToolBar.Text = "显示工具栏";
this.tsmiShowToolBar.CheckedChanged += new System.EventHandler(this.tsmiShowToolBar_CheckedChanged);
//
// tsmiShowImageSwitch
//
this.tsmiShowImageSwitch.CheckOnClick = true;
this.tsmiShowImageSwitch.Name = "tsmiShowImageSwitch";
this.tsmiShowImageSwitch.Size = new System.Drawing.Size(148, 22);
this.tsmiShowImageSwitch.Text = "显示图像开关";
this.tsmiShowImageSwitch.CheckedChanged += new System.EventHandler(this.tsmiShowOpBar_CheckedChanged);
//
// tsmiShowStatusBar
//
this.tsmiShowStatusBar.CheckOnClick = true;
this.tsmiShowStatusBar.Name = "tsmiShowStatusBar";
this.tsmiShowStatusBar.Size = new System.Drawing.Size(148, 22);
this.tsmiShowStatusBar.Text = "显示状态栏";
this.tsmiShowStatusBar.CheckedChanged += new System.EventHandler(this.tsmiShowStatusBar_CheckedChanged);
//
// tsmiShowOpConfig
//
this.tsmiShowOpConfig.CheckOnClick = true;
this.tsmiShowOpConfig.Name = "tsmiShowOpConfig";
this.tsmiShowOpConfig.Size = new System.Drawing.Size(148, 22);
this.tsmiShowOpConfig.Text = "显示操作配置";
this.tsmiShowOpConfig.CheckedChanged += new System.EventHandler(this.tsmiShowOpConfig_CheckedChanged);
//
// gBox
//
this.gBox.Controls.Add(this.tscImageSwitch);
this.gBox.Controls.Add(this.plMain);
this.gBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.gBox.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.gBox.Location = new System.Drawing.Point(0, 0);
this.gBox.Name = "gBox";
this.gBox.Size = new System.Drawing.Size(596, 488);
this.gBox.TabIndex = 2;
this.gBox.TabStop = false;
this.gBox.Text = "groupBox1";
//
// tscImageSwitch
//
this.tscImageSwitch.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tscImageSwitch.BottomToolStripPanelVisible = false;
//
// tscImageSwitch.ContentPanel
//
this.tscImageSwitch.ContentPanel.BackColor = System.Drawing.Color.Transparent;
this.tscImageSwitch.ContentPanel.Controls.Add(this.chkShowDefect);
this.tscImageSwitch.ContentPanel.Controls.Add(this.chkShowOrigin);
this.tscImageSwitch.ContentPanel.Margin = new System.Windows.Forms.Padding(0);
this.tscImageSwitch.ContentPanel.Size = new System.Drawing.Size(202, 24);
this.tscImageSwitch.LeftToolStripPanelVisible = false;
this.tscImageSwitch.Location = new System.Drawing.Point(78, 13);
this.tscImageSwitch.Name = "tscImageSwitch";
this.tscImageSwitch.RightToolStripPanelVisible = false;
this.tscImageSwitch.Size = new System.Drawing.Size(202, 24);
this.tscImageSwitch.TabIndex = 3;
this.tscImageSwitch.Text = "toolStripContainer2";
this.tscImageSwitch.TopToolStripPanelVisible = false;
this.tscImageSwitch.Visible = false;
//
// chkShowDefect
//
this.chkShowDefect.AutoSize = true;
this.chkShowDefect.Checked = true;
this.chkShowDefect.CheckState = System.Windows.Forms.CheckState.Checked;
this.chkShowDefect.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.chkShowDefect.Location = new System.Drawing.Point(3, 3);
this.chkShowDefect.Name = "chkShowDefect";
this.chkShowDefect.Size = new System.Drawing.Size(74, 18);
this.chkShowDefect.TabIndex = 0;
this.chkShowDefect.Text = "显示缺陷";
this.chkShowDefect.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.chkShowDefect.TextImageRelation = System.Windows.Forms.TextImageRelation.TextAboveImage;
this.chkShowDefect.UseVisualStyleBackColor = true;
this.chkShowDefect.CheckedChanged += new System.EventHandler(this.chkShowDefect_CheckedChanged);
//
// chkShowOrigin
//
this.chkShowOrigin.AutoSize = true;
this.chkShowOrigin.Checked = true;
this.chkShowOrigin.CheckState = System.Windows.Forms.CheckState.Checked;
this.chkShowOrigin.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.chkShowOrigin.Location = new System.Drawing.Point(83, 3);
this.chkShowOrigin.Name = "chkShowOrigin";
this.chkShowOrigin.Size = new System.Drawing.Size(74, 18);
this.chkShowOrigin.TabIndex = 1;
this.chkShowOrigin.Text = "显示原图";
this.chkShowOrigin.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.chkShowOrigin.TextImageRelation = System.Windows.Forms.TextImageRelation.TextAboveImage;
this.chkShowOrigin.UseVisualStyleBackColor = true;
this.chkShowOrigin.CheckedChanged += new System.EventHandler(this.chkShowOrigin_CheckedChanged);
//
// plMain
//
this.plMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.plMain.Location = new System.Drawing.Point(3, 18);
this.plMain.Name = "plMain";
this.plMain.Size = new System.Drawing.Size(590, 467);
this.plMain.TabIndex = 0;
//
// CtrlDetectionDisplay
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ContextMenuStrip = this.ctmsVisibleControl;
this.Controls.Add(this.gBox);
this.Name = "CtrlDetectionDisplay";
this.Size = new System.Drawing.Size(596, 488);
this.ctmsVisibleControl.ResumeLayout(false);
this.gBox.ResumeLayout(false);
this.tscImageSwitch.ContentPanel.ResumeLayout(false);
this.tscImageSwitch.ContentPanel.PerformLayout();
this.tscImageSwitch.ResumeLayout(false);
this.tscImageSwitch.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ContextMenuStrip ctmsVisibleControl;
private System.Windows.Forms.ToolStripMenuItem tsmiShowToolBar;
private System.Windows.Forms.ToolStripMenuItem tsmiShowImageSwitch;
private System.Windows.Forms.ToolStripMenuItem tsmiShowStatusBar;
private System.Windows.Forms.GroupBox gBox;
private System.Windows.Forms.Panel plMain;
private System.Windows.Forms.ToolStripMenuItem tsmiShowOpConfig;
private System.Windows.Forms.ToolStripContainer tscImageSwitch;
private System.Windows.Forms.CheckBox chkShowDefect;
private System.Windows.Forms.CheckBox chkShowOrigin;
}
}

View File

@ -0,0 +1,172 @@

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using DH.Commons.Enums;
using DH.UI.Model.Winform;
namespace XKRS.UI.Device.Winform
{
public partial class CtrlVisionDisplay : UserControl
{
public Canvas CvImage { get; set; }
public bool IsShowPreTreatedImage { get; set; } = true;
public bool IsShowDefectImage { get; set; } = true;
public Bitmap CurrBitmap { get; set; }
public List<IShapeElement> CurrDetectionResults { get; set; } = new List<IShapeElement>();
public event Action<bool> OnShowOpConfigMenuStateChanged;
public CtrlVisionDisplay()
{
InitializeComponent();
CvImage = new Canvas();
CvImage.IsShowElementList = false;
CvImage.IsShowROITool = false;
CvImage.Dock = DockStyle.Fill;
CvImage.ContextMenuStrip = ctmsVisibleControl;
plMain.Controls.Add(CvImage);
InitialToolBarVisible();
this.Load += ((s, e) =>
{
gBox.Text = DetectionName;
});
}
public string DetectionId { get; set; }
public string DetectionName { get; set; }
public int RowIndex { get; set; }
public int ColIndex { get; set; }
public void RefreshDetectionResult(Bitmap image, List<IShapeElement> detectionResults)
{
try
{
if (image == null)
return;
CurrBitmap = image;
if (detectionResults != null)
{
CurrDetectionResults = new List<IShapeElement>(detectionResults);
}
if (CvImage.IsHandleCreated)
{
CvImage.Elements.Clear();
if (IsShowPreTreatedImage)
{
CvImage.LoadImage(image);
}
else
{
//加载一张同样大小的 空白图
Bitmap newImage = new Bitmap(image.Width, image.Height);
using (Graphics grp = Graphics.FromImage(newImage))
{
grp.FillRectangle(Brushes.White, 0, 0, newImage.Width, newImage.Height);
}
CvImage.LoadImage(newImage);
}
if (IsShowDefectImage && detectionResults != null)
{
detectionResults.ForEach(e => CvImage.Elements.Add(e));
}
}
}
catch (Exception ex)
{
}
}
#region
private void chkShowDefect_CheckedChanged(object sender, EventArgs e)
{
IsShowDefectImage = chkShowDefect.Checked;
RefreshDetectionResult(CurrBitmap, CurrDetectionResults);
}
private void chkShowOrigin_CheckedChanged(object sender, EventArgs e)
{
IsShowPreTreatedImage = chkShowOrigin.Checked;
RefreshDetectionResult(CurrBitmap, CurrDetectionResults);
}
#endregion
#region
public bool IsShowOperationBar
{
get => tscImageSwitch.Visible;
set => tsmiShowImageSwitch.Checked = tscImageSwitch.Visible = value;
}
public bool IsShowToolBar
{
get => CvImage.IsShowToolBar;
set => tsmiShowToolBar.Checked = CvImage.IsShowToolBar = value;
}
public bool IsShowStatusBar
{
get => CvImage.IsShowStatusBar;
set => tsmiShowStatusBar.Checked = CvImage.IsShowStatusBar = value;
}
private bool isShowOpConfig = false;
public bool IsShowOpConfig
{
get => tsmiShowOpConfig.Checked;
set
{
if (tsmiShowOpConfig.Checked != value)
{
tsmiShowOpConfig.Checked = value;
}
OnShowOpConfigMenuStateChanged?.Invoke(value);
}
}
private void tsmiShowOpConfig_CheckedChanged(object sender, EventArgs e)
{
IsShowOpConfig = tsmiShowOpConfig.Checked;
}
private void InitialToolBarVisible()
{
IsShowOperationBar = IsShowToolBar = IsShowStatusBar = false;
}
private void tsmiShowToolBar_CheckedChanged(object sender, EventArgs e)
{
IsShowToolBar = tsmiShowToolBar.Checked;
}
private void tsmiShowOpBar_CheckedChanged(object sender, EventArgs e)
{
IsShowOperationBar = tsmiShowImageSwitch.Checked;
}
private void tsmiShowStatusBar_CheckedChanged(object sender, EventArgs e)
{
IsShowStatusBar = tsmiShowStatusBar.Checked;
}
#endregion
}
}

View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="ctmsVisibleControl.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>44, 19</value>
</metadata>
</root>

View File

@ -0,0 +1,174 @@

namespace XKRS.UI.Device.Winform
{
partial class CtrlVisionRunBase
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.tableDisplay = new System.Windows.Forms.TableLayoutPanel();
this.tlpOpConfig = new System.Windows.Forms.TableLayoutPanel();
this.propOpConfig = new System.Windows.Forms.PropertyGrid();
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.btnExecuteOpConfig = new System.Windows.Forms.Button();
this.btnBatchRun = new System.Windows.Forms.Button();
this.splitCMain = new System.Windows.Forms.SplitContainer();
this.tlpOpConfig.SuspendLayout();
this.flowLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitCMain)).BeginInit();
this.splitCMain.Panel1.SuspendLayout();
this.splitCMain.Panel2.SuspendLayout();
this.splitCMain.SuspendLayout();
this.SuspendLayout();
//
// tableDisplay
//
this.tableDisplay.ColumnCount = 2;
this.tableDisplay.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableDisplay.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableDisplay.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableDisplay.Location = new System.Drawing.Point(0, 0);
this.tableDisplay.Name = "tableDisplay";
this.tableDisplay.RowCount = 2;
this.tableDisplay.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableDisplay.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableDisplay.Size = new System.Drawing.Size(769, 251);
this.tableDisplay.TabIndex = 0;
//
// tlpOpConfig
//
this.tlpOpConfig.ColumnCount = 1;
this.tlpOpConfig.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tlpOpConfig.Controls.Add(this.propOpConfig, 0, 1);
this.tlpOpConfig.Controls.Add(this.flowLayoutPanel1, 0, 0);
this.tlpOpConfig.Dock = System.Windows.Forms.DockStyle.Fill;
this.tlpOpConfig.Location = new System.Drawing.Point(0, 0);
this.tlpOpConfig.Name = "tlpOpConfig";
this.tlpOpConfig.RowCount = 2;
this.tlpOpConfig.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 35F));
this.tlpOpConfig.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tlpOpConfig.Size = new System.Drawing.Size(769, 247);
this.tlpOpConfig.TabIndex = 0;
//
// propOpConfig
//
this.propOpConfig.Dock = System.Windows.Forms.DockStyle.Fill;
this.propOpConfig.Location = new System.Drawing.Point(3, 38);
this.propOpConfig.Name = "propOpConfig";
this.propOpConfig.Size = new System.Drawing.Size(763, 206);
this.propOpConfig.TabIndex = 1;
this.propOpConfig.ToolbarVisible = false;
//
// flowLayoutPanel1
//
this.flowLayoutPanel1.Controls.Add(this.btnExecuteOpConfig);
this.flowLayoutPanel1.Controls.Add(this.btnBatchRun);
this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft;
this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
this.flowLayoutPanel1.Size = new System.Drawing.Size(769, 35);
this.flowLayoutPanel1.TabIndex = 2;
//
// btnExecuteOpConfig
//
this.btnExecuteOpConfig.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnExecuteOpConfig.BackColor = System.Drawing.SystemColors.GradientActiveCaption;
this.btnExecuteOpConfig.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnExecuteOpConfig.Font = new System.Drawing.Font("微软雅黑", 12F);
this.btnExecuteOpConfig.Location = new System.Drawing.Point(598, 3);
this.btnExecuteOpConfig.Margin = new System.Windows.Forms.Padding(5, 3, 5, 3);
this.btnExecuteOpConfig.MinimumSize = new System.Drawing.Size(1, 1);
this.btnExecuteOpConfig.Name = "btnExecuteOpConfig";
this.btnExecuteOpConfig.Size = new System.Drawing.Size(166, 30);
this.btnExecuteOpConfig.TabIndex = 0;
this.btnExecuteOpConfig.Text = "执行当前配置操作";
this.btnExecuteOpConfig.UseVisualStyleBackColor = false;
// this.btnExecuteOpConfig.Click += new System.EventHandler(this.btnExecuteOpConfig_Click);
//
// btnBatchRun
//
this.btnBatchRun.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnBatchRun.BackColor = System.Drawing.SystemColors.Info;
this.btnBatchRun.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnBatchRun.Font = new System.Drawing.Font("微软雅黑", 12F);
this.btnBatchRun.Location = new System.Drawing.Point(488, 3);
this.btnBatchRun.Margin = new System.Windows.Forms.Padding(5, 3, 5, 3);
this.btnBatchRun.MinimumSize = new System.Drawing.Size(1, 1);
this.btnBatchRun.Name = "btnBatchRun";
this.btnBatchRun.Size = new System.Drawing.Size(100, 30);
this.btnBatchRun.TabIndex = 0;
this.btnBatchRun.Text = "批量检测";
this.btnBatchRun.UseVisualStyleBackColor = false;
// this.btnBatchRun.Click += new System.EventHandler(this.btnBatchRun_Click);
//
// splitCMain
//
this.splitCMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitCMain.Location = new System.Drawing.Point(0, 0);
this.splitCMain.Name = "splitCMain";
this.splitCMain.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitCMain.Panel1
//
this.splitCMain.Panel1.Controls.Add(this.tableDisplay);
//
// splitCMain.Panel2
//
this.splitCMain.Panel2.Controls.Add(this.tlpOpConfig);
this.splitCMain.Size = new System.Drawing.Size(769, 502);
this.splitCMain.SplitterDistance = 251;
this.splitCMain.TabIndex = 2;
//
// CtrlVisionRunBase
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.splitCMain);
this.Name = "CtrlVisionRunBase";
this.Size = new System.Drawing.Size(769, 502);
this.tlpOpConfig.ResumeLayout(false);
this.flowLayoutPanel1.ResumeLayout(false);
this.splitCMain.Panel1.ResumeLayout(false);
this.splitCMain.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitCMain)).EndInit();
this.splitCMain.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableDisplay;
private System.Windows.Forms.TableLayoutPanel tlpOpConfig;
private System.Windows.Forms.Button btnExecuteOpConfig;
private System.Windows.Forms.PropertyGrid propOpConfig;
private System.Windows.Forms.SplitContainer splitCMain;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
private System.Windows.Forms.Button btnBatchRun;
}
}

View File

@ -0,0 +1,249 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using DH.Commons.Enums;
using DH.Devices.Devices;
namespace XKRS.UI.Device.Winform
{
public partial class CtrlVisionRunBase : UserControl
{
private DateTime LastDisplayTime = DateTime.MinValue;
//public CtrlVisionRunBase()
//{
// InitializeComponent();
//}
//private object OnUpdateBatchNO(ISubscriber arg1, object arg2, object arg3)
//{
// //获取BatchNO
// if (arg2 is string batchNo)
// {
// ML.BatchNO = string.IsNullOrEmpty(batchNo) ? "OFFline_" + DateTime.Now.ToString("yyyyMMdd") : batchNo;
// }
// return null;
//}
public CtrlVisionRunBase(VisionEngineBase device)
{
InitializeComponent();
Device = device;
InitialLayout();
this.Load += (s, e) =>
{
ML.OnDetectionDone -= ML_OnDetectionDone;
ML.OnDetectionDone += ML_OnDetectionDone;
};
// PubSubCenter.GetInstance().RemoveSubscribers(PubSubCenterMessageType.UpdateBatchNO.ToString());
// PubSubCenter.GetInstance().Subscribe(PubSubCenterMessageType.UpdateBatchNO.ToString(), OnUpdateBatchNO);
}
private async void ML_OnDetectionDone(string detectionId, Bitmap image, List<IShapeElement> detectionResults)
{
await Task.Run(() =>
{
if (!this.IsHandleCreated)
return;
this.Invoke(new Action(() =>
{
if (this.IsDisposed)
return;
var display = displayList.FirstOrDefault(u => u.DetectionId == detectionId);
if (display != null)
{
display.RefreshDetectionResult(image, detectionResults);
}
}));
});
}
public VisionEngineBase Device { get; set; }
protected VisionEngineBase ML
{
get => Device as VisionEngineBase;
}
//VisionEngineInitialConfigBase IConfig => ML?.InitialConfig as VisionEngineInitialConfigBase;
//VisionEngineOperationConfigBase OpConfig = new VisionEngineOperationConfigBase();
//private void btnExecuteOpConfig_Click(object sender, EventArgs e)
//{
// try
// {
// PubSubCenter.GetInstance().Publish(PubSubCenterMessageType.RequestBatchNO.ToString(), null, null);
// var msg = ML.RunWrap(OpConfig);
// if (msg.Result != 1)
// {
// MessageBox.Show(msg.Message);
// }
// }
// catch (Exception ex)
// {
// MessageBox.Show(ex.GetExceptionMessage());
// }
//}
#region Layout
int rows = 1;
int cols = 1;
public int Rows
{
get => rows;
set
{
if (value <= 1)
{
rows = 1;
}
else
{
rows = value;
}
}
}
public int Cols
{
get => cols;
set
{
if (value <= 1)
{
cols = 1;
}
else
{
cols = value;
}
}
}
List<CtrlVisionDisplay> displayList = null;
private void InitialLayout()
{
if (ML.DetectionConfigs.Count == 0)
{
return;
}
var locations = ML.DetectionConfigs.Select(u => u.ShowLocation).ToList();
if (locations.Count > 0)
{
Rows = (int)locations.Max(u => u.Y);
Cols = (int)locations.Max(u => u.X);
}
tableDisplay.ColumnCount = Cols;
tableDisplay.RowCount = Rows;
tableDisplay.ColumnStyles.Clear();
for (int i = 0; i < Cols; i++)
{
ColumnStyle colStyle = new ColumnStyle();
colStyle.SizeType = SizeType.Percent;
colStyle.Width = 1.0f / (float)Cols;
tableDisplay.ColumnStyles.Add(colStyle);
}
tableDisplay.RowStyles.Clear();
for (int i = 0; i < Rows; i++)
{
RowStyle rowStyle = new RowStyle();
rowStyle.SizeType = SizeType.Percent;
rowStyle.Height = 1.0f / (float)Rows;
tableDisplay.RowStyles.Add(rowStyle);
}
tableDisplay.Controls.Clear();
displayList = new List<CtrlVisionDisplay>();
ML.DetectionConfigs.ForEach(d =>
{
//if (!d.IsShowInUI)
// return;
CtrlVisionDisplay display = new CtrlVisionDisplay();
display.DetectionId = d.Id;
display.DetectionName = d.Name;
display.RowIndex = (int)d.ShowLocation.Y - 1;
display.ColIndex = (int)d.ShowLocation.X - 1;
//display.RowIndex = (int)count%row;
//display.ColIndex = (int)count / row;
display.Dock = DockStyle.Fill;
display.OnShowOpConfigMenuStateChanged -= Display_OnShowOpConfigMenuStateChanged;
display.OnShowOpConfigMenuStateChanged += Display_OnShowOpConfigMenuStateChanged;
displayList.Add(display);
tableDisplay.Controls.Add(display);
tableDisplay.SetCellPosition(display, new TableLayoutPanelCellPosition(display.ColIndex, display.RowIndex));
});
splitCMain.Panel2Collapsed = true;
// propOpConfig.SelectedObject = OpConfig;
}
private void Display_OnShowOpConfigMenuStateChanged(bool isVisible)
{
IsShowOpConfig = isVisible;
}
public bool IsShowOpConfig
{
get => !splitCMain.Panel2Collapsed;
set
{
if (splitCMain.Panel2Collapsed == value)
{
splitCMain.Panel2Collapsed = !value;
displayList.ForEach(d => d.IsShowOpConfig = value);
}
}
}
#endregion
//private void btnBatchRun_Click(object sender, EventArgs e)
//{
// FrmMLBatchRun frmMLBatchRun = new FrmMLBatchRun(Device);
// frmMLBatchRun.MdiParent = (this.Parent as DeviceRunFrmBase).MdiParent;
// frmMLBatchRun.DockPanel = (this.Parent as DeviceRunFrmBase).DockPanel;
// frmMLBatchRun.DockState = DockState.Document;
// frmMLBatchRun.Text = $"{Device.Name}_批量检测";
// frmMLBatchRun.Show();
//}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -29,6 +29,13 @@
private void InitializeComponent()
{
panel1 = new AntdUI.Panel();
select_Result = new AntdUI.Select();
label5 = new AntdUI.Label();
input_maxArea = new AntdUI.InputNumber();
label3 = new AntdUI.Label();
input_minArea = new AntdUI.InputNumber();
label4 = new AntdUI.Label();
input_maxScore = new AntdUI.InputNumber();
label2 = new AntdUI.Label();
input_minScore = new AntdUI.InputNumber();
label1 = new AntdUI.Label();
@ -38,13 +45,6 @@
stackPanel1 = new AntdUI.StackPanel();
button_cancel = new AntdUI.Button();
button_ok = new AntdUI.Button();
input_maxScore = new AntdUI.InputNumber();
input_maxArea = new AntdUI.InputNumber();
label3 = new AntdUI.Label();
input_minArea = new AntdUI.InputNumber();
label4 = new AntdUI.Label();
label5 = new AntdUI.Label();
select_Result = new AntdUI.Select();
panel1.SuspendLayout();
stackPanel1.SuspendLayout();
SuspendLayout();
@ -74,6 +74,87 @@
panel1.TabIndex = 0;
panel1.Text = "panel1";
//
// select_Result
//
select_Result.Dock = DockStyle.Top;
select_Result.Location = new Point(18, 408);
select_Result.Name = "select_Result";
select_Result.Size = new Size(464, 41);
select_Result.TabIndex = 27;
select_Result.Text = "select1";
//
// label5
//
label5.Dock = DockStyle.Top;
label5.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
label5.Location = new Point(18, 384);
label5.Name = "label5";
label5.Size = new Size(464, 24);
label5.TabIndex = 25;
label5.Text = "标签结果";
//
// input_maxArea
//
input_maxArea.Dock = DockStyle.Top;
input_maxArea.Font = new Font("Microsoft YaHei UI", 9F);
input_maxArea.Increment = new decimal(new int[] { 10, 0, 0, 0 });
input_maxArea.Location = new Point(18, 346);
input_maxArea.Maximum = new decimal(new int[] { 999999999, 0, 0, 0 });
input_maxArea.Minimum = new decimal(new int[] { 0, 0, 0, 0 });
input_maxArea.Name = "input_maxArea";
input_maxArea.Radius = 3;
input_maxArea.Size = new Size(464, 38);
input_maxArea.TabIndex = 24;
input_maxArea.Text = "0";
//
// label3
//
label3.Dock = DockStyle.Top;
label3.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
label3.Location = new Point(18, 322);
label3.Name = "label3";
label3.Size = new Size(464, 24);
label3.TabIndex = 23;
label3.Text = "最大面积";
//
// input_minArea
//
input_minArea.Dock = DockStyle.Top;
input_minArea.Font = new Font("Microsoft YaHei UI", 9F);
input_minArea.Increment = new decimal(new int[] { 10, 0, 0, 0 });
input_minArea.Location = new Point(18, 284);
input_minArea.Maximum = new decimal(new int[] { 999999999, 0, 0, 0 });
input_minArea.Minimum = new decimal(new int[] { 0, 0, 0, 0 });
input_minArea.Name = "input_minArea";
input_minArea.Radius = 3;
input_minArea.Size = new Size(464, 38);
input_minArea.TabIndex = 22;
input_minArea.Text = "0";
//
// label4
//
label4.Dock = DockStyle.Top;
label4.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
label4.Location = new Point(18, 260);
label4.Name = "label4";
label4.Size = new Size(464, 24);
label4.TabIndex = 21;
label4.Text = "最小面积";
//
// input_maxScore
//
input_maxScore.Dock = DockStyle.Top;
input_maxScore.Font = new Font("Microsoft YaHei UI", 9F);
input_maxScore.Increment = new decimal(new int[] { 1, 0, 0, 65536 });
input_maxScore.Location = new Point(18, 222);
input_maxScore.Maximum = new decimal(new int[] { 1, 0, 0, 0 });
input_maxScore.Minimum = new decimal(new int[] { 0, 0, 0, 0 });
input_maxScore.Name = "input_maxScore";
input_maxScore.Radius = 3;
input_maxScore.Size = new Size(464, 38);
input_maxScore.TabIndex = 20;
input_maxScore.Text = "0";
//
// label2
//
label2.Dock = DockStyle.Top;
@ -96,7 +177,7 @@
input_minScore.Radius = 3;
input_minScore.Size = new Size(464, 38);
input_minScore.TabIndex = 18;
input_minScore.Text = "0.3";
input_minScore.Text = "0";
//
// label1
//
@ -169,86 +250,6 @@
button_ok.Text = "Submit";
button_ok.Type = AntdUI.TTypeMini.Primary;
//
// input_maxScore
//
input_maxScore.Dock = DockStyle.Top;
input_maxScore.Font = new Font("Microsoft YaHei UI", 9F);
input_maxScore.Increment = new decimal(new int[] { 1, 0, 0, 65536 });
input_maxScore.Location = new Point(18, 222);
input_maxScore.Maximum = new decimal(new int[] { 1, 0, 0, 0 });
input_maxScore.Minimum = new decimal(new int[] { 0, 0, 0, 0 });
input_maxScore.Name = "input_maxScore";
input_maxScore.Radius = 3;
input_maxScore.Size = new Size(464, 38);
input_maxScore.TabIndex = 20;
input_maxScore.Text = "0";
//
// input_maxArea
//
input_maxArea.Dock = DockStyle.Top;
input_maxArea.Font = new Font("Microsoft YaHei UI", 9F);
input_maxArea.Increment = new decimal(new int[] { 10, 0, 0, 0 });
input_maxArea.Location = new Point(18, 346);
input_maxArea.Maximum = new decimal(new int[] { 999999999, 0, 0, 0 });
input_maxArea.Minimum = new decimal(new int[] { 0, 0, 0, 0 });
input_maxArea.Name = "input_maxArea";
input_maxArea.Radius = 3;
input_maxArea.Size = new Size(464, 38);
input_maxArea.TabIndex = 24;
input_maxArea.Text = "0";
//
// label3
//
label3.Dock = DockStyle.Top;
label3.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
label3.Location = new Point(18, 322);
label3.Name = "label3";
label3.Size = new Size(464, 24);
label3.TabIndex = 23;
label3.Text = "最大面积";
//
// input_minArea
//
input_minArea.Dock = DockStyle.Top;
input_minArea.Font = new Font("Microsoft YaHei UI", 9F);
input_minArea.Increment = new decimal(new int[] { 10, 0, 0, 0 });
input_minArea.Location = new Point(18, 284);
input_minArea.Maximum = new decimal(new int[] { 999999999, 0, 0, 0 });
input_minArea.Minimum = new decimal(new int[] { 0, 0, 0, 0 });
input_minArea.Name = "input_minArea";
input_minArea.Radius = 3;
input_minArea.Size = new Size(464, 38);
input_minArea.TabIndex = 22;
input_minArea.Text = "0";
//
// label4
//
label4.Dock = DockStyle.Top;
label4.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
label4.Location = new Point(18, 260);
label4.Name = "label4";
label4.Size = new Size(464, 24);
label4.TabIndex = 21;
label4.Text = "最小面积";
//
// label5
//
label5.Dock = DockStyle.Top;
label5.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
label5.Location = new Point(18, 384);
label5.Name = "label5";
label5.Size = new Size(464, 24);
label5.TabIndex = 25;
label5.Text = "标签结果";
//
// select_Result
//
select_Result.Location = new Point(21, 414);
select_Result.Name = "select_Result";
select_Result.Size = new Size(458, 41);
select_Result.TabIndex = 27;
select_Result.Text = "select1";
//
// DefectRowEdit
//
Controls.Add(panel1);

View File

@ -42,7 +42,7 @@ namespace AntdUIDemo.Views.Table
if (String.IsNullOrEmpty(input_name.Text))
{
input_name.Status = AntdUI.TType.Error;
AntdUI.Message.warn(window, "姓名不能为空!", autoClose: 3);
AntdUI.Message.warn(window, "标签不能为空!", autoClose: 3);
return;
}
user.LabelDescription = input_name.Text;
@ -57,6 +57,9 @@ namespace AntdUIDemo.Views.Table
input_name.Text = user.LabelDescription;
// input_addr.Text = user.Address;
input_minScore.Value =(decimal) user.ScoreMinValue;
input_maxScore.Value =(decimal) user.ScoreMaxValue;
input_minArea.Value =(decimal) user.ScoreMaxValue;
input_maxScore.Value =(decimal) user.ScoreMaxValue;
}
}
}

View File

@ -29,90 +29,211 @@
private void InitializeComponent()
{
panel1 = new Panel();
panel3 = new Panel();
label6 = new AntdUI.Label();
cbxDetectType = new AntdUI.Select();
label1 = new AntdUI.Label();
tbDetectName = new AntdUI.Input();
btnPreOpen = new AntdUI.Button();
tbModelpath = new AntdUI.Input();
button3 = new AntdUI.Button();
switchEnable = new AntdUI.Switch();
label8 = new AntdUI.Label();
label10 = new AntdUI.Label();
sthPic = new AntdUI.Switch();
sthSaveNGPic = new AntdUI.Switch();
label7 = new AntdUI.Label();
label9 = new AntdUI.Label();
swSaveOKPic = new AntdUI.Switch();
panel2 = new Panel();
label2 = new Label();
label2 = new AntdUI.Label();
buttonDEL = new AntdUI.Button();
table_base = new AntdUI.Table();
buttonADD = new AntdUI.Button();
label10 = new AntdUI.Label();
sthSaveNGPic = new AntdUI.Switch();
label9 = new AntdUI.Label();
swSaveOKPic = new AntdUI.Switch();
label7 = new AntdUI.Label();
sthPic = new AntdUI.Switch();
label8 = new AntdUI.Label();
switchEnable = new AntdUI.Switch();
tbDetectName = new TextBox();
label6 = new AntdUI.Label();
cbxDetectType = new ComboBox();
label5 = new AntdUI.Label();
btnPreOpen = new AntdUI.Button();
tbModelpath = new TextBox();
label1 = new AntdUI.Label();
panel1.SuspendLayout();
panel3.SuspendLayout();
panel2.SuspendLayout();
SuspendLayout();
//
// panel1
//
panel1.BorderStyle = BorderStyle.FixedSingle;
panel1.Controls.Add(button3);
panel1.Controls.Add(panel3);
panel1.Controls.Add(panel2);
panel1.Controls.Add(label10);
panel1.Controls.Add(sthSaveNGPic);
panel1.Controls.Add(label9);
panel1.Controls.Add(swSaveOKPic);
panel1.Controls.Add(label7);
panel1.Controls.Add(sthPic);
panel1.Controls.Add(label8);
panel1.Controls.Add(switchEnable);
panel1.Controls.Add(tbDetectName);
panel1.Controls.Add(label6);
panel1.Controls.Add(cbxDetectType);
panel1.Controls.Add(label5);
panel1.Controls.Add(btnPreOpen);
panel1.Controls.Add(tbModelpath);
panel1.Controls.Add(label1);
panel1.Dock = DockStyle.Fill;
panel1.Location = new Point(0, 0);
panel1.Name = "panel1";
panel1.Size = new Size(683, 445);
panel1.Size = new Size(600, 445);
panel1.TabIndex = 0;
//
// panel3
//
panel3.Controls.Add(label6);
panel3.Controls.Add(cbxDetectType);
panel3.Controls.Add(label1);
panel3.Controls.Add(tbDetectName);
panel3.Controls.Add(btnPreOpen);
panel3.Controls.Add(tbModelpath);
panel3.Controls.Add(button3);
panel3.Controls.Add(switchEnable);
panel3.Controls.Add(label8);
panel3.Controls.Add(label10);
panel3.Controls.Add(sthPic);
panel3.Controls.Add(sthSaveNGPic);
panel3.Controls.Add(label7);
panel3.Controls.Add(label9);
panel3.Controls.Add(swSaveOKPic);
panel3.Dock = DockStyle.Fill;
panel3.Location = new Point(0, 0);
panel3.Name = "panel3";
panel3.Size = new Size(598, 206);
panel3.TabIndex = 41;
//
// label6
//
label6.Location = new Point(3, 15);
label6.Name = "label6";
label6.Size = new Size(58, 23);
label6.TabIndex = 25;
label6.Text = "检测名称";
//
// cbxDetectType
//
cbxDetectType.Anchor = AnchorStyles.Top | AnchorStyles.Right;
cbxDetectType.Location = new Point(341, 7);
cbxDetectType.Name = "cbxDetectType";
cbxDetectType.Size = new Size(226, 31);
cbxDetectType.TabIndex = 40;
//
// label1
//
label1.Location = new Point(3, 44);
label1.Name = "label1";
label1.Size = new Size(73, 23);
label1.TabIndex = 9;
label1.Text = "模型路径";
//
// tbDetectName
//
tbDetectName.Location = new Point(82, 7);
tbDetectName.Name = "tbDetectName";
tbDetectName.Size = new Size(249, 31);
tbDetectName.TabIndex = 39;
//
// btnPreOpen
//
btnPreOpen.Anchor = AnchorStyles.Top | AnchorStyles.Right;
btnPreOpen.Location = new Point(507, 36);
btnPreOpen.MinimumSize = new Size(20, 0);
btnPreOpen.Name = "btnPreOpen";
btnPreOpen.Size = new Size(60, 31);
btnPreOpen.TabIndex = 22;
btnPreOpen.Text = "...";
//
// tbModelpath
//
tbModelpath.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tbModelpath.Location = new Point(82, 36);
tbModelpath.Name = "tbModelpath";
tbModelpath.Size = new Size(415, 31);
tbModelpath.TabIndex = 38;
//
// button3
//
button3.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
button3.Location = new Point(538, 70);
button3.Anchor = AnchorStyles.Top | AnchorStyles.Right;
button3.Location = new Point(385, 73);
button3.Name = "button3";
button3.Size = new Size(115, 34);
button3.Size = new Size(182, 34);
button3.TabIndex = 37;
button3.Text = "查看文件夹";
//
// switchEnable
//
switchEnable.Location = new Point(82, 84);
switchEnable.Name = "switchEnable";
switchEnable.Size = new Size(60, 23);
switchEnable.TabIndex = 27;
switchEnable.Text = "switch1";
//
// label8
//
label8.Location = new Point(3, 84);
label8.Name = "label8";
label8.Size = new Size(58, 23);
label8.TabIndex = 28;
label8.Text = "模型启用";
//
// label10
//
label10.Location = new Point(176, 113);
label10.Name = "label10";
label10.Size = new Size(73, 23);
label10.TabIndex = 34;
label10.Text = "保存NG原图";
//
// sthPic
//
sthPic.Location = new Point(263, 84);
sthPic.Name = "sthPic";
sthPic.Size = new Size(60, 23);
sthPic.TabIndex = 29;
sthPic.Text = "switch2";
//
// sthSaveNGPic
//
sthSaveNGPic.Location = new Point(263, 113);
sthSaveNGPic.Name = "sthSaveNGPic";
sthSaveNGPic.Size = new Size(60, 23);
sthSaveNGPic.TabIndex = 33;
sthSaveNGPic.Text = "switch4";
//
// label7
//
label7.Location = new Point(184, 84);
label7.Name = "label7";
label7.Size = new Size(58, 23);
label7.TabIndex = 30;
label7.Text = "数据保存";
//
// label9
//
label9.Location = new Point(3, 113);
label9.Name = "label9";
label9.Size = new Size(73, 23);
label9.TabIndex = 32;
label9.Text = "保存OK原图";
//
// swSaveOKPic
//
swSaveOKPic.Location = new Point(82, 113);
swSaveOKPic.Name = "swSaveOKPic";
swSaveOKPic.Size = new Size(60, 23);
swSaveOKPic.TabIndex = 31;
swSaveOKPic.Text = "switch3";
//
// panel2
//
panel2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
panel2.Controls.Add(label2);
panel2.Controls.Add(buttonDEL);
panel2.Controls.Add(table_base);
panel2.Controls.Add(buttonADD);
panel2.Location = new Point(17, 141);
panel2.Dock = DockStyle.Bottom;
panel2.Location = new Point(0, 206);
panel2.Name = "panel2";
panel2.Size = new Size(639, 286);
panel2.Size = new Size(598, 237);
panel2.TabIndex = 35;
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(3, 5);
label2.Location = new Point(3, 3);
label2.Name = "label2";
label2.Size = new Size(56, 17);
label2.TabIndex = 25;
label2.Size = new Size(58, 23);
label2.TabIndex = 29;
label2.Text = "模型参数";
//
// buttonDEL
//
buttonDEL.Location = new Point(93, 25);
buttonDEL.Location = new Point(93, 28);
buttonDEL.Name = "buttonDEL";
buttonDEL.Size = new Size(84, 34);
buttonDEL.TabIndex = 24;
@ -121,152 +242,30 @@
// table_base
//
table_base.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
table_base.Location = new Point(3, 65);
table_base.Location = new Point(0, 68);
table_base.Name = "table_base";
table_base.Size = new Size(633, 218);
table_base.Size = new Size(598, 169);
table_base.TabIndex = 22;
table_base.Text = "table1";
//
// buttonADD
//
buttonADD.Location = new Point(3, 25);
buttonADD.Location = new Point(3, 28);
buttonADD.Name = "buttonADD";
buttonADD.Size = new Size(84, 34);
buttonADD.TabIndex = 23;
buttonADD.Text = "新增";
//
// label10
//
label10.Location = new Point(171, 99);
label10.Name = "label10";
label10.Size = new Size(73, 23);
label10.TabIndex = 34;
label10.Text = "保存NG原图";
//
// sthSaveNGPic
//
sthSaveNGPic.Location = new Point(258, 99);
sthSaveNGPic.Name = "sthSaveNGPic";
sthSaveNGPic.Size = new Size(57, 23);
sthSaveNGPic.TabIndex = 33;
sthSaveNGPic.Text = "switch4";
//
// label9
//
label9.Location = new Point(17, 99);
label9.Name = "label9";
label9.Size = new Size(73, 23);
label9.TabIndex = 32;
label9.Text = "保存OK原图";
//
// swSaveOKPic
//
swSaveOKPic.Location = new Point(96, 99);
swSaveOKPic.Name = "swSaveOKPic";
swSaveOKPic.Size = new Size(57, 23);
swSaveOKPic.TabIndex = 31;
swSaveOKPic.Text = "switch3";
//
// label7
//
label7.Location = new Point(179, 70);
label7.Name = "label7";
label7.Size = new Size(58, 23);
label7.TabIndex = 30;
label7.Text = "数据保存";
//
// sthPic
//
sthPic.Location = new Point(258, 70);
sthPic.Name = "sthPic";
sthPic.Size = new Size(57, 23);
sthPic.TabIndex = 29;
sthPic.Text = "switch2";
//
// label8
//
label8.Location = new Point(17, 70);
label8.Name = "label8";
label8.Size = new Size(58, 23);
label8.TabIndex = 28;
label8.Text = "模型启用";
//
// switchEnable
//
switchEnable.Location = new Point(96, 70);
switchEnable.Name = "switchEnable";
switchEnable.Size = new Size(57, 23);
switchEnable.TabIndex = 27;
switchEnable.Text = "switch1";
//
// tbDetectName
//
tbDetectName.Location = new Point(96, 12);
tbDetectName.Name = "tbDetectName";
tbDetectName.Size = new Size(211, 23);
tbDetectName.TabIndex = 26;
//
// label6
//
label6.Location = new Point(17, 12);
label6.Name = "label6";
label6.Size = new Size(58, 23);
label6.TabIndex = 25;
label6.Text = "检测名称";
//
// cbxDetectType
//
cbxDetectType.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
cbxDetectType.DropDownStyle = ComboBoxStyle.DropDownList;
cbxDetectType.FormattingEnabled = true;
cbxDetectType.Location = new Point(402, 10);
cbxDetectType.Name = "cbxDetectType";
cbxDetectType.Size = new Size(254, 25);
cbxDetectType.TabIndex = 24;
//
// label5
//
label5.Location = new Point(333, 12);
label5.Name = "label5";
label5.Size = new Size(73, 23);
label5.TabIndex = 23;
label5.Text = "目标类型";
//
// btnPreOpen
//
btnPreOpen.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
btnPreOpen.Location = new Point(613, 41);
btnPreOpen.Name = "btnPreOpen";
btnPreOpen.Size = new Size(43, 23);
btnPreOpen.TabIndex = 22;
btnPreOpen.Text = "...";
//
// tbModelpath
//
tbModelpath.Location = new Point(96, 41);
tbModelpath.Name = "tbModelpath";
tbModelpath.Size = new Size(511, 23);
tbModelpath.TabIndex = 17;
//
// label1
//
label1.Location = new Point(17, 41);
label1.Name = "label1";
label1.Size = new Size(73, 23);
label1.TabIndex = 9;
label1.Text = "模型路径";
//
// DetectConfigControl
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(panel1);
Name = "DetectConfigControl";
Size = new Size(683, 445);
Size = new Size(600, 445);
panel1.ResumeLayout(false);
panel1.PerformLayout();
panel3.ResumeLayout(false);
panel2.ResumeLayout(false);
panel2.PerformLayout();
ResumeLayout(false);
}
@ -274,11 +273,7 @@
private Panel panel1;
private AntdUI.Label label1;
private TextBox tbModelpath;
private TextBox tbDetectName;
private AntdUI.Label label6;
private ComboBox cbxDetectType;
private AntdUI.Label label5;
private AntdUI.Button btnPreOpen;
private AntdUI.Label label7;
private AntdUI.Switch sthPic;
@ -289,10 +284,14 @@
private AntdUI.Label label9;
private AntdUI.Switch swSaveOKPic;
private Panel panel2;
private Label label2;
private AntdUI.Button buttonDEL;
private AntdUI.Table table_base;
private AntdUI.Button buttonADD;
private AntdUI.Button button3;
private AntdUI.Input tbDetectName;
private AntdUI.Input tbModelpath;
private AntdUI.Label label2;
private AntdUI.Select cbxDetectType;
private Panel panel3;
}
}

View File

@ -1,5 +1,6 @@
using AntdUI;
using AntdUIDemo.Views.Table;
using DH.Commons.Enums;
using DH.Devices.Vision;
using DHSoftware.Models;
using System;
@ -148,12 +149,12 @@ namespace DHSoftware.Views
},
new ColumnSwitch("IsEnable", "是否启用", ColumnAlign.Center){
//支持点击回调
Call= (value,record, i_row, i_col) =>{
//执行耗时操作
Thread.Sleep(1000);
// AntdUI.Message.info(window, value.ToString(),autoClose:1);
return value;
}
//Call= (value,record, i_row, i_col) =>{
// //执行耗时操作
// Thread.Sleep(10);
// // AntdUI.Message.info(window, value.ToString(),autoClose:1);
// return value;
//}
},
new Column("ScoreMinValue", "最小得分",ColumnAlign.Center),
new Column("ScoreMaxValue", "最大得分",ColumnAlign.Center),
@ -222,7 +223,12 @@ namespace DHSoftware.Views
{
DefectRow useradd = new DefectRow()
{
LabelDescription="xinquexian"
LabelDescription="xinquexian",
IsEnable=true,
ScoreMinValue=0.3,
ScoreMaxValue=1,
AreaMinValue=1,
AreaMaxValue=999999999,
};
var form = new DefectRowEdit(_window, useradd) { Size = new Size(700, 500) };
@ -361,87 +367,87 @@ namespace DHSoftware.Views
//表格内部按钮事件
private void Table_base_CellButtonClick(object sender, TableButtonEventArgs e)
{
//var buttontext = e.Btn.Text;
var buttontext = e.Btn.Text;
//if (e.Record is User user)
//{
// curUser = user;
// switch (buttontext)
// {
// //暂不支持进入整行编辑,只支持指定单元格编辑,推荐使用弹窗或抽屉编辑整行数据
// case "编辑":
// var form = new UserEdit(window, user) { Size = new Size(500, 300) };
// AntdUI.Drawer.open(new AntdUI.Drawer.Config(window, form)
// {
// OnLoad = () =>
// {
// AntdUI.Message.info(window, "进入编辑", autoClose: 1);
// },
// OnClose = () =>
// {
// AntdUI.Message.info(window, "结束编辑", autoClose: 1);
// }
// });
// break;
// case "删除":
// var result = Modal.open(window, "删除警告!", "确认要删除选择的数据吗?", TType.Warn);
// if (result == DialogResult.OK)
// antList.Remove(user);
// break;
// case "AntdUI":
// //超链接内容
// AntdUI.Message.info(window, user.CellLinks.FirstOrDefault().Id, autoClose: 1);
// break;
// case "查看图片":
// //使用clone可以防止table中的image被修改
// Preview.open(new Preview.Config(window, (Image)curUser.CellImages[0].Image.Clone()));
// break;
// }
//}
if (e.Record is DefectRow user)
{
curUser = user;
switch (buttontext)
{
//暂不支持进入整行编辑,只支持指定单元格编辑,推荐使用弹窗或抽屉编辑整行数据
case "编辑":
var form = new DefectRowEdit(_window, user) { Size = new Size(500, 300) };
AntdUI.Drawer.open(new AntdUI.Drawer.Config(_window, form)
{
OnLoad = () =>
{
AntdUI.Message.info(_window, "进入编辑", autoClose: 1);
},
OnClose = () =>
{
AntdUI.Message.info(_window, "结束编辑", autoClose: 1);
}
});
break;
case "删除":
var result = Modal.open(_window, "删除警告!", "确认要删除选择的数据吗?", TType.Warn);
if (result == DialogResult.OK)
antList.Remove(user);
break;
case "AntdUI":
//超链接内容
// AntdUI.Message.info(_window, user.CellLinks.FirstOrDefault().Id, autoClose: 1);
break;
case "查看图片":
//使用clone可以防止table中的image被修改
// Preview.open(new Preview.Config(window, (Image)curUser.CellImages[0].Image.Clone()));
break;
}
}
}
private void ButtonDEL_Click(object sender, EventArgs e)
{
//if (antList.Count == 0 || !antList.Any(x => x.Selected))
//{
// bool isSubSelected = false;
// // 判断子元素是否勾选
// for (int i = 0; i < antList.Count; i++)
// {
// if (antList[i].Users != null && antList[i].Users.Any(x => x.Selected))
// {
// isSubSelected = true;
// break;
// }
// }
// if (!isSubSelected)
// {
// AntdUI.Message.warn(window, "请选择要删除的行!", autoClose: 3);
// return;
// }
//}
if (antList.Count == 0 || !antList.Any(x => x.Selected))
{
bool isSubSelected = false;
//// 判断子元素是否勾选
//for (int i = 0; i < antList.Count; i++)
//{
// if (antList[i].Users != null && antList[i].Users.Any(x => x.Selected))
// {
// isSubSelected = true;
// break;
// }
//}
if (!isSubSelected)
{
AntdUI.Message.warn(_window, "请选择要删除的行!", autoClose: 3);
return;
}
}
//var result = Modal.open(window, "删除警告!", "确认要删除选择的数据吗?", TType.Warn);
//if (result == DialogResult.OK)
//{
// // 使用反转for循环删除主列表中选中的项
// for (int i = antList.Count - 1; i >= 0; i--)
// {
// // 删除选中的主列表项
// if (antList[i].Selected)
// {
// antList.RemoveAt(i);
// }
// else
// {
// // 删除子列表中选中的项
// antList[i].Users = antList[i].Users?.Where(user => !user.Selected).ToArray();
// }
// }
// // 提示删除完成
// // AntdUI.Message.success(this.w, "删除成功!", autoClose: 3);
// MessageBox.Show("删除成功!");
//}
var result = Modal.open(_window, "删除警告!", "确认要删除选择的数据吗?", TType.Warn);
if (result == DialogResult.OK)
{
// 使用反转for循环删除主列表中选中的项
for (int i = antList.Count - 1; i >= 0; i--)
{
// 删除选中的主列表项
if (antList[i].Selected)
{
antList.RemoveAt(i);
}
else
{
// 删除子列表中选中的项
// antList[i].Users = antList[i].Users?.Where(user => !user.Selected).ToArray();
}
}
// 提示删除完成
// AntdUI.Message.success(this.w, "删除成功!", autoClose: 3);
MessageBox.Show("删除成功!");
}
}

View File

@ -8,6 +8,7 @@ using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using AntdUI;
using DH.Commons.Enums;
using DH.Devices.Devices;
using DH.Devices.Vision;

View File

@ -1,5 +1,6 @@
using AntdUI;
using AntdUIDemo.Models;
using DH.Commons.Enums;
using DH.Devices.Devices;
using DH.Devices.Vision;
using System;
@ -198,8 +199,8 @@ namespace DHSoftware.Views
int width = tabs.Width;
int height = tabs.Height;
// 创建新 TabPage
UserDetetion control = new UserDetetion(width, height);
control._windows = Window;
UserDetetion control = new UserDetetion(Window,width, height);
// control._windows = Window;
switch (name)
{
case "工位1":

View File

@ -17,9 +17,10 @@ namespace DHSoftware.Views
private StackPanel panel, panel2, panel3, panel4;
public Window _windows;
//根据检测配置 将对应的相机配置、中处理预处理、尺寸测量
public UserDetetion(int parentWidth, int parentHeight)
public UserDetetion(Window windows,int parentWidth, int parentHeight)
{
InitializeComponent();
_windows = windows;
AntdUI.CollapseItem group1 = new CollapseItem();
group1.Height = parentHeight / 4;
group1.Text = "相机配置";
@ -214,7 +215,7 @@ namespace DHSoftware.Views
// 遍历 panel 的 Controls找到最后一个 CameraConfigControl 并移除
for (int i = panel3.Controls.Count - 1; i >= 0; i--)
{
if (panel3.Controls[i] is CameraConfigControl)
if (panel3.Controls[i] is DetectConfigControl)
{
panel3.Controls.RemoveAt(i);
break; // 只删除一个

View File

@ -1,4 +1,5 @@
using DH.Devices.Vision;
using DH.Commons.Enums;
using DH.Devices.Vision;
using System;
using System.Collections.Generic;
using System.Linq;