10 Commits

Author SHA1 Message Date
6182dc2192 Merge branch 'KM' of https://gitea.star-rising.cn/xiaohuimin/DHDHSoftware into KM 2025-04-16 08:52:56 +08:00
28e15a556d 1111 2025-04-16 08:52:53 +08:00
TD
d2f3b3f3aa 修改 2025-04-16 08:47:59 +08:00
TD
b009a7355b 修改日志1 2025-04-15 09:24:39 +08:00
TD
72b67b6a2f 修改合并界面 2025-04-11 14:15:03 +08:00
TD
8a0668ed96 解决合并冲突 2025-04-11 11:52:29 +08:00
TD
e31a890b06 修改图片保存路径 2025-04-11 11:47:29 +08:00
428896dbf8 修改保存相机原图和保存结果图命名一致 2025-04-11 11:09:55 +08:00
TD
f9d472295b 1 2025-04-11 10:42:40 +08:00
4765e0e5bd 修改统计 2025-04-10 14:08:55 +08:00
32 changed files with 2817 additions and 1103 deletions

View File

@ -343,7 +343,18 @@ namespace DH.Commons.Base
}
// 其他方法保持原有逻辑
public Action<DateTime, CameraBase, Mat> OnHImageOutput { get; set; }
public MatSet CopyImageSet(MatSet srcSet)
{
MatSet imageSet = new MatSet
{
Id = srcSet.Id,
_mat = srcSet._mat.Clone(),
// ImageSaveOption = srcSet.ImageSaveOption.Copy(),
ImageTime = srcSet.ImageTime
};
return imageSet;
}
public Action<DateTime, CameraBase, MatSet> OnHImageOutput { get; set; }
public virtual bool CameraConnect() { return false; }

View File

@ -488,6 +488,7 @@ namespace DH.Commons.Base
#region
private string _id = Guid.NewGuid().ToString();
private string _name;
private EnumDetectionType _detectionType= EnumDetectionType.;
private string _cameraSourceId = "";
private List<RelatedCamera> _cameraCollects = new List<RelatedCamera>();
private bool _isEnableGPU;
@ -509,7 +510,7 @@ namespace DH.Commons.Base
private AntList<SizeTreatParam> _sizeTreatParamList = new AntList<SizeTreatParam>();
private CustomizedPoint _showLocation = new CustomizedPoint();
private string _imageSaveDirectory="D://Images";
private string _imageSaveDirectory= "D://PROJECTS//Images//";
private bool _saveOKOriginal = false;
private bool _saveNGOriginal = false;
private bool _saveOKDetect = false;
@ -789,7 +790,19 @@ namespace DH.Commons.Base
}
}
[Category("检测配置")]
[DisplayName("检测类型")]
[Description("检测类型")]
public EnumDetectionType DetectionType
{
get => _detectionType;
set
{
if (_detectionType == value) return;
_detectionType = value;
OnPropertyChanged(nameof(DetectionType));
}
}
[Category("显示配置")]
[DisplayName("显示位置")]
@ -1072,6 +1085,15 @@ namespace DH.Commons.Base
OnPropertyChanged(nameof(CellLinks));
}
}
public bool FilterOperation(DetectionResultDetail recongnitionResult)
{
double compareValue = recongnitionResult.Area;
double compareScoreValue = recongnitionResult.Score;
return (compareValue >= MinArea && compareValue <= MaxArea)&& (compareScoreValue >= MinScore && compareScoreValue <= MaxScore);
}
}
public class SizeTreatParam : NotifyProperty

View File

@ -305,7 +305,7 @@ namespace DH.Commons.Base
//if (InitialConfig.IsEnableLog)
//{
// LoggerHelper.LogAsync(msg);
LoggerHelper.LogAsync(msg);
//}
}

View File

@ -36,7 +36,7 @@ namespace DH.Commons.Base
public HTuple hv_ModelID;
public abstract DetectStationResult RunInference(Mat originImgSet, string detectionId = null);
public abstract DetectStationResult RunInference(MatSet originImgSet, string detectionId = null);
//public abstract void SaveDetectResultAsync(DetectStationResult detectResult);

View File

@ -12,6 +12,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AntdUI" Version="1.8.9" />

View File

@ -141,6 +141,14 @@ namespace DH.Commons.Enums
False,
True
}
public enum EnumDetectionType
{
,
}
public enum StreamFormat
{
[Description("8位图像")]

View File

@ -375,6 +375,22 @@ namespace DH.Commons.Enums
[Description("异常")]
DSExcept = 32
}
public enum RunState
{
[ColorSelect("Gold")]
[Description("空闲")]
Idle = 1,
[ColorSelect("Lime")]
[Description("运行中")]
Running = 2,
[ColorSelect("Gray")]
[Description("停止")]
Stop = 3,
[ColorSelect("Red")]
[Description("宕机")]
Down = 99,
}
public enum PriorityDirection
{
X,

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DH.Commons.Models
{
public class CameraSummary
{
public string CameraName { get; set; } // 相机名称
public int TiggerCount { get; set; } //触发数
public int OKCount { get; set; } // OK 数
public int NGCount { get; set; } // NG 数
public int TotalCount => OKCount + NGCount; // 总检测数量
public string YieldStr => $"{Yield:f2} %"; // 良率(字符串形式)
public double Yield => OKCount + NGCount > 0 ? (double)OKCount / (OKCount + NGCount) * 100 : 0;
}
public class ProductSummary
{
public int ProductAmount { get; set; }
public string ResultDesc { get; set; }
public string PercentStr { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection.Metadata;
using System.Xml.Linq;
@ -9,6 +10,7 @@ using DVPCameraType;
using OpenCvSharp;
using OpenCvSharp.Extensions;
using static System.Net.Mime.MediaTypeNames;
using static MvCamCtrl.NET.MyCamera;
using LogLevel = DH.Commons.Enums.EnumHelper.LogLevel;
@ -38,7 +40,7 @@ namespace DH.Devices.Camera
{
LoggerHelper.LogPath = "D://";
LoggerHelper.LogPrefix = CameraName;
}
@ -61,6 +63,7 @@ namespace DH.Devices.Camera
{
try
{
pCallBackFunc = new DVPCamera.dvpEventCallback(cbExceptiondelegate);
nRet = DVPCamera.dvpOpenByUserId(CameraName,
dvpOpenMode.OPEN_NORMAL,
ref m_handle);
@ -81,13 +84,13 @@ namespace DH.Devices.Camera
nRet = DVPCamera.dvpGetCameraInfo(m_handle, ref camerainfo);
SerialNumber = camerainfo.SerialNumber;
// ch:注册异常回调函数 | en:Register Exception Callback
//nRet = DVPCamera.dvpRegisterEventCallback(m_handle, pCallBackFunc, dvpEvent.EVENT_DISCONNECTED, IntPtr.Zero);
//if (nRet != dvpStatus.DVP_STATUS_OK)
//{
// throw new Exception($"Register expection callback failed:{nRet}");
//}
//GC.KeepAlive(pCallBackFunc);
//ch: 注册异常回调函数 | en:Register Exception Callback
nRet = DVPCamera.dvpRegisterEventCallback(m_handle, pCallBackFunc, dvpEvent.EVENT_DISCONNECTED, IntPtr.Zero);
if (nRet != dvpStatus.DVP_STATUS_OK)
{
throw new Exception($"Register expection callback failed:{nRet}");
}
GC.KeepAlive(pCallBackFunc);
//// ch:设置采集连续模式 | en:Set Continues Aquisition Mode
if (IsContinueMode)
@ -152,7 +155,7 @@ namespace DH.Devices.Camera
SetGain(Gain);
}
//全画幅
if(!IsAllPicEnabled)
if (!IsAllPicEnabled)
SetPictureRoi((int)ROIX, (int)ROIY, (int)ROIW, (int)ROIH);
//// 设置 触发延迟
@ -190,7 +193,26 @@ namespace DH.Devices.Camera
}
/// <summary>
/// 回调函数
/// </summary>
/// <param name="handle"></param>
/// <param name="_event"></param>
/// <param name="pContext"></param>
/// <param name="param"></param>
/// <param name="refVariant"></param>
/// <returns></returns>
public int cbExceptiondelegate(uint handle, dvpEvent _event, IntPtr pContext, int param, ref dvpVariant refVariant)
{
if (_event == dvpEvent.EVENT_DISCONNECTED)
{
}
return dvpStatus.DVP_STATUS_OK.ToInt();
}
private void IIConfig_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
@ -329,7 +351,7 @@ namespace DH.Devices.Camera
Mat cvImage = new Mat();
if (this.CameraName.Equals("Cam1"))
{
Console.WriteLine( );
Console.WriteLine();
}
if (this.CameraName.Equals("Cam2"))
{
@ -369,13 +391,15 @@ namespace DH.Devices.Camera
{
_mat = smat,
};
InitialImageSet(imageSet);
OnHImageOutput?.Invoke(DateTime.Now, this, smat);
var outImgSet = CopyImageSet(imageSet);
OnHImageOutput?.Invoke(DateTime.Now, this, outImgSet);
//存图
DisplayAndSaveOriginImage(imageSet.Id,SnapshotCount);
DisplayAndSaveOriginImage(imageSet.Id, SnapshotCount);
@ -391,7 +415,7 @@ namespace DH.Devices.Camera
}
return 0;
}
public void InitialImageSet(MatSet set)
public void InitialImageSet(MatSet set)
{
//if (saveOption != null)
//{
@ -415,13 +439,25 @@ namespace DH.Devices.Camera
{
await Task.Run(() =>
{
Bitmap showImage = set._mat.ToBitmap();
Bitmap? showImage = null;
try
{
showImage = set._mat.ToBitmap();
}
catch (Exception)
{
//释放 himage
ClearImageSet(set);
return;
}
// showImage.Save("D:/test333.bmp");
// Marshal.Copy(pbyteImageBuffer, 0, (IntPtr)lAddrImage, (int)dwBufferSize);
// Bitmap saveImage = showImage?.CopyBitmap();
// Bitmap saveImage = showImage?.CopyBitmap();
// saveImage.Save("d://TEST444.BMP");
// OnShowImageUpdated?.Invoke(this, showImage, imgSetId);
if (IsSavePicEnabled)
// OnShowImageUpdated?.Invoke(this, showImage, imgSetId);
if (IsSavePicEnabled && showImage != null)
{
string fullname = Path.Combine(ImageSaveDirectory, $"{CameraName}_{_counter:D7}_{set.Id}.{set._imageFormat.ToString().ToLower()}");
ImageSaveAsync(fullname, showImage);
@ -466,7 +502,7 @@ namespace DH.Devices.Camera
{
FullName = fullName,
SaveImage = map,
};
ImageSaveHelper.ImageSaveAsync(imageSaveSet);
@ -475,31 +511,39 @@ namespace DH.Devices.Camera
{
try
{
dvpStreamState StreamState = new dvpStreamState();
nRet = DVPCamera.dvpGetStreamState(m_handle, ref StreamState);
//Debug.Assert(nRet == dvpStatus.DVP_STATUS_OK);
if (StreamState == dvpStreamState.STATE_STARTED)
// 1. 停止采集(如果正在运行)
dvpStreamState streamState = new dvpStreamState();
nRet = DVPCamera.dvpGetStreamState(m_handle, ref streamState);
if (streamState == dvpStreamState.STATE_STARTED)
{
// stop camera
// 先停止采集流
nRet = DVPCamera.dvpStop(m_handle);
Debug.Assert(nRet == dvpStatus.DVP_STATUS_OK);
if (nRet != dvpStatus.DVP_STATUS_OK)
{
throw new Exception($"Stop grabbing failed{nRet:x8}");
throw new Exception($"停止采集失败错误码0x{nRet:X8}");
}
}
// 2. 设置触发源为软件触发(此时设备已停止)
nRet = DVPCamera.dvpSetTriggerState(m_handle, false);
if (nRet != dvpStatus.DVP_STATUS_OK)
{
throw new Exception($"设置软件触发失败错误码0x{nRet:X8}");
}
// 3. 注销事件回调
nRet = DVPCamera.dvpUnregisterEventCallback(m_handle, pCallBackFunc, dvpEvent.EVENT_DISCONNECTED, IntPtr.Zero);
if (nRet != dvpStatus.DVP_STATUS_OK)
{
throw new Exception($"Unregister expection callback failed:{nRet}");
throw new Exception($"注销事件回调失败错误码0x{nRet:X8}");
}
// ch:关闭设备 | en:Close device
// 4. 关闭设备
nRet = DVPCamera.dvpClose(m_handle);
if (nRet != dvpStatus.DVP_STATUS_OK)
{
throw new Exception($"Close device failed{nRet:x8}");
throw new Exception($"关闭设备失败错误码0x{nRet:X8}");
}
m_handle = 0;
@ -525,7 +569,7 @@ namespace DH.Devices.Camera
LoggerHelper.LogAsync(msg);
}
}
public void LogAsync(DateTime dt, LogLevel logLevel, string msg)
public void LogAsync(DateTime dt, LogLevel logLevel, string msg)
{
LogAsync(new LogMsg(dt, logLevel, msg));
}

View File

@ -368,7 +368,7 @@ namespace DH.Devices.Camera
throw new NotSupportedException($"Unsupported pixel type: {pFrameInfo.enPixelType}");
}
OnHImageOutput?.Invoke(DateTime.Now, this, cvImage);
//OnHImageOutput?.Invoke(DateTime.Now, this, cvImage);
}
catch (Exception ex)

View File

@ -41,7 +41,7 @@ namespace DH.Devices.PLC
{
try
{
LoggerHelper.LogPath = "D://";
LoggerHelper.LogPath = "D://PROJECTS//Logs//";
LoggerHelper.LogPrefix = "PLC";
TcpNet.IpAddress = IP;

View File

@ -58,7 +58,7 @@ namespace DH.Devices.Vision
//{
// LogAsync(new LogMsg(dt, LogLevel.Error, msg));
//}
public override DetectStationResult RunInference(Mat originImgSet, string detectionId = null)
public override DetectStationResult RunInference(MatSet originImgSet, string detectionId = null)
{
DetectStationResult detectResult = new DetectStationResult();
DetectionConfig detectConfig = null;
@ -78,19 +78,20 @@ namespace DH.Devices.Vision
//未能获得检测配置
return detectResult;
}
detectResult.Id = originImgSet.Id;
detectResult.DetectName = detectConfig.Name;
detectResult.ImageSaveDirectory=detectConfig.ImageSaveDirectory;
detectResult.SaveNGDetect=detectConfig.SaveNGDetect;
detectResult.SaveNGOriginal=detectConfig.SaveNGOriginal;
detectResult.SaveOKDetect=detectConfig.SaveOKDetect;
detectResult.SaveOKOriginal=detectConfig.SaveOKOriginal;
Mat OriginImage = originImgSet.Clone();
Mat OriginImage = originImgSet._mat.Clone();
detectResult.DetectionOriginImage = CopyBitmapWithLockBits(OriginImage.ToBitmap());
//detectResult.DetectionOriginImage = originImgSet.Clone().ToBitmap();
Stopwatch sw = new Stopwatch();
#region 1.
sw.Start();
using (Mat PreTMat = originImgSet.Clone())
using (Mat PreTMat = originImgSet._mat.Clone())
{
PreTreated(detectConfig, detectResult, PreTMat);
PreTreated2(detectConfig, detectResult, PreTMat);
@ -142,7 +143,7 @@ namespace DH.Devices.Vision
req.ResizeHeight = (int)detectConfig.ModelHeight;
// req.LabelNames = detectConfig.GetLabelNames();
// req.Score = IIConfig.Score;
req.mImage = originImgSet.Clone();
req.mImage = originImgSet._mat.Clone();
req.in_lable_path = detectConfig.In_lable_path;
@ -170,41 +171,10 @@ namespace DH.Devices.Vision
// LogAsync(DateTime.Now, LogLevel.Information, $"{detectConfig.Name} 产品{detectResult.TempPid} RunInference BEGIN");
mlWatch.Start();
//20230802改成多线程推理 RunInferenceFixed
// MLResult result = new MLResult();
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();
@ -268,22 +238,22 @@ namespace DH.Devices.Vision
}
//foreach (IGrouping<ResultState, DetectionFilter> group in conditionList)
//{
// bool b = group.ToList().Any(f =>
// {
// return f.FilterOperation(d);
// });
foreach (IGrouping<ResultState, DetectionLable> group in conditionList)
{
bool b = group.ToList().Any(f =>
{
return f.FilterOperation(d);
});
// if (b)
// {
// d.FinalResult = group.Key;
// break;
// }
if (b)
{
d.FinalResult = group.Key;
break;
}
//}
}
});
#endregion
#region 5.NG
@ -308,7 +278,7 @@ namespace DH.Devices.Vision
DisplayDetectionResult(detectResult, originImgSet.Clone(), detectionId);
DisplayDetectionResult(detectResult, originImgSet._mat.Clone(), detectionId);
@ -455,7 +425,7 @@ namespace DH.Devices.Vision
{
// throw new ProcessException("异常:模型加载异常", null);
}
LogAsync(DateTime.Now, LogLevel.Information, $"模型加载成功是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}" + $" {dc.ModelType.GetEnumDescription()}:{dc.ModelPath}");
LogAsync(DateTime.Now, LogLevel.Action, $"模型加载成功是否GPU:{isGPU} CoreInx:{coreInx} - {dc.Name}" + $" {dc.ModelType.GetEnumDescription()}:{dc.ModelPath}");
}
}
catch (Exception ex)

View File

@ -12,9 +12,11 @@
<OutputType>WinExe</OutputType>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Services\AuthService.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="db\config.json">
@ -27,6 +29,15 @@
<ItemGroup>
<PackageReference Include="AntdUI" Version="1.8.9" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.185" />
@ -55,9 +66,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Folder Include="Services\" />
</ItemGroup>
<ItemGroup>
<None Include="db\db.sqlite">

File diff suppressed because it is too large Load Diff

View File

@ -23,9 +23,11 @@ using System;
using System.CodeDom;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
@ -37,6 +39,7 @@ using static DH.Commons.Enums.EnumHelper;
using Camera = DHSoftware.Models.Camera;
using LogLevel = DH.Commons.Enums.EnumHelper.LogLevel;
using ResultState = DH.Commons.Base.ResultState;
using Timer = System.Threading.Timer;
namespace DHSoftware
{
@ -44,6 +47,13 @@ namespace DHSoftware
{
private Dictionary<string, List<string>> _cameraRelatedDetectionDict = null;
public event Action<LogMsg> OnLog;
public List<CameraSummary> CameraSummaries { get; set; } = new List<CameraSummary>();
public List<ProductSummary> ProductSummaries = new List<ProductSummary>();
static object _productSummaryLock = new object();
public event Action<DateTime, object, string> OnUpdateResult;
public event Action<DateTime, object, string> OnUpdateCamResult;
private string _loginName;
public string LoginName
@ -261,7 +271,6 @@ namespace DHSoftware
public MainWindow()
{
InitializeComponent();
//refreshTimer.Start();
//初始化数据
InitData();
@ -273,6 +282,321 @@ namespace DHSoftware
//userControlFrm.Dock = DockStyle.Fill;
//tabPage2.Controls.Add(userControlFrm);
}
//#region OEE
// public event Action<RunState> OnProcessRunStateChanged;
#region INotifyPropertyChanged
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?.Invoke(this, new PropertyChangedEventArgs(propName));
}
}
#endregion
#region Properties
private int uph = 0;
private int upm = 0;
private DateTime? startTime = null;
private TimeSpan runTime = new TimeSpan();
private TimeSpan idleTime = new TimeSpan();
private TimeSpan downTime = new TimeSpan();
private TimeSpan totalTime = new TimeSpan();
private int qty_OEE = 0;
private int qty_OEE_OK = 0;
private float oee = 0;
public int UPH
{
get => uph;
set => Set(ref uph, value);
}
public int UPM
{
get => upm;
set => Set(ref upm, value);
}
public DateTime? StartTime
{
get => startTime;
set => Set(ref startTime, value);
}
/// <summary>
/// 有效运行时间
/// </summary>
public TimeSpan RunTime
{
get => runTime;
set => Set(ref runTime, value);
}
/// <summary>
/// 空闲待机时间
/// </summary>
public TimeSpan IdleTime
{
get => idleTime;
set => Set(ref idleTime, value);
}
/// <summary>
/// 故障宕机时间
/// </summary>
public TimeSpan DownTime
{
get => downTime;
set => Set(ref downTime, value);
}
/// <summary>
/// 总开机时间
/// </summary>
public TimeSpan TotalTime
{
get => totalTime;
set => Set(ref totalTime, value);
}
public float OEE
{
get => oee;
set => Set(ref oee, value);
}
#endregion
#region Timer
System.Threading.Timer _runTimer = null;
System.Threading.Timer _idleTimer = null;
System.Threading.Timer _downTimer = null;
System.Threading.Timer _checkIdleTimer = null;
//System.Threading.Timer _calculateTimer = null;
private RunState? currentState = null;
public RunState? CurrentState
{
get => currentState;
set
{
if (value != null)
{
if (value.Value == RunState.Running)
{
_checkIdleTimer?.Change(10 * 1000, -1);
}
if (currentState != value.Value)
{
switch (currentState)
{
case RunState.Idle:
//AddRunEventInBuffer(DateTime.Now, RunEvent_EventType.Idle, false);
break;
case RunState.Down:
//AddRunEventInBuffer(DateTime.Now, RunEvent_EventType.Down, false);
break;
}
switch (value.Value)
{
case RunState.Stop:
_runTimer?.Change(-1, -1);
_idleTimer?.Change(-1, -1);
_downTimer?.Change(-1, -1);
break;
case RunState.Running:
_idleTimer?.Change(-1, -1);
_downTimer?.Change(-1, -1);
_runTimer?.Change(0, 1000);
break;
case RunState.Idle:
_runTimer?.Change(-1, -1);
_downTimer?.Change(-1, -1);
_idleTimer?.Change(0, 1000);
//AddRunEventInBuffer(DateTime.Now, RunEvent_EventType.Idle, true);
break;
case RunState.Down:
_idleTimer?.Change(-1, -1);
_runTimer?.Change(-1, -1);
_downTimer?.Change(0, 1000);
//AddRunEventInBuffer(DateTime.Now, RunEvent_EventType.Down, true);
break;
}
currentState = value;
}
}
}
}
private void CheckIdleTimeStart(object state)
{
if (CurrentState == RunState.Running)
{
RunTime = RunTime.Add(new TimeSpan(0, 0, 0 - 10));
IdleTime = IdleTime.Add(new TimeSpan(0, 0, 10));
CurrentState = RunState.Idle;
}
}
public void InitialOEEStatistic()
{
InitialStatisticTimers();
ResetOEETimeDistribute();
ResetProductSummaries();
}
public void ResetProductSummaries()
{
ProductSummaries = new List<ProductSummary>();
}
private void InitialStatisticTimers()
{
if (_checkIdleTimer == null)
{
_checkIdleTimer = new Timer(new TimerCallback(CheckIdleTimeStart), null, -1, -1);
}
if (_runTimer == null)
{
_runTimer = new System.Threading.Timer(RunTimerCallBack, null, -1, -1);
}
if (_idleTimer == null)
{
_idleTimer = new System.Threading.Timer(IdleTimerCallBack, null, -1, -1);
}
if (_downTimer == null)
{
_downTimer = new System.Threading.Timer(DownTimerCallBack, null, -1, -1);
}
StartTime = DateTime.Now;
DownTime = IdleTime = RunTime = new TimeSpan(0, 0, 0);
CurrentState = RunState.Running;
}
private void DownTimerCallBack(object state)
{
DownTime = DownTime.Add(new TimeSpan(0, 0, 1));
GetTotalTime();
}
private void IdleTimerCallBack(object state)
{
IdleTime = IdleTime.Add(new TimeSpan(0, 0, 1));
GetTotalTime();
}
private void RunTimerCallBack(object state)
{
RunTime = RunTime.Add(new TimeSpan(0, 0, 1));
GetTotalTime();
}
private void GetTotalTime()
{
TotalTime = RunTime + IdleTime + DownTime;
}
public void ResetOEETimeDistribute()
{
StartTime = DateTime.Now;
DownTime = IdleTime = RunTime = new TimeSpan(0, 0, 0);
ProductNum_Total = ProductNum_OK = 0;
}
public void CloseStatisticTimers()
{
CloseTimer(ref _checkIdleTimer);
CloseTimer(ref _runTimer);
CloseTimer(ref _idleTimer);
CloseTimer(ref _downTimer);
CurrentState = RunState.Stop;
}
private void CloseTimer(ref System.Threading.Timer timer)
{
timer?.Change(-1, -1);
timer?.Dispose();
timer = null;
}
#endregion
#region CameraSum
private void InitialCameraSumsView()
{
dgvProductNums.AutoGenerateColumns = false;
dgvProductNums.DefaultCellStyle.Font = new Font("Tahoma", 12, FontStyle.Regular, GraphicsUnit.World);
dgvProductNums.DataSource = null;
dgvProductNums.DataSource = ProductSummaries;
dgvCamreaNums.Columns.Clear();
// 添加 CCD 列
dgvCamreaNums.Columns.Add(new DataGridViewTextBoxColumn
{
HeaderText = "CCD",
DataPropertyName = "CameraName"
});
// 添加 触发数 列
var TiggerCountColumn = new DataGridViewTextBoxColumn
{
HeaderText = "触发数",
DataPropertyName = "TiggerCount"
};
dgvCamreaNums.Columns.Add(TiggerCountColumn);
// 添加 合格 列
var okColumn = new DataGridViewTextBoxColumn
{
HeaderText = "合格",
DataPropertyName = "OKCount"
};
okColumn.DefaultCellStyle.ForeColor = Color.Green; // 设置背景为绿色
dgvCamreaNums.Columns.Add(okColumn);
// 添加 不合格 列
var ngColumn = new DataGridViewTextBoxColumn
{
HeaderText = "不合格",
DataPropertyName = "NGCount"
};
ngColumn.DefaultCellStyle.ForeColor = Color.LightCoral; // 设置背景为红色
dgvCamreaNums.Columns.Add(ngColumn);
// 添加 总数 列
dgvCamreaNums.Columns.Add(new DataGridViewTextBoxColumn
{
HeaderText = "总数",
DataPropertyName = "TotalCount"
});
// 添加 良率 列
dgvCamreaNums.Columns.Add(new DataGridViewTextBoxColumn
{
HeaderText = "良率",
DataPropertyName = "YieldStr"
});
dgvCamreaNums.AutoGenerateColumns = false;
dgvCamreaNums.DataSource = new BindingList<CameraSummary>(CameraSummaries);
}
#endregion
/// <summary>
/// 窗体对象实例
@ -353,22 +677,22 @@ namespace DHSoftware
if (cameraBase.CamType == EnumCamType.Do3think)
{
Do3ThinkCamera cam =new Do3ThinkCamera();
Do3ThinkCamera cam = new Do3ThinkCamera();
cam.IsSavePicEnabled = cameraBase.IsSavePicEnabled;
cam.CameraName = cameraBase.CameraName;
cam.CameraIP = cameraBase.CameraIP;
cam.IsEnabled = cameraBase.IsEnabled;
cam.ImageSaveDirectory = "D://Cam1//";
cam.ImageSaveDirectory = Path.Combine("D://Projects", cameraBase.CameraName);
Cameras.Add(cam);
if(cameraBase.IsEnabled)
if (cameraBase.IsEnabled)
{
cam.OnLog -= _visionEngine_OnLog;
cam.OnLog += _visionEngine_OnLog;
cam.CameraConnect();
cam.OnHImageOutput += OnCameraHImageOutput;
}
}
else if (cameraBase.CamType == EnumCamType.hik)
{
@ -378,7 +702,7 @@ namespace DHSoftware
cam.IsEnabled = cameraBase.IsEnabled;
HKCameras.Add(cam);
// cam.CameraConnect();
cam.OnHImageOutput += OnCameraHImageOutput;
//cam.OnHImageOutput += OnCameraHImageOutput;
}
}
}
@ -424,7 +748,8 @@ namespace DHSoftware
detectionConfig.ModelHeight = detection.ModelHeight;
detectionConfig.In_lable_path = detection.In_lable_path;
detectionConfig.IsEnabled = detection.IsEnabled;
detectionConfig.ImageSaveDirectory = "D://Projects//Images";
detectionConfig.ShowLocation.X = (i + 1) % 5 + (i + 1) / 5;
// detectionConfig.ShowLocation.X = detection.ShowLocation.X;
detectionConfig.ShowLocation.Y = (i + 1) / 5 + 1;
@ -459,6 +784,8 @@ namespace DHSoftware
//
_visionEngine = new SimboVisionDriver();
_visionEngine.DetectionConfigs = DetectionConfigs;
_visionEngine.LoggerHelper.LogPath = "D://PROJECTS//Logs//";
_visionEngine.LoggerHelper.LogPrefix = "Vision";
_visionEngine.OnLog += _visionEngine_OnLog;
//初始化模型 加载模型
_visionEngine.Init();
@ -471,13 +798,14 @@ namespace DHSoftware
private void _visionEngine_OnLog(LogMsg msg)
{
OnLog?.Invoke(msg);
//OnLog?.Invoke(msg);
LogDisplay(msg);
}
private void LogDisplay(LogMsg msg)
{
frmLog?.LogDisplay(msg);
//frmLog?.LogDisplay(msg);
frmLog?.AddLog(msg);
}
public LoggerHelper LoggerHelper { get; set; } = new LoggerHelper();
public virtual void LogAsync(LogMsg msg)
@ -496,30 +824,92 @@ namespace DHSoftware
OnLog?.Invoke(msg);
//if (IConfig?.IsLogEnabled ?? true)
//{
LoggerHelper.LogAsync(msg);
LoggerHelper.LogAsync(msg);
//}
}
public virtual void LogAsync(DateTime dt, LogLevel logLevel, string msg)
{
LogAsync(new LogMsg(dt, logLevel, msg));
}
System.Windows.Forms.Timer _refreshUITimer = new System.Windows.Forms.Timer();
private void BindEventHandler()
{
btnAddProject.Click += BtnAddProject_Click;
btnDeleteProject.Click += BtnDeleteProject_Click;
btnLoadProject.Click += BtnLoadProject_Click;
LoggerHelper.LogPath = "D://";
LoggerHelper.LogPath = "D://PROJECTS//Logs//";
LoggerHelper.LogPrefix = "Process";
OnLog -= LogDisplay;
OnLog += LogDisplay;
OnUpdateCamResult -= UpdateCamResult;
OnUpdateCamResult += UpdateCamResult;
OnUpdateResult -= UpdateResult;
OnUpdateResult += UpdateResult;
Load += (s, e) =>
{
_refreshUITimer.Interval = 1000;
_refreshUITimer.Tick += _refreshUITimer_Tick;
_refreshUITimer.Enabled = true;
};
lbInBackend.Click += LbInBackend_Click;
}
private void LbInBackend_Click(object? sender, EventArgs e)
{
DH.RBAC.RBACWindow.Instance.Show();
}
private void _refreshUITimer_Tick(object sender, EventArgs e)
{
_refreshUITimer.Enabled = false;
if (this != null)
{
lblStartTime.Text = StartTime == null ? "" : StartTime.Value.ToString("yyyy/MM/dd HH:mm:ss");
lblTotalTime.Text = TotalTime.ToString(); // 运行时间
// lblRunTime.Text = RunTime.ToString(); // 有效时间
// lblIdleTime.Text = ProcessControl.IdleTime.ToString(); // 空闲时间
// lblDownTime.Text = ProcessControl.DownTime.ToString(); // 宕机时间
lblOEE_Total.Text = ProductNum_Total.ToString();
// lblOEE_OK.Text = ProcessControl.ProductNum_OK.ToString();
}
_refreshUITimer.Enabled = true;
}
private void UpdateCamResult(DateTime updateTime, object objData, string customMessage)
{
this.Invoke(new Action(() =>
{
BindingList<CameraSummary> cameraSummaries = new BindingList<CameraSummary>(CameraSummaries);
dgvCamreaNums.DataSource = cameraSummaries;
}));
}
private void UpdateResult(DateTime updateTime, object objData, string result)
{
this.Invoke(new Action(() =>
{
dgvProductNums.DataSource = new BindingList<ProductSummary>(ProductSummaries);
//if (dgvProductNums.Rows.Count > 0)
//{
// dgvProductNums.Height = dgvProductNums.Rows[0].Height * dgvProductNums.Rows.Count + 15;
//}
//else
//{
// dgvProductNums.Height = 35;
//}
//lblOEE_Rate.Text = ProcessControl.OEE.ToString("f2") + " %";
lblUPH.Text = UPM.ToString();
}));
}
private void BtnDeleteProject_Click(object? sender, EventArgs e)
@ -716,7 +1106,7 @@ namespace DHSoftware
}
segmented1.SelectIndex = -1;
}
public string BatchNO { get; set; }
public bool CurrentMachine = false;
public volatile int ProductNum_Total = 0;
public volatile int ProductNum_OK = 0;
@ -729,9 +1119,15 @@ namespace DHSoftware
private Dictionary<string, HDevEngineTool> HalconToolDict = new Dictionary<string, HDevEngineTool>();
public List<RecongnitionLabel> RecongnitionLabelList { get; set; } = new List<RecongnitionLabel>();
public DateTime ProcessstartTime;
private void PrepareBatchNO()
{
BatchNO = string.IsNullOrEmpty(BatchNO) ? SystemModel.CurrentScheme + "-" + DateTime.Now.ToString("yyyyMMddHHmmss") : BatchNO;
// DataSavePath = string.IsNullOrEmpty(DataSavePath) ? Path.Combine(X018PLCConfig.ImgDirectory, DateTime.Now.ToString("yyyyMMdd"), BatchNO) : DataSavePath;
}
private void HandleStartButton()
{
InitialCameraSumsView();
LogAsync(DateTime.Now, LogLevel.Information, "流程启动中,请稍候...");
StartProcess();
LogAsync(DateTime.Now, LogLevel.Action, "流程启动完成!");
@ -741,11 +1137,16 @@ namespace DHSoftware
private void StartProcess()
{
BatchNO = textBoxBatchNO.Text;
textBoxBatchNO.ReadOnly = true;
btnCreateBatchNO.Enabled = false;
PrepareBatchNO();//生成批次号
ProcessstartTime = DateTime.Now;
lblstarttime2.Text = ProcessstartTime.ToString("yyyy-MM-dd HH:mm:ss");
lblStartTime.Text = ProcessstartTime.ToString("yyyy-MM-dd HH:mm:ss");
//计数清零
PieceCount = 0;
//CameraSummaries.Clear();
if (PLC?.Enable == true)
{
@ -844,11 +1245,11 @@ namespace DHSoftware
// ProductBaseCount = _MGSCameraList.Count;
//流程执行时PLC
PLC.StartProcess();
InitialOEEStatistic();
@ -889,7 +1290,7 @@ namespace DHSoftware
LogAsync(DateTime.Now, LogLevel.Action, $">> 轴{axisIndex}新产品{pieceNumber}加入队列{index}----板卡计数{PieceCount}");
}
DateTime dtNow = DateTime.Now;
UpdateCT(null, (float)(dtNow - _ctTime).TotalSeconds);
_ctTime = dtNow;
@ -909,7 +1310,7 @@ namespace DHSoftware
/// <param name="dt"></param>
/// <param name="camera"></param>
/// <param name="imageSet"></param>
private void OnCameraHImageOutput(DateTime dt, CameraBase camera, Mat imageSet)
private void OnCameraHImageOutput(DateTime dt, CameraBase camera, MatSet imageSet)
{
//if (camera.CameraName.Equals("cam1", StringComparison.OrdinalIgnoreCase))
//{
@ -925,7 +1326,7 @@ namespace DHSoftware
Task.Run(async () =>
{
using (Mat localImageSet = imageSet.Clone()) // 复制 Mat 避免并发问题
//using (Mat localImageSet = imageSet._mat.Clone()) // 复制 Mat 避免并发问题
{
// imageSet?.Dispose();
// 拍照计数与物件编号一致,查找对应的产品
@ -947,7 +1348,7 @@ namespace DHSoftware
}
else
{
Thread.Sleep(20);
Thread.Sleep(20);
//await Task.Delay(20);
}
retryTimes--;
@ -964,20 +1365,20 @@ namespace DHSoftware
}
//LogAsync(DateTime.Now, LogLevel.Error, $"{camera.Name} 未找到产品,编号:{productNumber},队列{index}数量:{tmpDic.Count},列表:{pnStr}");
localImageSet.Dispose();
imageSet.Dispose();
return;
}
// LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 找到产品{productNumber},队列{index}数量:{tmpDic.Count}");
LogAsync(DateTime.Now, LogLevel.Information, $"{camera.CameraName} 找到产品{productNumber},队列{index}数量:{tmpDic.Count}");
if (!_cameraRelatedDetectionDict.ContainsKey(camera.CameraName))
{
localImageSet.Dispose();
imageSet.Dispose();
LogAsync(DateTime.Now, LogLevel.Warning, $"{camera.CameraName} 找到产品{productNumber}但是没有推理1");
LogAsync(DateTime.Now, LogLevel.Warning, $"{camera.CameraName} 找到产品{productNumber}但是没有推理1");
return;
}
@ -990,19 +1391,37 @@ namespace DHSoftware
for (int i = 0; i < detectionDict.Count; i++)
{
string detectionId = detectionDict[i];
var tmpImgSet = camera.CopyImageSet(imageSet as MatSet);
//imageSet
// using (Mat inferenceImage = localImageSet.Clone()) // 仅在此处克隆,确保推理过程中 Mat 有独立副本
using (Mat inferenceImage = localImageSet.Clone()) // 仅在此处克隆,确保推理过程中 Mat 有独立副本
DetectStationResult temp1 = _visionEngine.RunInference(tmpImgSet, detectionId);
resultStates.Add(temp1.ResultState);
product.ResultCollection.Add(temp1);
if (temp1 != null)
{
DetectStationResult temp1 = _visionEngine.RunInference(inferenceImage, detectionId);
UpdateResultTigger(dt, temp1.DetectName, (int)productNumber);
//if (tmpModuleData.CamIDs.Count == 1)
//{
// UpdateResultoverride(dt, temp1.DetectName, resultStates, totalTime, _cameraRelatedDetectionDict.Keys.Count);
//}
//else //合图的合成一列
//{
// UpdateResultoverride(dt, temp1.DetectName, resultStates, totalTime, _cameraRelatedDetectionDict.Keys.Count);
//}
if (product.ResultCollection.Count != 0)
UpdateResultoverride(dt, temp1.DetectName, resultStates, totalTime, _cameraRelatedDetectionDict.Keys.Count);
resultStates.Add(temp1.ResultState);
product.ResultCollection.Add(temp1);
}
}
stopwatch.Stop();
product.InferenceOne();
// LogAsync(DateTime.Now, LogLevel.Information, $"{camera.Name} 推理完成,产品{productNumber}");
@ -1011,24 +1430,32 @@ namespace DHSoftware
{
return;
}
UpdateResult(DateTime.Now, null, product.ProductResult.GetEnumDescription());
#region 6.
product.ProductResult = product.ResultCollection.Any(u => u.ResultState != ResultState.OK)
? ResultState.B_NG
: ResultState.OK;
//if (product.ProductResult == ResultState.OK)
//{
// PLC.Blowing(productNumber, 1);
//}
//else
//{
// PLC.Blowing(productNumber, 2);
//}
product.ProductLabelCategory = product.ProductResult.GetEnumDescription();
product.ProductLabel = product.ProductResult.GetEnumDescription();
UpdateResultPro(DateTime.Now, null, product.ProductResult.GetEnumDescription());
LogAsync(DateTime.Now, LogLevel.Information, $"产品{product.PieceNumber}获取结果:{product.ProductResult} {(product.IsA2B ? "IsA2B" : "")}");
if (product.ProductResult == ResultState.OK)
{
PLC.Blowing(productNumber, 1);
LogAsync(DateTime.Now, LogLevel.Action, $"产品{product.PieceNumber}PLC,OK吹气");
}
else
{
PLC.Blowing(productNumber, 2);
LogAsync(DateTime.Now, LogLevel.Action, $"产品{product.PieceNumber}PLC,NG吹气");
}
#endregion 6.
@ -1052,12 +1479,12 @@ namespace DHSoftware
$"当前队列产品数量:{tmpDic.Count}";
this.BeginInvoke(new MethodInvoker(delegate ()
{
// int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y;
// int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y;
// richTextBox1.AppendText(logStr);
// richTextBox1.AppendText(logStr);
// 设置回原来的滚动位置
// richTextBox1.SelectionStart = richTextBox1.TextLength;
// richTextBox1.SelectionStart = richTextBox1.TextLength;
//richTextBox1.ScrollToCaret();
}));
}
@ -1072,18 +1499,15 @@ namespace DHSoftware
{
//int currentScrollPosition = richTextBox1.GetPositionFromCharIndex(richTextBox1.TextLength).Y;
// richTextBox1.AppendText(logStr);
// richTextBox1.AppendText(logStr);
// 设置回原来的滚动位置
// richTextBox1.SelectionStart = richTextBox1.TextLength;
// richTextBox1.SelectionStart = richTextBox1.TextLength;
//richTextBox1.ScrollToCaret();
}));
//重新生成实例 销毁之前的实例
var saveData = temp.GetProductData();
using (StreamWriter sw = new StreamWriter("D://123log.txt", true, Encoding.UTF8))
{
sw.WriteLine(logStr);
}
}
catch (Exception) { }
finally
@ -1105,46 +1529,193 @@ namespace DHSoftware
}
});
}
public async Task UpdateResult(DateTime dt, object objData, string resultStr)
public virtual void AddOKProduct(string resultStr)
{
// CurrentState = RunState.Running;
if (resultStr.ToLower() == "ok")
{
ProductNum_OK++;
}
}
public async Task UpdateResultTigger(DateTime dt, string objData, int _cameraDictCount)
{
CurrentState = RunState.Running;
// 根据相机名称找到对应的信息(假设有一个字典或其他集合保存相机相关信息)
var cameraName = objData; // 假设 CameraBase 有 Name 属性
if (string.IsNullOrEmpty(cameraName))
{
throw new ArgumentException("相机名称不能为空");
}
lock (_cameraSummaryLock)
{
// 查找或添加相机统计项
var summary = CameraSummaries.FirstOrDefault(c => c.CameraName == cameraName)
?? new CameraSummary { CameraName = cameraName };
if (!CameraSummaries.Contains(summary))
{
CameraSummaries.Add(summary);
}
summary.TiggerCount = _cameraDictCount;
}
await Task.Run(() =>
{
OnUpdateCamResult?.Invoke(dt, objData, "");
});
}
public async Task UpdateResultoverride(DateTime dt, string objData, List<ResultState> resultStr, double total, int _cameraDictCount)
{
// CurrentState = RunState.Running;
// 根据相机名称找到对应的信息(假设有一个字典或其他集合保存相机相关信息)
var cameraName = objData; // 假设 CameraBase 有 Name 属性
if (string.IsNullOrEmpty(cameraName))
{
throw new ArgumentException("相机名称不能为空");
}
lock (_cameraSummaryLock)
{
// 查找或添加相机统计项
var summary = CameraSummaries.FirstOrDefault(c => c.CameraName == cameraName)
?? new CameraSummary { CameraName = cameraName };
if (!CameraSummaries.Contains(summary))
{
CameraSummaries.Add(summary);
}
if (resultStr.Any(u => u.ToString().ToLower() == "ok"))
{
summary.OKCount++;
}
else /*if (resultStr.Equals("TBD", StringComparison.OrdinalIgnoreCase))*/
{
summary.NGCount++;
}
}
await Task.Run(() =>
{
OnUpdateCamResult?.Invoke(dt, objData, "");
});
}
public async Task UpdateResultPro(DateTime dt, object objData, string resultStr)
{
CurrentState = RunState.Running;
ProductNum_Total++;
//AddOKProduct(resultStr);
AddOKProduct(resultStr);
lock (_productSummaryLock)
{
var product = ProductSummaries.FirstOrDefault(u => u.ResultDesc == resultStr);
if (product != null)
{
product.ProductAmount++;
}
else
{
product = new ProductSummary();
product.ResultDesc = resultStr;
product.ProductAmount = 1;
ProductSummaries.Add(product);
}
int totalNum = ProductSummaries.Sum(p => p.ProductAmount);
ProductSummaries.ForEach(p => p.PercentStr = ((double)p.ProductAmount * 100.0 / totalNum).ToString("f2") + " %");
}
CalculateOEE();
await Task.Run(() =>
{
OnUpdateResult?.Invoke(dt, objData, resultStr);
});
lock (_cameraSummaryLock)
{
// 查找或添加相机统计项
var summary = CameraSummaries.FirstOrDefault(c => c.CameraName == "合计")
?? new CameraSummary { CameraName = "合计" };
summary.OKCount = ProductNum_OK;
summary.NGCount = ProductNum_Total - ProductNum_OK;
if (!CameraSummaries.Contains(summary))
{
CameraSummaries.Add(summary);
}
}
await Task.Run(() =>
{
OnUpdateCamResult?.Invoke(dt, objData, "合计");
});
}
private void HandleStopButton()
{
// Cameras.Clear();
// Dectection.Clear();
textBoxBatchNO.ReadOnly = false;
btnCreateBatchNO.Enabled = true;
// Cameras.Clear();
// Dectection.Clear();
// Add the code for the "停止" button click here
PLC.TurnStart(false);
CurrentMachine = true;
//sLDMotion.Stop();
}
public int UPH = 0;
public void CalculateOEE()
{
TimeSpan timeSpan = DateTime.Now - ProcessstartTime;
UPH = (int)(ProductNum_Total / timeSpan.TotalHours) + 100;
//UPM = (int)UPH / 60;
this.BeginInvoke(new MethodInvoker(delegate ()
if (TotalTime.TotalHours == 0)
{
lblNowtime2.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
lblUPH2.Text = UPH.ToString();
lblNum2.Text = ProductNum_Total.ToString();
labuph.Text = UPH.ToString();
}));
UPH = 0;
UPM = 0;
}
else
{
UPH = (int)(ProductNum_Total / RunTime.TotalHours) + 100;
UPM = (int)UPH / 60;
}
//TimeSpan timeSpan = DateTime.Now - ProcessstartTime;
//UPH = (int)(ProductNum_Total / timeSpan.TotalHours) + 100;
////UPM = (int)UPH / 60;
//this.BeginInvoke(new MethodInvoker(delegate ()
//{
// lblNowtime.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
// lblUPH.Text = UPH.ToString();
// lblNum.Text = ProductNum_Total.ToString();
//}));
}
private void HandleResetButton()
@ -1167,18 +1738,9 @@ namespace DHSoftware
LoginWindow.Instance.Show();
}
private void splitter1_SplitterMoved(object sender, SplitterEventArgs e)
private void btnCreateBatchNO_Click(object sender, EventArgs e)
{
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
private void splitContainer2_Panel1_Paint(object sender, PaintEventArgs e)
{
textBoxBatchNO.Text = SystemModel.CurrentScheme + "-" + DateTime.Now.ToString("yyyyMMddHHmmss");
}
}
}

View File

@ -117,34 +117,34 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="segmentedItem1.IconActiveSvg" xml:space="preserve">
<data name="segmentedItem6.IconActiveSvg" xml:space="preserve">
<value>&lt;svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"&gt;&lt;path d="M731.818667 500.280889L386.844444 239.729778a14.677333 14.677333 0 0 0-23.495111 11.719111v521.159111a14.677333 14.677333 0 0 0 23.495111 11.662222l344.860445-260.608a14.677333 14.677333 0 0 0 0.113778-23.381333z" fill="#FFFFFF"/&gt;&lt;path d="M512 1024a512 512 0 1 1 512-512 512.568889 512.568889 0 0 1-512 512z m0-946.915556A434.915556 434.915556 0 1 0 946.915556 512 435.427556 435.427556 0 0 0 512 77.084444z" fill="#FFFFFF"/&gt;&lt;/svg&gt;</value>
</data>
<data name="segmentedItem1.IconSvg" xml:space="preserve">
<data name="segmentedItem6.IconSvg" xml:space="preserve">
<value>&lt;svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"&gt;&lt;path d="M731.818667 500.280889L386.844444 239.729778a14.677333 14.677333 0 0 0-23.495111 11.719111v521.159111a14.677333 14.677333 0 0 0 23.495111 11.662222l344.860445-260.608a14.677333 14.677333 0 0 0 0.113778-23.381333z" fill="#FFFFFF"/&gt;&lt;path d="M512 1024a512 512 0 1 1 512-512 512.568889 512.568889 0 0 1-512 512z m0-946.915556A434.915556 434.915556 0 1 0 946.915556 512 435.427556 435.427556 0 0 0 512 77.084444z" fill="#FFFFFF"/&gt;&lt;/svg&gt;</value>
</data>
<data name="segmentedItem2.IconActiveSvg" xml:space="preserve">
<data name="segmentedItem7.IconActiveSvg" xml:space="preserve">
<value>&lt;svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"&gt;&lt;path d="M365.014704 657.815846H657.084939V365.74561H365.014704V657.815846zm584.140471-146.035118c0-240.906781-197.125482-438.105353-438.105353-438.105353-240.979872 0-438.105353 197.198572-438.105354 438.105353 0 240.979872 197.125482 438.178444 438.105354 438.178444 240.979872 0 438.105353-197.198572 438.105353-438.178444zM511.634547 0.730906c281.399001 0 511.634547 230.235546 511.634547 511.634547s-230.235546 511.634547-511.634547 511.634547-511.634547-230.235546-511.634547-511.634547 230.235546-511.634547 511.634547-511.634547z" fill="#FFFFFF"/&gt;&lt;/svg&gt;</value>
</data>
<data name="segmentedItem2.IconSvg" xml:space="preserve">
<data name="segmentedItem7.IconSvg" xml:space="preserve">
<value>&lt;svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"&gt;&lt;path d="M365.014704 657.815846H657.084939V365.74561H365.014704V657.815846zm584.140471-146.035118c0-240.906781-197.125482-438.105353-438.105353-438.105353-240.979872 0-438.105353 197.198572-438.105354 438.105353 0 240.979872 197.125482 438.178444 438.105354 438.178444 240.979872 0 438.105353-197.198572 438.105353-438.178444zM511.634547 0.730906c281.399001 0 511.634547 230.235546 511.634547 511.634547s-230.235546 511.634547-511.634547 511.634547-511.634547-230.235546-511.634547-511.634547 230.235546-511.634547 511.634547-511.634547z" fill="#FFFFFF"/&gt;&lt;/svg&gt;</value>
</data>
<data name="segmentedItem3.IconActiveSvg" xml:space="preserve">
<data name="segmentedItem8.IconActiveSvg" xml:space="preserve">
<value>&lt;svg viewBox="0 0 1027 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"&gt;&lt;path d="M512 0C229.376 0 0 229.376 0 512s229.376 512 512 512 512-229.376 512-512S794.624 0 512 0zm0 963.584c-249.344 0-451.584-202.24-451.584-451.584S262.656 60.416 512 60.416s451.584 202.24 451.584 451.584-202.24 451.584-451.584 451.584z" fill="#FFFFFF"/&gt;&lt;path d="M527.36 351.744V292.864L410.624 380.416 527.36 468.48V410.624c72.192 8.192 124.416 73.216 116.224 145.408-8.192 72.192-73.216 124.416-145.408 116.224-66.56-7.168-117.248-64-117.248-131.072-0.512-5.12-0.512-9.728 0-14.848H323.584c-0.512 5.12-0.512 9.728 0 14.848 0 104.96 85.504 189.952 190.464 189.952s189.952-85.504 189.952-190.464c-0.512-99.328-77.312-181.76-176.64-188.928z" fill="#FFFFFF"/&gt;&lt;/svg&gt;</value>
</data>
<data name="segmentedItem3.IconSvg" xml:space="preserve">
<data name="segmentedItem8.IconSvg" xml:space="preserve">
<value>&lt;svg viewBox="0 0 1027 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"&gt;&lt;path d="M512 0C229.376 0 0 229.376 0 512s229.376 512 512 512 512-229.376 512-512S794.624 0 512 0zm0 963.584c-249.344 0-451.584-202.24-451.584-451.584S262.656 60.416 512 60.416s451.584 202.24 451.584 451.584-202.24 451.584-451.584 451.584z" fill="#FFFFFF"/&gt;&lt;path d="M527.36 351.744V292.864L410.624 380.416 527.36 468.48V410.624c72.192 8.192 124.416 73.216 116.224 145.408-8.192 72.192-73.216 124.416-145.408 116.224-66.56-7.168-117.248-64-117.248-131.072-0.512-5.12-0.512-9.728 0-14.848H323.584c-0.512 5.12-0.512 9.728 0 14.848 0 104.96 85.504 189.952 190.464 189.952s189.952-85.504 189.952-190.464c-0.512-99.328-77.312-181.76-176.64-188.928z" fill="#FFFFFF"/&gt;&lt;/svg&gt;</value>
</data>
<data name="segmentedItem4.IconActiveSvg" xml:space="preserve">
<data name="segmentedItem9.IconActiveSvg" xml:space="preserve">
<value>&lt;svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"&gt;&lt;path d="M512 0C229.376 0 0 229.376 0 512s229.376 512 512 512 512-229.376 512-512S794.624 0 512 0zm0 963.584c-249.344 0-451.584-202.24-451.584-451.584S262.656 60.416 512 60.416s451.584 202.24 451.584 451.584-202.24 451.584-451.584 451.584z" fill="#FFFFFF"/&gt;&lt;path transform="scale(0.8) translate(128,128)" d="M960.853333 903.816533a463.633067 463.633067 0 0 0-11.264-39.185066c-1.536-4.539733-3.413333-8.942933-5.051733-13.448534a484.078933 484.078933 0 0 0-9.557333-24.4736c-2.2528-5.188267-4.881067-10.274133-7.338667-15.394133-3.413333-7.099733-6.8608-14.165333-10.6496-21.0944-2.901333-5.3248-6.075733-10.513067-9.181867-15.701333-2.423467-4.061867-4.573867-8.226133-7.133866-12.219734-1.604267-2.4576-3.413333-4.778667-5.0176-7.202133-1.501867-2.218667-2.730667-4.608-4.266667-6.792533-0.4096-0.6144-1.058133-0.887467-1.501867-1.4336a461.482667 461.482667 0 0 0-90.385066-96.768c-13.5168-10.786133-27.7504-20.48-42.257067-29.5936-0.477867-0.341333-0.7168-0.8192-1.194667-1.1264-3.6864-2.286933-7.509333-4.3008-11.264-6.485334-4.266667-2.491733-8.4992-5.051733-12.868266-7.441066-6.826667-3.6864-13.789867-7.099733-20.753067-10.478934-3.618133-1.7408-7.202133-3.618133-10.8544-5.290666a449.194667 449.194667 0 0 0-31.607467-12.731734c-0.7168-0.273067-1.365333-0.6144-2.082133-0.8192-3.140267-1.1264-6.417067-1.911467-9.557333-2.935466-4.164267-1.399467-8.328533-2.833067-12.561067-4.096a259.9936 259.9936 0 0 0 129.194667-225.450667 260.061867 260.061867 0 0 0-76.629334-185.002667 259.9936 259.9936 0 0 0-185.002666-76.629333H512h-0.034133a259.857067 259.857067 0 0 0-185.002667 76.629333 259.925333 259.925333 0 0 0-76.629333 185.002667 259.584 259.584 0 0 0 76.629333 185.002667c15.906133 15.940267 33.655467 29.2864 52.565333 40.448-4.266667 1.262933-8.430933 2.730667-12.663466 4.096-3.140267 1.058133-6.3488 1.8432-9.489067 2.935466-0.7168 0.238933-1.365333 0.580267-2.048 0.8192-10.683733 3.822933-21.265067 8.0896-31.675733 12.765867-3.584 1.604267-7.0656 3.4816-10.615467 5.154133-7.099733 3.413333-14.165333 6.826667-21.0944 10.615467-4.266667 2.321067-8.3968 4.8128-12.561067 7.2704-3.822933 2.218667-7.748267 4.266667-11.502933 6.621867-0.512 0.3072-0.750933 0.8192-1.2288 1.160533-14.506667 9.147733-28.706133 18.807467-42.222933 29.559467a459.6736 459.6736 0 0 0-90.385067 96.768c-0.443733 0.546133-1.092267 0.8192-1.501867 1.4336-1.536 2.184533-2.7648 4.573867-4.266666 6.792533-1.604267 2.423467-3.447467 4.744533-5.0176 7.202133-2.56 3.9936-4.7104 8.157867-7.133867 12.219734-3.106133 5.188267-6.280533 10.376533-9.181867 15.701333-3.7888 6.929067-7.202133 13.994667-10.6496 21.0944-2.4576 5.12-5.051733 10.205867-7.338666 15.394133-3.515733 8.021333-6.519467 16.247467-9.557334 24.4736-1.672533 4.5056-3.549867 8.9088-5.051733 13.448534-4.3008 12.868267-8.0896 25.941333-11.264 39.185066-3.072 12.970667 2.594133 25.770667 13.073067 32.802134a31.3344 31.3344 0 0 0 9.966933 4.608 30.9248 30.9248 0 0 0 34.030933-15.2576 30.446933 30.446933 0 0 0 3.345067-7.7824c2.833067-11.844267 6.178133-23.483733 10.0352-34.9184 0.6144-1.8432 1.399467-3.549867 2.013867-5.358934 3.447467-9.762133 7.133867-19.456 11.332266-28.945066 0.512-1.160533 1.1264-2.2528 1.6384-3.447467 4.7104-10.308267 9.728-20.48 15.291734-30.344533l0.068266-0.1024a402.773333 402.773333 0 0 1 19.694934-31.4368l0.136533-0.375467a397.4144 397.4144 0 0 1 116.599467-111.2064c0.136533-0.1024 0.3072-0.068267 0.443733-0.170667a397.824 397.824 0 0 1 94.993067-42.973866c2.7648-0.8192 5.495467-1.7408 8.2944-2.491734 5.7344-1.604267 11.5712-3.003733 17.373866-4.334933a367.8208 367.8208 0 0 1 47.342934-7.953067c3.8912-0.443733 7.7824-0.9216 11.6736-1.2288 10.410667-0.785067 20.8896-1.3312 31.505066-1.3312s21.060267 0.546133 31.505067 1.3312c3.8912 0.3072 7.816533 0.785067 11.707733 1.2288a361.3696 361.3696 0 0 1 47.240534 7.953067c5.870933 1.3312 11.707733 2.730667 17.5104 4.334933 2.696533 0.750933 5.358933 1.6384 8.021333 2.4576 33.348267 10.103467 65.365333 24.405333 95.197867 43.008 0.136533 0.1024 0.3072 0.068267 0.443733 0.170667a396.151467 396.151467 0 0 1 116.599467 111.2064c0.1024 0.136533 0.1024 0.273067 0.170666 0.375467 13.687467 19.7632 25.3952 40.5504 35.191467 62.1568l1.467733 3.037866c4.3008 9.659733 8.055467 19.592533 11.605334 29.5936 0.546133 1.604267 1.2288 3.106133 1.774933 4.7104 3.822933 11.4688 7.236267 23.176533 10.0352 35.0208a31.061333 31.061333 0 0 0 60.450133-14.336zm-249.275733-560.2304A199.850667 199.850667 0 0 1 512 543.197867a199.850667 199.850667 0 0 1-199.5776-199.611734A199.816533 199.816533 0 0 1 512 144.008533a199.816533 199.816533 0 0 1 199.5776 199.5776z" fill="#FFFFFF"/&gt;&lt;/svg&gt;</value>
</data>
<data name="segmentedItem4.IconSvg" xml:space="preserve">
<data name="segmentedItem9.IconSvg" xml:space="preserve">
<value>&lt;svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"&gt;&lt;path d="M512 0C229.376 0 0 229.376 0 512s229.376 512 512 512 512-229.376 512-512S794.624 0 512 0zm0 963.584c-249.344 0-451.584-202.24-451.584-451.584S262.656 60.416 512 60.416s451.584 202.24 451.584 451.584-202.24 451.584-451.584 451.584z" fill="#FFFFFF"/&gt;&lt;path transform="scale(0.8) translate(128,128)" d="M960.853333 903.816533a463.633067 463.633067 0 0 0-11.264-39.185066c-1.536-4.539733-3.413333-8.942933-5.051733-13.448534a484.078933 484.078933 0 0 0-9.557333-24.4736c-2.2528-5.188267-4.881067-10.274133-7.338667-15.394133-3.413333-7.099733-6.8608-14.165333-10.6496-21.0944-2.901333-5.3248-6.075733-10.513067-9.181867-15.701333-2.423467-4.061867-4.573867-8.226133-7.133866-12.219734-1.604267-2.4576-3.413333-4.778667-5.0176-7.202133-1.501867-2.218667-2.730667-4.608-4.266667-6.792533-0.4096-0.6144-1.058133-0.887467-1.501867-1.4336a461.482667 461.482667 0 0 0-90.385066-96.768c-13.5168-10.786133-27.7504-20.48-42.257067-29.5936-0.477867-0.341333-0.7168-0.8192-1.194667-1.1264-3.6864-2.286933-7.509333-4.3008-11.264-6.485334-4.266667-2.491733-8.4992-5.051733-12.868266-7.441066-6.826667-3.6864-13.789867-7.099733-20.753067-10.478934-3.618133-1.7408-7.202133-3.618133-10.8544-5.290666a449.194667 449.194667 0 0 0-31.607467-12.731734c-0.7168-0.273067-1.365333-0.6144-2.082133-0.8192-3.140267-1.1264-6.417067-1.911467-9.557333-2.935466-4.164267-1.399467-8.328533-2.833067-12.561067-4.096a259.9936 259.9936 0 0 0 129.194667-225.450667 260.061867 260.061867 0 0 0-76.629334-185.002667 259.9936 259.9936 0 0 0-185.002666-76.629333H512h-0.034133a259.857067 259.857067 0 0 0-185.002667 76.629333 259.925333 259.925333 0 0 0-76.629333 185.002667 259.584 259.584 0 0 0 76.629333 185.002667c15.906133 15.940267 33.655467 29.2864 52.565333 40.448-4.266667 1.262933-8.430933 2.730667-12.663466 4.096-3.140267 1.058133-6.3488 1.8432-9.489067 2.935466-0.7168 0.238933-1.365333 0.580267-2.048 0.8192-10.683733 3.822933-21.265067 8.0896-31.675733 12.765867-3.584 1.604267-7.0656 3.4816-10.615467 5.154133-7.099733 3.413333-14.165333 6.826667-21.0944 10.615467-4.266667 2.321067-8.3968 4.8128-12.561067 7.2704-3.822933 2.218667-7.748267 4.266667-11.502933 6.621867-0.512 0.3072-0.750933 0.8192-1.2288 1.160533-14.506667 9.147733-28.706133 18.807467-42.222933 29.559467a459.6736 459.6736 0 0 0-90.385067 96.768c-0.443733 0.546133-1.092267 0.8192-1.501867 1.4336-1.536 2.184533-2.7648 4.573867-4.266666 6.792533-1.604267 2.423467-3.447467 4.744533-5.0176 7.202133-2.56 3.9936-4.7104 8.157867-7.133867 12.219734-3.106133 5.188267-6.280533 10.376533-9.181867 15.701333-3.7888 6.929067-7.202133 13.994667-10.6496 21.0944-2.4576 5.12-5.051733 10.205867-7.338666 15.394133-3.515733 8.021333-6.519467 16.247467-9.557334 24.4736-1.672533 4.5056-3.549867 8.9088-5.051733 13.448534-4.3008 12.868267-8.0896 25.941333-11.264 39.185066-3.072 12.970667 2.594133 25.770667 13.073067 32.802134a31.3344 31.3344 0 0 0 9.966933 4.608 30.9248 30.9248 0 0 0 34.030933-15.2576 30.446933 30.446933 0 0 0 3.345067-7.7824c2.833067-11.844267 6.178133-23.483733 10.0352-34.9184 0.6144-1.8432 1.399467-3.549867 2.013867-5.358934 3.447467-9.762133 7.133867-19.456 11.332266-28.945066 0.512-1.160533 1.1264-2.2528 1.6384-3.447467 4.7104-10.308267 9.728-20.48 15.291734-30.344533l0.068266-0.1024a402.773333 402.773333 0 0 1 19.694934-31.4368l0.136533-0.375467a397.4144 397.4144 0 0 1 116.599467-111.2064c0.136533-0.1024 0.3072-0.068267 0.443733-0.170667a397.824 397.824 0 0 1 94.993067-42.973866c2.7648-0.8192 5.495467-1.7408 8.2944-2.491734 5.7344-1.604267 11.5712-3.003733 17.373866-4.334933a367.8208 367.8208 0 0 1 47.342934-7.953067c3.8912-0.443733 7.7824-0.9216 11.6736-1.2288 10.410667-0.785067 20.8896-1.3312 31.505066-1.3312s21.060267 0.546133 31.505067 1.3312c3.8912 0.3072 7.816533 0.785067 11.707733 1.2288a361.3696 361.3696 0 0 1 47.240534 7.953067c5.870933 1.3312 11.707733 2.730667 17.5104 4.334933 2.696533 0.750933 5.358933 1.6384 8.021333 2.4576 33.348267 10.103467 65.365333 24.405333 95.197867 43.008 0.136533 0.1024 0.3072 0.068267 0.443733 0.170667a396.151467 396.151467 0 0 1 116.599467 111.2064c0.1024 0.136533 0.1024 0.273067 0.170666 0.375467 13.687467 19.7632 25.3952 40.5504 35.191467 62.1568l1.467733 3.037866c4.3008 9.659733 8.055467 19.592533 11.605334 29.5936 0.546133 1.604267 1.2288 3.106133 1.774933 4.7104 3.822933 11.4688 7.236267 23.176533 10.0352 35.0208a31.061333 31.061333 0 0 0 60.450133-14.336zm-249.275733-560.2304A199.850667 199.850667 0 0 1 512 543.197867a199.850667 199.850667 0 0 1-199.5776-199.611734A199.816533 199.816533 0 0 1 512 144.008533a199.816533 199.816533 0 0 1 199.5776 199.5776z" fill="#FFFFFF"/&gt;&lt;/svg&gt;</value>
</data>
<data name="segmentedItem5.IconActiveSvg" xml:space="preserve">
<data name="segmentedItem10.IconActiveSvg" xml:space="preserve">
<value>&lt;svg viewBox="0 0 1027 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"&gt;&lt;path d="M512 0C229.376 0 0 229.376 0 512s229.376 512 512 512 512-229.376 512-512S794.624 0 512 0zm0 963.584c-249.344 0-451.584-202.24-451.584-451.584S262.656 60.416 512 60.416s451.584 202.24 451.584 451.584-202.24 451.584-451.584 451.584z" fill="#FFFFFF"/&gt;&lt;path d="M437.314 840.84l-18.967-5.795c-43.935-13.425-84.182-35.551-119.623-65.767l-15.203-12.962 11.199-16.544c17.376-25.668 17.938-59.158 1.433-85.319-14.356-22.787-39.028-36.385-66.006-36.385-4.102 0-8.229 0.328-12.267 0.974l-19.752 3.158-5.301-19.288c-8.196-29.823-12.353-59.896-12.353-89.381 0-19.675 1.863-39.491 5.694-60.582l3.652-20.105 20.349 1.862c2.343 0.214 4.726 0.323 7.081 0.323 29.007 0 55.436-15.908 68.974-41.516 14.941-28.2 11.264-62.223-9.356-86.694l-13.166-15.625L278.1 276.7c38.694-38.954 86.677-68.095 138.76-84.273l19.741-6.132 7.631 19.211c11.88 29.908 40.312 49.234 72.432 49.234 32.097 0 60.521-19.328 72.413-49.241l7.632-19.197 19.73 6.122c43.968 13.642 84.295 36.164 119.862 66.938l15.414 13.337-11.883 16.561c-18.636 25.975-19.684 60.166-2.671 87.105 14.369 22.78 39.055 36.373 66.04 36.372 4.344 0 8.71-0.366 12.978-1.087l20.143-3.403 5.176 19.762c7.539 28.792 11.362 57.566 11.362 85.522 0 21.328-2.143 43.048-6.365 64.554l-3.859 19.65-19.952-1.709a77.999 77.999 0 0 0-6.612-0.281c-28.998 0-55.44 15.917-69.009 41.542-14.47 27.405-11.311 60.816 8.063 85.095l12.496 15.661-14.222 14.111c-38.674 38.378-86.551 67.041-138.455 82.892l-18.968 5.792-7.988-18.152c-12.462-28.318-40.459-46.617-71.325-46.617-30.883 0-58.893 18.299-71.36 46.619l-7.99 18.152zm-95.455-94.18c22.324 16.82 46.59 30.174 72.469 39.881 22.445-34.023 60.731-55.125 102.336-55.125 41.59 0 79.862 21.1 102.303 55.12 32.745-12.298 63.249-30.557 89.663-53.667-19.709-35.774-20.525-79.555-1.04-116.455 19.699-37.203 56.634-61.386 98.053-64.883 1.705-12.731 2.565-25.453 2.565-38 0-18.339-1.923-37.155-5.729-56.144-42.123-0.241-80.616-21.581-103.077-57.189-22.944-36.331-25.024-81.029-6.697-118.768-22.165-16.932-46.203-30.4-71.788-40.221-8.847 14.328-20.577 26.719-34.618 36.447-20.522 14.219-44.602 21.735-69.635 21.735-25.044 0-49.131-7.516-69.657-21.734-14.042-9.727-25.773-22.116-34.618-36.441-32.551 12.503-62.856 30.935-89.106 54.196 21.198 36.233 22.547 80.974 2.407 118.987-19.71 37.285-56.808 61.499-98.402 64.875-1.45 11.713-2.161 23.035-2.161 34.255 0 19.715 2.166 39.792 6.449 59.894 41.851 0.474 80.029 21.785 102.35 57.214 22.218 35.217 24.782 78.871 7.933 116.023z" fill="#FFFFFF"/&gt;&lt;path d="M516.664 633.864c-66.246 0-120.141-53.897-120.141-120.147 0-66.249 53.895-120.146 120.141-120.146 66.237 0 120.127 53.897 120.127 120.146 0 66.25-53.89 120.147-120.127 120.147zm0-195.641c-41.625 0-75.488 33.866-75.488 75.494s33.863 75.495 75.488 75.495c41.617 0 75.475-33.867 75.475-75.495s-33.858-75.494-75.475-75.494z" fill="#FFFFFF"/&gt;&lt;/svg&gt;</value>
</data>
<data name="segmentedItem5.IconSvg" xml:space="preserve">
<data name="segmentedItem10.IconSvg" xml:space="preserve">
<value>&lt;svg viewBox="0 0 1027 1024" xmlns="http://www.w3.org/2000/svg" width="200" height="200"&gt;&lt;path d="M512 0C229.376 0 0 229.376 0 512s229.376 512 512 512 512-229.376 512-512S794.624 0 512 0zm0 963.584c-249.344 0-451.584-202.24-451.584-451.584S262.656 60.416 512 60.416s451.584 202.24 451.584 451.584-202.24 451.584-451.584 451.584z" fill="#FFFFFF"/&gt;&lt;path d="M437.314 840.84l-18.967-5.795c-43.935-13.425-84.182-35.551-119.623-65.767l-15.203-12.962 11.199-16.544c17.376-25.668 17.938-59.158 1.433-85.319-14.356-22.787-39.028-36.385-66.006-36.385-4.102 0-8.229 0.328-12.267 0.974l-19.752 3.158-5.301-19.288c-8.196-29.823-12.353-59.896-12.353-89.381 0-19.675 1.863-39.491 5.694-60.582l3.652-20.105 20.349 1.862c2.343 0.214 4.726 0.323 7.081 0.323 29.007 0 55.436-15.908 68.974-41.516 14.941-28.2 11.264-62.223-9.356-86.694l-13.166-15.625L278.1 276.7c38.694-38.954 86.677-68.095 138.76-84.273l19.741-6.132 7.631 19.211c11.88 29.908 40.312 49.234 72.432 49.234 32.097 0 60.521-19.328 72.413-49.241l7.632-19.197 19.73 6.122c43.968 13.642 84.295 36.164 119.862 66.938l15.414 13.337-11.883 16.561c-18.636 25.975-19.684 60.166-2.671 87.105 14.369 22.78 39.055 36.373 66.04 36.372 4.344 0 8.71-0.366 12.978-1.087l20.143-3.403 5.176 19.762c7.539 28.792 11.362 57.566 11.362 85.522 0 21.328-2.143 43.048-6.365 64.554l-3.859 19.65-19.952-1.709a77.999 77.999 0 0 0-6.612-0.281c-28.998 0-55.44 15.917-69.009 41.542-14.47 27.405-11.311 60.816 8.063 85.095l12.496 15.661-14.222 14.111c-38.674 38.378-86.551 67.041-138.455 82.892l-18.968 5.792-7.988-18.152c-12.462-28.318-40.459-46.617-71.325-46.617-30.883 0-58.893 18.299-71.36 46.619l-7.99 18.152zm-95.455-94.18c22.324 16.82 46.59 30.174 72.469 39.881 22.445-34.023 60.731-55.125 102.336-55.125 41.59 0 79.862 21.1 102.303 55.12 32.745-12.298 63.249-30.557 89.663-53.667-19.709-35.774-20.525-79.555-1.04-116.455 19.699-37.203 56.634-61.386 98.053-64.883 1.705-12.731 2.565-25.453 2.565-38 0-18.339-1.923-37.155-5.729-56.144-42.123-0.241-80.616-21.581-103.077-57.189-22.944-36.331-25.024-81.029-6.697-118.768-22.165-16.932-46.203-30.4-71.788-40.221-8.847 14.328-20.577 26.719-34.618 36.447-20.522 14.219-44.602 21.735-69.635 21.735-25.044 0-49.131-7.516-69.657-21.734-14.042-9.727-25.773-22.116-34.618-36.441-32.551 12.503-62.856 30.935-89.106 54.196 21.198 36.233 22.547 80.974 2.407 118.987-19.71 37.285-56.808 61.499-98.402 64.875-1.45 11.713-2.161 23.035-2.161 34.255 0 19.715 2.166 39.792 6.449 59.894 41.851 0.474 80.029 21.785 102.35 57.214 22.218 35.217 24.782 78.871 7.933 116.023z" fill="#FFFFFF"/&gt;&lt;path d="M516.664 633.864c-66.246 0-120.141-53.897-120.141-120.147 0-66.249 53.895-120.146 120.141-120.146 66.237 0 120.127 53.897 120.127 120.146 0 66.25-53.89 120.147-120.127 120.147zm0-195.641c-41.625 0-75.488 33.866-75.488 75.494s33.863 75.495 75.488 75.495c41.617 0 75.475-33.867 75.475-75.495s-33.858-75.494-75.475-75.494z" fill="#FFFFFF"/&gt;&lt;/svg&gt;</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

View File

@ -1,63 +0,0 @@
using SqlSugar;
namespace DHSoftware.Models
{
[SugarTable("User")]
public class User
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
[SugarColumn(Length = 50, IsNullable = false)]
public string UserName { get; set; }
[SugarColumn(Length = 100, IsNullable = false)]
public string Password { get; set; }
[SugarColumn(IsNullable = true)]
public DateTime? LastLoginTime { get; set; }
}
[SugarTable("Role")]
public class Role
{
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
[SugarColumn(Length = 50, IsNullable = false)]
public string RoleName { get; set; }
[SugarColumn(Length = 200)]
public string Description { get; set; }
}
[SugarTable("Permission")]
public class Permission
{
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string Code { get; set; }
[SugarColumn(Length = 100, IsNullable = false)]
public string Name { get; set; }
}
[SugarTable("UserRole")]
public class UserRole
{
[SugarColumn(IsPrimaryKey = true)]
public int UserId { get; set; }
[SugarColumn(IsPrimaryKey = true)]
public int RoleId { get; set; }
}
[SugarTable("RolePermission")]
public class RolePermission
{
[SugarColumn(IsPrimaryKey = true)]
public int RoleId { get; set; }
[SugarColumn(IsPrimaryKey = true)]
public string PermissionCode { get; set; }
}
}

View File

@ -1,64 +0,0 @@
using DHSoftware.Models;
using DHSoftware.Utils;
using SqlSugar;
namespace DHSoftware.Services
{
public static class AuthService
{
public static User CurrentUser { get; private set; }
public static bool Login(string username, string password)
{
using (var db = DatabaseUtil.GetDatabase())
{
var user = db.Queryable<User>()
.First(u => u.UserName == username);
if (user != null && HashHelper.MD5Encrypt(password).Equals(user.Password))
{
CurrentUser = user;
UpdateLastLoginTime(db, user.Id);
return true;
}
return false;
}
}
public static bool HasPermission(string permissionCode)
{
if (CurrentUser == null) return false;
using (var db = DatabaseUtil.GetDatabase())
{
return db.Queryable<UserRole>()
.InnerJoin<RolePermission>((ur, rp) => ur.RoleId == rp.RoleId)
.Where((ur, rp) => ur.UserId == CurrentUser.Id)
.Where((ur, rp) => rp.PermissionCode == permissionCode)
.Any();
}
}
public static List<string> GetUserPermissions()
{
if (CurrentUser == null) return new List<string>();
using (var db = DatabaseUtil.GetDatabase())
{
return db.Queryable<UserRole>()
.InnerJoin<RolePermission>((ur, rp) => ur.RoleId == rp.RoleId)
.Where((ur, rp) => ur.UserId == CurrentUser.Id)
.Select((ur, rp) => rp.PermissionCode)
.ToList();
}
}
private static void UpdateLastLoginTime(SqlSugarClient db, int userId)
{
db.Updateable<User>()
.SetColumns(u => u.LastLoginTime == DateTime.Now)
.Where(u => u.Id == userId)
.ExecuteCommand();
}
}
}

View File

@ -37,12 +37,16 @@
button_ok = new AntdUI.Button();
divider2 = new AntdUI.Divider();
lbTitleName = new AntdUI.Label();
sltdetectionType = new AntdUI.Select();
label1 = new AntdUI.Label();
panel1.SuspendLayout();
stackPanel1.SuspendLayout();
SuspendLayout();
//
// panel1
//
panel1.Controls.Add(sltdetectionType);
panel1.Controls.Add(label1);
panel1.Controls.Add(input_name);
panel1.Controls.Add(label3);
panel1.Controls.Add(divider1);
@ -54,7 +58,7 @@
panel1.Name = "panel1";
panel1.Padding = new Padding(12);
panel1.Shadow = 6;
panel1.Size = new Size(500, 194);
panel1.Size = new Size(500, 243);
panel1.TabIndex = 0;
panel1.Text = "panel1";
//
@ -137,11 +141,31 @@
lbTitleName.TabIndex = 17;
lbTitleName.Text = "新增工位操作";
//
// sltdetectionType
//
sltdetectionType.Dock = DockStyle.Top;
sltdetectionType.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
sltdetectionType.Location = new Point(18, 196);
sltdetectionType.Name = "sltdetectionType";
sltdetectionType.Radius = 3;
sltdetectionType.Size = new Size(464, 38);
sltdetectionType.TabIndex = 24;
//
// label1
//
label1.Dock = DockStyle.Top;
label1.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
label1.Location = new Point(18, 172);
label1.Name = "label1";
label1.Size = new Size(464, 24);
label1.TabIndex = 23;
label1.Text = "检测类型";
//
// AddCubicleControl
//
Controls.Add(panel1);
Name = "AddCubicleControl";
Size = new Size(500, 194);
Size = new Size(500, 243);
panel1.ResumeLayout(false);
stackPanel1.ResumeLayout(false);
ResumeLayout(false);
@ -158,5 +182,7 @@
private AntdUI.Button button_cancel;
private AntdUI.Button button_ok;
private AntdUI.Divider divider2;
private AntdUI.Select sltdetectionType;
private AntdUI.Label label1;
}
}

View File

@ -1,5 +1,7 @@

using DH.Commons.Enums;
namespace DHSoftware.Views
{
public partial class AddCubicleControl : UserControl
@ -7,11 +9,17 @@ namespace DHSoftware.Views
private AntdUI.Window window;
public bool submit;
public string CubicleName;
public EnumDetectionType DetectionType;
public AddCubicleControl(AntdUI.Window _window,string TitleName)
{
this.window = _window;
InitializeComponent();
lbTitleName.Text = TitleName;
sltdetectionType.Items.Clear();
foreach (EnumDetectionType value in Enum.GetValues(typeof(EnumDetectionType)))
{
sltdetectionType.Items.Add(value.ToString());
}
// 绑定事件
BindEventHandler();
}
@ -38,7 +46,14 @@ namespace DHSoftware.Views
AntdUI.Message.warn(window, "工位名称不能为空!", autoClose: 3);
return;
}
CubicleName=input_name.Text;
if (String.IsNullOrEmpty(sltdetectionType.Text))
{
input_name.Status = AntdUI.TType.Error;
AntdUI.Message.warn(window, "请选择检测类型!", autoClose: 3);
return;
}
CubicleName =input_name.Text;
DetectionType = (EnumDetectionType)sltdetectionType.SelectedIndex;
submit = true;
this.Dispose();
}

View File

@ -87,7 +87,7 @@
this.tsmiClearLog2.Name = "tsmiClearLog2";
this.tsmiClearLog2.Size = new System.Drawing.Size(68, 21);
this.tsmiClearLog2.Text = "清空日志";
this.tsmiClearLog2.Click += new System.EventHandler(this.tsmiClearLog2_Click);
// this.tsmiClearLog2.Click += new System.EventHandler(this.tsmiClearLog2_Click);
//
// lvLog
//

View File

@ -11,226 +11,534 @@ using System.Threading.Tasks;
using System.Windows.Forms;
using static DH.Commons.Enums.EnumHelper;
using DH.Commons.Enums;
using System.ComponentModel;
using System.Reflection;
namespace DHSoftware.Views
{
{
public partial class FrmLog : UserControl
{
#region Win32 API双缓冲处理
private const int LVM_SETEXTENDEDLISTVIEWSTYLE = 0x1036;
private const int LVS_EX_DOUBLEBUFFER = 0x00010000;
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
#endregion
#region
private const string SOURCE_PROCESS = "流程";
private const int LOG_NUM_LIMIT = 2000;
private const int BATCH_SIZE = 50;
private const int PROCESS_INTERVAL = 100;
private const int FIRST_COL_WIDTH = 120;
#endregion
#region
private readonly ConcurrentQueue<LogMsg> _logQueue = new ConcurrentQueue<LogMsg>();
private List<LogMsg> _logBuffer = new List<LogMsg>();
private List<LogLevel> _showLevels = new List<LogLevel>();
private List<string> _showSources = new List<string>();
private Task _logTask;
private static readonly object _logLock = new object();
#endregion
public FrmLog()
{
InitializeComponent();
lvLog.ShowItemToolTips = true;
this.Load += (s, e) =>
{
_showLevels.Clear();
tsmiLogLevels.DropDownItems.Clear();
JsonConvert.DeserializeObject<List<dynamic>>(JsonConvert.SerializeObject(EnumHelper.GetEnumListByType(typeof(LogLevel)))).ForEach(d =>
{
LogLevel lvl = (LogLevel)((int)d.Value);
ToolStripMenuItem item = new ToolStripMenuItem(d.Desc.ToString());
item.CheckOnClick = true;
item.Checked = true;
item.Tag = lvl;
item.CheckedChanged += LevelItem_CheckedChanged;
item.BackColor = lvl.GetEnumSelectedColor();
item.ForeColor = lvl.GetEnumSelectedFontColor();
tsmiLogLevels.DropDownItems.Add(item);
_showLevels.Add(lvl);
});
};
InitializeCustomComponents();
}
//public override void OnProcessUpdated()
//{
private void InitializeCustomComponents()
{
// 启用双缓冲
SendMessage(lvLog.Handle, LVM_SETEXTENDEDLISTVIEWSTYLE,
LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER);
// Invoke(new Action(() =>
// {
// _showDevice.Clear();
// tsmiLogSources.DropDownItems.Clear();
// ToolStripMenuItem processItem = new ToolStripMenuItem(SOURCE_PROCESS);
// processItem.CheckOnClick = true;
// processItem.Checked = true;
// processItem.CheckedChanged += SourceItem_CheckedChanged;
// tsmiLogSources.DropDownItems.Add(processItem);
// _showDevice.Add(SOURCE_PROCESS);
lvLog.ShowItemToolTips = true;
lvLog.FullRowSelect = true;
lvLog.View = View.Details;
// 启用自定义绘制
//lvLog.OwnerDraw = true;
//lvLog.DrawColumnHeader += LvLog_DrawColumnHeader;
//lvLog.DrawSubItem += LvLog_DrawSubItem;
//lvLog.DrawItem += LvLog_DrawItem;
// Process.DeviceCollection.ForEach(d =>
// {
// ToolStripMenuItem item = new ToolStripMenuItem(d.Name);
// item.CheckOnClick = true;
// item.Checked = true;
// item.CheckedChanged += SourceItem_CheckedChanged;
// tsmiLogSources.DropDownItems.Add(item);
// _showDevice.Add(d.Name);
// });
// }));
//}
// 初始化列头
lvLog.Columns.Add("时间", FIRST_COL_WIDTH);
lvLog.Columns.Add("来源", 150);
lvLog.Columns.Add("内容", 400);
private void LevelItem_CheckedChanged(object sender, EventArgs e)
InitializeLevelFilter();
StartProcessingTask();
}
private void InitializeLevelFilter()
{
_showLevels.Clear();
foreach (ToolStripMenuItem item in tsmiLogLevels.DropDownItems)
tsmiLogLevels.DropDownItems.Clear();
foreach (LogLevel level in Enum.GetValues(typeof(LogLevel)))
{
if (item.Checked)
var item = new ToolStripMenuItem(level.GetEnumDescription())
{
LogLevel lv = (LogLevel)Convert.ToInt32(item.Tag);
_showLevels.Add(lv);
CheckOnClick = true,
Checked = true,
Tag = level,
BackColor = level.GetEnumSelectedColor(),
ForeColor = level.GetEnumSelectedFontColor()
};
item.CheckedChanged += LevelItem_CheckedChanged;
tsmiLogLevels.DropDownItems.Add(item);
_showLevels.Add(level);
}
}
#region
private void LvLog_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
e.DrawDefault = true;
}
private void LvLog_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
var item = e.Item;
var log = item.Tag as LogMsg;
// 设置背景色
e.Graphics.FillRectangle(new SolidBrush(log.LogLevel.GetEnumSelectedColor()), e.Bounds);
// 设置文字颜色
TextRenderer.DrawText(e.Graphics, e.SubItem.Text, lvLog.Font,
e.Bounds, log.LogLevel.GetEnumSelectedFontColor(), TextFormatFlags.Left);
}
//private ListViewItem CreateLogItem(LogMsg log)
//{
// var item = new ListViewItem(log.LogTime.ToString("HH:mm:ss.fff"));
// item.SubItems.Add(FormatSource(log));
// item.SubItems.Add(log.Msg);
// item.Tag = log; // 重要将日志对象绑定到Tag
// return item;
//}
private void LvLog_DrawItem(object sender, DrawListViewItemEventArgs e)
{
e.DrawDefault = false; // 禁用默认绘制
}
#endregion
private void StartProcessingTask()
{
lock (_logLock)
{
if (_logTask == null || _logTask.IsCompleted)
{
_logTask = Task.Run(ProcessLogs);
}
}
}
private async Task ProcessLogs()
{
while (!IsDisposed)
{
try
{
await Task.Delay(PROCESS_INTERVAL);
ProcessBatch(BATCH_SIZE);
}
catch (Exception ex)
{
DebugWrite($"日志处理异常: {ex.Message}");
}
}
}
private void ProcessBatch(int batchSize)
{
if (InvokeRequired)
{
BeginInvoke(new Action(() => ProcessBatch(batchSize)));
return;
}
lvLog.BeginUpdate();
try
{
var items = new List<ListViewItem>();
int processed = 0;
while (processed < batchSize && _logQueue.TryDequeue(out var log))
{
_logBuffer.Add(log);
if (ShouldShow(log))
{
items.Add(CreateLogItem(log));
processed++;
}
}
if (items.Count > 0)
{
lvLog.Items.AddRange(items.ToArray());
MaintainBuffer();
AutoScrollIfNeeded();
}
}
finally
{
lvLog.EndUpdate();
UpdateLayout();
}
}
private bool ShouldShow(LogMsg log)
{
return _showLevels.Contains(log.LogLevel) &&
(_showSources.Count == 0 ||
(string.IsNullOrEmpty(log.MsgSource) ?
_showSources.Contains(SOURCE_PROCESS) :
_showSources.Contains(log.MsgSource)));
}
private ListViewItem CreateLogItem(LogMsg log)
{
var item = new ListViewItem(log.LogTime.ToString("HH:mm:ss.fff"));
item.SubItems.Add(FormatSource(log));
item.SubItems.Add(log.Msg);
item.ToolTipText = log.Msg;
item.BackColor = log.LogLevel.GetEnumSelectedColor();
item.ForeColor = log.LogLevel.GetEnumSelectedFontColor();
return item;
}
private string FormatSource(LogMsg log)
{
return string.IsNullOrEmpty(log.MsgSource) ?
SOURCE_PROCESS :
$"{log.MsgSource}[{log.ThreadId}]";
}
private void MaintainBuffer()
{
if (_logBuffer.Count > LOG_NUM_LIMIT * 2)
{
_logBuffer = _logBuffer
.Skip(_logBuffer.Count - LOG_NUM_LIMIT)
.ToList();
RefreshLogs();
}
}
public void AddLog(LogMsg log)
{
_logQueue.Enqueue(log);
}
private void RefreshLogs()
{
lvLog.BeginUpdate();
try
{
lvLog.Items.Clear();
var items = _logBuffer
.Where(ShouldShow)
.Select(CreateLogItem);
lvLog.Items.AddRange(items.ToArray());
}
finally
{
lvLog.EndUpdate();
UpdateLayout();
}
}
private void AutoScrollIfNeeded()
{
if (lvLog.Items.Count > 0 /*&& chkAutoScroll.Checked*/)
{
lvLog.EnsureVisible(lvLog.Items.Count - 1);
}
}
private void UpdateLayout()
{
if (lvLog.Columns.Count < 3) return;
// 动态调整列宽
lvLog.Columns[0].Width = FIRST_COL_WIDTH;
lvLog.Columns[1].Width = lvLog.Width > 600 ? 150 : 0;
lvLog.Columns[2].Width = lvLog.ClientSize.Width -
lvLog.Columns[0].Width -
lvLog.Columns[1].Width -
SystemInformation.VerticalScrollBarWidth;
}
#region
private void LevelItem_CheckedChanged(object sender, EventArgs e)
{
_showLevels = tsmiLogLevels.DropDownItems
.Cast<ToolStripMenuItem>()
.Where(i => i.Checked)
.Select(i => (LogLevel)i.Tag)
.ToList();
RefreshLogs();
}
private void SourceItem_CheckedChanged(object sender, EventArgs e)
{
_showDevice.Clear();
foreach (ToolStripMenuItem item in tsmiLogSources.DropDownItems)
{
if (item.Checked)
{
_showDevice.Add(item.Text);
}
}
_showSources = tsmiLogSources.DropDownItems
.Cast<ToolStripMenuItem>()
.Where(i => i.Checked)
.Select(i => i.Text)
.ToList();
RefreshLogs();
}
//public TaskFactory _taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.LongRunning);
readonly ConcurrentQueue<LogMsg> _logQueue = new ConcurrentQueue<LogMsg>();
Task _logTask = null;
static readonly object _logLock = new object();
List<LogMsg> _logBuffer = new List<LogMsg>();
List<LogLevel> _showLevels = new List<LogLevel>();
List<string> _showDevice = new List<string>();
const string SOURCE_PROCESS = "流程";
const int LOG_NUM_LIMIT = 20;
public void LogDisplay(LogMsg msg)
{
_logQueue.Enqueue(msg);
lock (_logLock)
{
if (_logTask == null)
{
_logTask = Task.Run(async () =>
{
while (true)
{
try
{
Invoke(new Action(() =>
{
bool isNeedScroll = false;
while (_logQueue.TryDequeue(out LogMsg log))
{
_logBuffer.Add(log);
if (_showLevels.Contains(log.LogLevel) && (_showDevice.Count == 0 || (string.IsNullOrWhiteSpace(log.MsgSource) && _showDevice.Contains(SOURCE_PROCESS)) || _showDevice.Contains(log.MsgSource)))
{
isNeedScroll = true;
ListViewItem item = new ListViewItem($"{log.LogTime.ToString("HH:mm:ss.fff")}");
item.SubItems.Add($"{log.MsgSource}[{log.ThreadId}]");
item.SubItems.Add(log.Msg);
item.ToolTipText = log.Msg;
item.ForeColor = log.LogLevel.GetEnumSelectedFontColor();
item.BackColor = log.LogLevel.GetEnumSelectedColor();
lvLog.Items.Add(item);
}
}
if (_logBuffer.Count > LOG_NUM_LIMIT * 2)
{
_logBuffer = _logBuffer.Skip(_logBuffer.Count - LOG_NUM_LIMIT).ToList();
RefreshLogs();
isNeedScroll = true;
}
if (isNeedScroll && lvLog.Items.Count > 0)
{
RefreshLvLayout();
}
}));
}
catch (Exception ex)
{
}
await Task.Delay(2000);
}
});
}
}
}
private void RefreshLogs()
{
lvLog.Items.Clear();
_logBuffer.ForEach(log =>
{
if (_showLevels.Contains(log.LogLevel) && ((string.IsNullOrWhiteSpace(log.MsgSource) && _showDevice.Contains(SOURCE_PROCESS)) || _showDevice.Contains(log.MsgSource)))
{
ListViewItem item = new ListViewItem($"{log.LogTime.ToString("HH:mm:ss.fff")}");
item.SubItems.Add($"{log.MsgSource}[{log.ThreadId}]");
item.SubItems.Add(log.Msg);
item.ToolTipText = log.Msg;
item.ForeColor = log.LogLevel.GetEnumSelectedFontColor();
item.BackColor = log.LogLevel.GetEnumSelectedColor();
lvLog.Items.Add(item);
}
});
RefreshLvLayout();
}
private void lvLog_SizeChanged(object sender, EventArgs e)
{
RefreshLvLayout();
}
int width_1stCol = 80;
public event Action<LogMsg> OnLogMsgOutput;
private void RefreshLvLayout()
{
if (lvLog.Columns.Count <= 0)
return;
lvLog.Columns[0].Width = width_1stCol;
if (lvLog.Width <= lvLog.Height)
{
lvLog.Columns[1].Width = 0;
}
else
{
lvLog.Columns[1].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
}
lvLog.Columns[2].Width = lvLog.Width - width_1stCol - lvLog.Columns[1].Width - 10;
if (lvLog.Items.Count > 0)
lvLog.EnsureVisible(lvLog.Items.Count - 1);
}
private void tsmiClearLog_Click(object sender, EventArgs e)
{
lvLog.Items.Clear();
_logBuffer.Clear();
}
private void tsmiClearLog2_Click(object sender, EventArgs e)
private void lvLog_SizeChanged(object sender, EventArgs e)
{
lvLog.Items.Clear();
UpdateLayout();
}
#endregion
#region
private void DebugWrite(string message)
{
System.Diagnostics.Debug.WriteLine($"[{DateTime.Now:HH:mm:ss.fff}] {message}");
}
#endregion
}
//public partial class FrmLog1 : UserControl
//{
// // 添加双缓冲字段
// private const int LVM_SETEXTENDEDLISTVIEWSTYLE = 0x1036;
// private const int LVS_EX_DOUBLEBUFFER = 0x00010000;
// [System.Runtime.InteropServices.DllImport("user32.dll")]
// private static extern int SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
// public FrmLog()
// {
// InitializeComponent();
// // 启用双缓冲
// SendMessage(lvLog.Handle, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER);
// lvLog.ShowItemToolTips = true;
// this.Load += (s, e) =>
// {
// _showLevels.Clear();
// tsmiLogLevels.DropDownItems.Clear();
// JsonConvert.DeserializeObject<List<dynamic>>(JsonConvert.SerializeObject(EnumHelper.GetEnumListByType(typeof(LogLevel)))).ForEach(d =>
// {
// LogLevel lvl = (LogLevel)((int)d.Value);
// ToolStripMenuItem item = new ToolStripMenuItem(d.Desc.ToString());
// item.CheckOnClick = true;
// item.Checked = true;
// item.Tag = lvl;
// item.CheckedChanged += LevelItem_CheckedChanged;
// item.BackColor = lvl.GetEnumSelectedColor();
// item.ForeColor = lvl.GetEnumSelectedFontColor();
// tsmiLogLevels.DropDownItems.Add(item);
// _showLevels.Add(lvl);
// });
// };
// }
// //public override void OnProcessUpdated()
// //{
// // Invoke(new Action(() =>
// // {
// // _showDevice.Clear();
// // tsmiLogSources.DropDownItems.Clear();
// // ToolStripMenuItem processItem = new ToolStripMenuItem(SOURCE_PROCESS);
// // processItem.CheckOnClick = true;
// // processItem.Checked = true;
// // processItem.CheckedChanged += SourceItem_CheckedChanged;
// // tsmiLogSources.DropDownItems.Add(processItem);
// // _showDevice.Add(SOURCE_PROCESS);
// // Process.DeviceCollection.ForEach(d =>
// // {
// // ToolStripMenuItem item = new ToolStripMenuItem(d.Name);
// // item.CheckOnClick = true;
// // item.Checked = true;
// // item.CheckedChanged += SourceItem_CheckedChanged;
// // tsmiLogSources.DropDownItems.Add(item);
// // _showDevice.Add(d.Name);
// // });
// // }));
// //}
// private void LevelItem_CheckedChanged(object sender, EventArgs e)
// {
// _showLevels.Clear();
// foreach (ToolStripMenuItem item in tsmiLogLevels.DropDownItems)
// {
// if (item.Checked)
// {
// LogLevel lv = (LogLevel)Convert.ToInt32(item.Tag);
// _showLevels.Add(lv);
// }
// }
// RefreshLogs();
// }
// private void SourceItem_CheckedChanged(object sender, EventArgs e)
// {
// _showDevice.Clear();
// foreach (ToolStripMenuItem item in tsmiLogSources.DropDownItems)
// {
// if (item.Checked)
// {
// _showDevice.Add(item.Text);
// }
// }
// RefreshLogs();
// }
// //public TaskFactory _taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.LongRunning);
// readonly ConcurrentQueue<LogMsg> _logQueue = new ConcurrentQueue<LogMsg>();
// Task _logTask = null;
// static readonly object _logLock = new object();
// List<LogMsg> _logBuffer = new List<LogMsg>();
// List<LogLevel> _showLevels = new List<LogLevel>();
// List<string> _showDevice = new List<string>();
// const string SOURCE_PROCESS = "流程";
// const int LOG_NUM_LIMIT = 20;
// public void LogDisplay(LogMsg msg)
// {
// _logQueue.Enqueue(msg);
// lock (_logLock)
// {
// if (_logTask == null)
// {
// _logTask = Task.Run(async () =>
// {
// while (true)
// {
// try
// {
// Invoke(new Action(() =>
// {
// bool isNeedScroll = false;
// while (_logQueue.TryDequeue(out LogMsg log))
// {
// _logBuffer.Add(log);
// if (_showLevels.Contains(log.LogLevel) && (_showDevice.Count == 0 || (string.IsNullOrWhiteSpace(log.MsgSource) && _showDevice.Contains(SOURCE_PROCESS)) || _showDevice.Contains(log.MsgSource)))
// {
// isNeedScroll = true;
// ListViewItem item = new ListViewItem($"{log.LogTime.ToString("HH:mm:ss.fff")}");
// item.SubItems.Add($"{log.MsgSource}[{log.ThreadId}]");
// item.SubItems.Add(log.Msg);
// item.ToolTipText = log.Msg;
// item.ForeColor = log.LogLevel.GetEnumSelectedFontColor();
// item.BackColor = log.LogLevel.GetEnumSelectedColor();
// lvLog.Items.Add(item);
// }
// }
// if (_logBuffer.Count > LOG_NUM_LIMIT * 2)
// {
// _logBuffer = _logBuffer.Skip(_logBuffer.Count - LOG_NUM_LIMIT).ToList();
// RefreshLogs();
// isNeedScroll = true;
// }
// if (isNeedScroll && lvLog.Items.Count > 0)
// {
// RefreshLvLayout();
// }
// }));
// }
// catch (Exception ex)
// {
// }
// await Task.Delay(2000);
// }
// });
// }
// }
// }
// private void RefreshLogs()
// {
// lvLog.Items.Clear();
// _logBuffer.ForEach(log =>
// {
// if (_showLevels.Contains(log.LogLevel) && ((string.IsNullOrWhiteSpace(log.MsgSource) && _showDevice.Contains(SOURCE_PROCESS)) || _showDevice.Contains(log.MsgSource)))
// {
// ListViewItem item = new ListViewItem($"{log.LogTime.ToString("HH:mm:ss.fff")}");
// item.SubItems.Add($"{log.MsgSource}[{log.ThreadId}]");
// item.SubItems.Add(log.Msg);
// item.ToolTipText = log.Msg;
// item.ForeColor = log.LogLevel.GetEnumSelectedFontColor();
// item.BackColor = log.LogLevel.GetEnumSelectedColor();
// lvLog.Items.Add(item);
// }
// });
// RefreshLvLayout();
// }
// private void lvLog_SizeChanged(object sender, EventArgs e)
// {
// RefreshLvLayout();
// }
// int width_1stCol = 80;
// public event Action<LogMsg> OnLogMsgOutput;
// private void RefreshLvLayout()
// {
// if (lvLog.Columns.Count <= 0)
// return;
// lvLog.Columns[0].Width = width_1stCol;
// if (lvLog.Width <= lvLog.Height)
// {
// lvLog.Columns[1].Width = 0;
// }
// else
// {
// lvLog.Columns[1].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
// }
// lvLog.Columns[2].Width = lvLog.Width - width_1stCol - lvLog.Columns[1].Width - 10;
// if (lvLog.Items.Count > 0)
// lvLog.EnsureVisible(lvLog.Items.Count - 1);
// }
// private void tsmiClearLog_Click(object sender, EventArgs e)
// {
// lvLog.Items.Clear();
// }
// private void tsmiClearLog2_Click(object sender, EventArgs e)
// {
// lvLog.Items.Clear();
// }
//}
}

View File

@ -0,0 +1,36 @@
namespace DHSoftware.Views
{
partial class ImageViewerControl
{
/// <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()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@ -0,0 +1,306 @@
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace DHSoftware.Views
{
public partial class ImageViewerControl : UserControl
{
#region
private PictureBox pictureBox;
private Label statusLabel;
#endregion
#region
private Bitmap _currentImage;
private float _scale = 1.0f;
private PointF _offset = PointF.Empty;
private RectangleF _roiRect;
private PointF _roiStart;
private bool _isDrawing;
private Point _dragStart;
private bool _isDragging;
private Pen _roiPen = new Pen(Color.Red, 2);
#endregion
#region
#region
public Bitmap Image
{
get => _currentImage;
set
{
// 记录旧状态
var oldSize = _currentImage?.Size ?? Size.Empty;
var oldScale = _scale;
var oldOffset = _offset;
_currentImage?.Dispose();
_currentImage = value;
if (_currentImage != null)
{
if (_currentImage.Size != oldSize)
{
// 尺寸不同时重置ROI、自动适配
_roiRect = RectangleF.Empty;
AutoFit();
}
else
{
// 尺寸相同时:保留缩放和偏移
_scale = oldScale;
_offset = oldOffset;
ClampOffset();
}
}
pictureBox.Invalidate();
}
}
#endregion
public RectangleF CurrentROI => _roiRect;
#endregion
public ImageViewerControl()
{
InitializeComponents();
SetupDoubleBuffering();
}
#region
private void InitializeComponents()
{
// 主显示区域
pictureBox = new PictureBox
{
Dock = DockStyle.Fill,
BackColor = Color.DarkGray,
Cursor = Cursors.Cross
};
// 状态栏
statusLabel = new Label
{
Dock = DockStyle.Bottom,
Height = 20,
Text = "就绪",
BorderStyle = BorderStyle.FixedSingle,
Font = new Font("Consolas", 10)
};
// 事件绑定
pictureBox.MouseDown += PictureBox_MouseDown;
pictureBox.MouseMove += PictureBox_MouseMove;
pictureBox.MouseUp += PictureBox_MouseUp;
pictureBox.MouseWheel += PictureBox_MouseWheel;
pictureBox.Paint += PictureBox_Paint;
Controls.Add(pictureBox);
Controls.Add(statusLabel);
}
private void SetupDoubleBuffering()
{
typeof(PictureBox).GetMethod("SetStyle",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance)
?.Invoke(pictureBox, new object[] {
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint,
true
});
}
#endregion
#region
private void AutoFit()
{
if (_currentImage == null) return;
const float marginRatio = 0.1f;
float marginWidth = Width * marginRatio;
float marginHeight = Height * marginRatio;
_scale = Math.Min(
(Width - marginWidth * 2) / _currentImage.Width,
(Height - marginHeight * 2) / _currentImage.Height
);
_offset.X = marginWidth + (Width - marginWidth * 2 - _currentImage.Width * _scale) / 2;
_offset.Y = marginHeight + (Height - marginHeight * 2 - _currentImage.Height * _scale) / 2;
}
private void PictureBox_Paint(object sender, PaintEventArgs e)
{
if (_currentImage == null) return;
// 绘制图像
var destRect = new RectangleF(
_offset.X,
_offset.Y,
_currentImage.Width * _scale,
_currentImage.Height * _scale);
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
e.Graphics.DrawImage(_currentImage, destRect);
// 绘制ROI
if (!_roiRect.IsEmpty)
{
var displayRect = new RectangleF(
_roiRect.X * _scale + _offset.X,
_roiRect.Y * _scale + _offset.Y,
_roiRect.Width * _scale,
_roiRect.Height * _scale);
using (var pen = new Pen(_roiPen.Color, _roiPen.Width / _scale))
{
e.Graphics.DrawRectangle(pen,
displayRect.X,
displayRect.Y,
displayRect.Width,
displayRect.Height);
}
}
}
#endregion
#region
private void PictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && _currentImage != null)
{
_roiStart = ClampCoordinates(ConvertToImageCoords(e.Location));
_isDrawing = true;
}
else if (e.Button == MouseButtons.Right)
{
_dragStart = e.Location;
_isDragging = true;
}
}
private void PictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (_isDragging)
{
_offset.X += e.X - _dragStart.X;
_offset.Y += e.Y - _dragStart.Y;
_dragStart = e.Location;
ClampOffset();
pictureBox.Invalidate();
}
else if (_isDrawing && _currentImage != null)
{
PointF current = ClampCoordinates(ConvertToImageCoords(e.Location));
_roiRect = new RectangleF(
Math.Min(_roiStart.X, current.X),
Math.Min(_roiStart.Y, current.Y),
Math.Abs(_roiStart.X - current.X),
Math.Abs(_roiStart.Y - current.Y)
);
pictureBox.Invalidate();
}
UpdateStatus(e.Location);
}
private void PictureBox_MouseUp(object sender, MouseEventArgs e)
{
_isDragging = false;
_isDrawing = false;
}
private void PictureBox_MouseWheel(object sender, MouseEventArgs e)
{
if (_currentImage == null) return;
PointF mousePos = e.Location;
PointF imgPosBefore = ConvertToImageCoords(mousePos);
if (imgPosBefore.X < 0 || imgPosBefore.X > _currentImage.Width ||
imgPosBefore.Y < 0 || imgPosBefore.Y > _currentImage.Height) return;
float zoom = e.Delta > 0 ? 1.1f : 0.9f;
float newScale = Math.Clamp(_scale * zoom, 0.1f, 10f);
_offset.X = mousePos.X - imgPosBefore.X * newScale;
_offset.Y = mousePos.Y - imgPosBefore.Y * newScale;
_scale = newScale;
ClampOffset();
pictureBox.Invalidate();
}
#endregion
#region
private PointF ConvertToImageCoords(PointF mousePos)
{
return new PointF(
(mousePos.X - _offset.X) / _scale,
(mousePos.Y - _offset.Y) / _scale);
}
private PointF ClampCoordinates(PointF point)
{
return new PointF(
Math.Max(0, Math.Min(_currentImage.Width, point.X)),
Math.Max(0, Math.Min(_currentImage.Height, point.Y)));
}
private void ClampOffset()
{
if (_currentImage == null) return;
float imgWidth = _currentImage.Width * _scale;
float imgHeight = _currentImage.Height * _scale;
if (imgWidth <= Width)
{
_offset.X = Math.Clamp(_offset.X, 0, Width - imgWidth);
}
else
{
_offset.X = Math.Clamp(_offset.X, Width - imgWidth, 0);
}
if (imgHeight <= Height)
{
_offset.Y = Math.Clamp(_offset.Y, 0, Height - imgHeight);
}
else
{
_offset.Y = Math.Clamp(_offset.Y, Height - imgHeight, 0);
}
}
private void UpdateStatus(Point mousePos)
{
if (_currentImage == null) return;
PointF imgPos = ConvertToImageCoords(mousePos);
bool inImage = imgPos.X >= 0 && imgPos.X <= _currentImage.Width &&
imgPos.Y >= 0 && imgPos.Y <= _currentImage.Height;
string roiInfo = _roiRect.IsEmpty ?
"未选择区域" :
$"选区: X={_roiRect.X:0} Y={_roiRect.Y:0} {_roiRect.Width:0}x{_roiRect.Height:0}";
statusLabel.Text = inImage ?
$"坐标: ({imgPos.X:0}, {imgPos.Y:0}) | 缩放: {_scale * 100:0}% | {roiInfo}" :
$"图像尺寸: {_currentImage.Width}x{_currentImage.Height} | 缩放: {_scale * 100:0}% | {roiInfo}";
}
public void ClearROI()
{
_roiRect = RectangleF.Empty;
pictureBox.Invalidate(); // 触发重绘
UpdateStatus(Point.Empty); // 更新状态栏
}
#endregion
}
}

View File

@ -1,17 +1,17 @@
<?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
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>
@ -26,36 +26,36 @@
<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
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
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
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
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
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
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
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->

View File

@ -112,12 +112,20 @@ namespace DHSoftware.Views
}
}
DetectionConfig? detectionConfig = ConfigModel.DetectionList.Where(c => c.Name == clickedItem.Text).FirstOrDefault();
if (detectionConfig == null)
{
detectionConfig = new DetectionConfig();
}
//if (detectionConfig == null)
//{
// detectionConfig = new DetectionConfig();
//}
UserControl control1 = null;
control1 = new DetectControl(this, detectionConfig);
if (DH.Commons.Enums.EnumDetectionType.==detectionConfig?.DetectionType)
{
control1 = new DetectControl(this, detectionConfig);
}
else
{
control1=new SizeControl(this,detectionConfig);
}
if (control1 != null)
{
//容器添加控件需要调整dpi
@ -764,7 +772,7 @@ namespace DHSoftware.Views
if (workstationItem1 != null)
{
var form = new AddCubicleControl(this, "新增工位操作") { Size = new Size(300, 200) };
var form = new AddCubicleControl(this, "新增工位操作") { Size = new Size(300, 400) };
AntdUI.Modal.open(new AntdUI.Modal.Config(this, "", form, TType.None)
{
BtnHeight = 0,
@ -779,6 +787,7 @@ namespace DHSoftware.Views
workstationItem1.Sub.Add(newItem);
DetectionConfig detection = new DetectionConfig();
detection.Name = form.CubicleName;
detection.DetectionType = form.DetectionType;
ConfigModel.DetectionList.Add(detection);
}
else

View File

@ -1,104 +0,0 @@
namespace DHSoftware.Views
{
partial class SizeConfigControl
{
/// <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()
{
panel2 = new Panel();
label2 = new Label();
btnDelSizeParm = new AntdUI.Button();
tbSizeParm = new AntdUI.Table();
btnAddSizeParm = new AntdUI.Button();
panel2.SuspendLayout();
SuspendLayout();
//
// panel2
//
panel2.Controls.Add(label2);
panel2.Controls.Add(btnDelSizeParm);
panel2.Controls.Add(tbSizeParm);
panel2.Controls.Add(btnAddSizeParm);
panel2.Location = new Point(3, 3);
panel2.Name = "panel2";
panel2.Size = new Size(779, 286);
panel2.TabIndex = 36;
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(3, 5);
label2.Name = "label2";
label2.Size = new Size(56, 17);
label2.TabIndex = 25;
label2.Text = "尺寸参数";
//
// btnDelSizeParm
//
btnDelSizeParm.Location = new Point(93, 25);
btnDelSizeParm.Name = "btnDelSizeParm";
btnDelSizeParm.Size = new Size(84, 34);
btnDelSizeParm.TabIndex = 24;
btnDelSizeParm.Text = "删除";
//
// tbSizeParm
//
tbSizeParm.Location = new Point(3, 65);
tbSizeParm.Name = "tbSizeParm";
tbSizeParm.Size = new Size(773, 218);
tbSizeParm.TabIndex = 22;
tbSizeParm.Text = "table1";
//
// btnAddSizeParm
//
btnAddSizeParm.Location = new Point(3, 25);
btnAddSizeParm.Name = "btnAddSizeParm";
btnAddSizeParm.Size = new Size(84, 34);
btnAddSizeParm.TabIndex = 23;
btnAddSizeParm.Text = "新增";
//
// SizeConfigControl
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
BorderStyle = BorderStyle.FixedSingle;
Controls.Add(panel2);
Name = "SizeConfigControl";
Size = new Size(783, 290);
panel2.ResumeLayout(false);
panel2.PerformLayout();
ResumeLayout(false);
}
#endregion
private Panel panel2;
private Label label2;
private AntdUI.Button btnDelSizeParm;
private AntdUI.Table tbSizeParm;
private AntdUI.Button btnAddSizeParm;
}
}

View File

@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace DHSoftware.Views
{
public partial class SizeConfigControl : UserControl
{
public SizeConfigControl()
{
InitializeComponent();
}
}
}

151
DHSoftware/Views/SizeControl.Designer.cs generated Normal file
View File

@ -0,0 +1,151 @@
namespace DHSoftware.Views
{
partial class SizeControl
{
/// <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()
{
AntdUI.Tabs.StyleLine styleLine1 = new AntdUI.Tabs.StyleLine();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SizeControl));
tabPage3 = new AntdUI.TabPage();
tabPage4 = new AntdUI.TabPage();
tabs1 = new AntdUI.Tabs();
panel1 = new AntdUI.Panel();
btnSizeDel = new AntdUI.Button();
btnSizeAdd = new AntdUI.Button();
SizeTable = new AntdUI.Table();
tabPage3.SuspendLayout();
tabPage4.SuspendLayout();
tabs1.SuspendLayout();
panel1.SuspendLayout();
SuspendLayout();
//
// tabPage3
//
tabPage3.Controls.Add(tabPage4);
tabPage3.Location = new Point(3, 31);
tabPage3.Name = "tabPage3";
tabPage3.Size = new Size(909, 575);
tabPage3.TabIndex = 3;
tabPage3.Text = "尺寸测量";
//
// tabPage4
//
tabPage4.Controls.Add(SizeTable);
tabPage4.Controls.Add(panel1);
tabPage4.Location = new Point(8, 8);
tabPage4.Name = "tabPage4";
tabPage4.Size = new Size(909, 575);
tabPage4.TabIndex = 1;
tabPage4.Text = "预处理";
//
// tabs1
//
tabs1.Centered = true;
tabs1.Dock = DockStyle.Fill;
tabs1.Font = new Font("Microsoft YaHei UI", 10.5F, FontStyle.Regular, GraphicsUnit.Point, 134);
tabs1.Location = new Point(0, 0);
tabs1.Name = "tabs1";
tabs1.Pages.Add(tabPage3);
tabs1.Size = new Size(915, 609);
tabs1.Style = styleLine1;
tabs1.TabIndex = 1;
tabs1.Text = "tabs1";
//
// panel1
//
panel1.Controls.Add(btnSizeDel);
panel1.Controls.Add(btnSizeAdd);
panel1.Dock = DockStyle.Top;
panel1.Location = new Point(0, 0);
panel1.Name = "panel1";
panel1.Size = new Size(909, 42);
panel1.TabIndex = 9;
panel1.Text = "panel1";
//
// btnSizeDel
//
btnSizeDel.BorderWidth = 2F;
btnSizeDel.Dock = DockStyle.Left;
btnSizeDel.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
btnSizeDel.Ghost = true;
btnSizeDel.IconRatio = 0.8F;
btnSizeDel.IconSvg = resources.GetString("btnSizeDel.IconSvg");
btnSizeDel.Location = new Point(80, 0);
btnSizeDel.Name = "btnSizeDel";
btnSizeDel.Size = new Size(80, 42);
btnSizeDel.TabIndex = 12;
btnSizeDel.Text = "删除";
//
// btnSizeAdd
//
btnSizeAdd.BorderWidth = 2F;
btnSizeAdd.Dock = DockStyle.Left;
btnSizeAdd.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
btnSizeAdd.Ghost = true;
btnSizeAdd.IconRatio = 0.8F;
btnSizeAdd.IconSvg = resources.GetString("btnSizeAdd.IconSvg");
btnSizeAdd.Location = new Point(0, 0);
btnSizeAdd.Name = "btnSizeAdd";
btnSizeAdd.Size = new Size(80, 42);
btnSizeAdd.TabIndex = 11;
btnSizeAdd.Text = "新增";
//
// SizeTable
//
SizeTable.Dock = DockStyle.Fill;
SizeTable.EmptyHeader = true;
SizeTable.Location = new Point(0, 42);
SizeTable.Name = "SizeTable";
SizeTable.Size = new Size(909, 533);
SizeTable.TabIndex = 10;
SizeTable.Text = "table1";
//
// SizeControl
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(tabs1);
Name = "SizeControl";
Size = new Size(915, 609);
tabPage3.ResumeLayout(false);
tabPage4.ResumeLayout(false);
tabs1.ResumeLayout(false);
panel1.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private AntdUI.TabPage tabPage3;
private AntdUI.TabPage tabPage4;
private AntdUI.Tabs tabs1;
private AntdUI.Table SizeTable;
private AntdUI.Panel panel1;
private AntdUI.Button btnSizeDel;
private AntdUI.Button btnSizeAdd;
}
}

View File

@ -0,0 +1,223 @@
using System.ComponentModel;
using System.Data;
using System.Reflection;
using AntdUI;
using DH.Commons.Base;
using DH.Commons.Enums;
using DH.Devices.PLC;
using XKRS.CanFly;
using static System.Windows.Forms.AxHost;
using static DH.Commons.Enums.EnumHelper;
namespace DHSoftware.Views
{
public partial class SizeControl : UserControl
{
Window window;
DetectionConfig detectionConfig;
public SizeControl(Window _window,DetectionConfig _detection)
{
window = _window;
detectionConfig = _detection;
InitializeComponent();
//初始化表格列头
InitTableColumns();
InitData();
BindEventHandler();
}
private void BindEventHandler()
{
btnSizeAdd.Click += BtnSizeAdd_Click;
btnSizeDel.Click += BtnSizeDelete_Click;
SizeTable.CellButtonClick += SizeTable_CellButtonClick;
}
private void SizeTable_CellButtonClick(object sender, TableButtonEventArgs e)
{
var buttontext = e.Btn.Text;
if (e.Record is SizeTreatParam sizeTreat)
{
switch (buttontext)
{
//暂不支持进入整行编辑,只支持指定单元格编辑,推荐使用弹窗或抽屉编辑整行数据
case "编辑":
var form = new SizeLabelEdit(window, sizeTreat) { 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)
detectionConfig.SizeTreatParamList.Remove(sizeTreat);
break;
case "进行测量":
var sizeType = ((int)sizeTreat.PreType).ToString();
// 根据测量类型打开不同的窗口
switch (sizeType)
{
case "1":
case "2":
case "3":
case "4":
case "5":
FrmMain3 frmMain3 = new FrmMain3(sizeType);
frmMain3.ShowDialog();
if (!string.IsNullOrEmpty(frmMain3.inputtext))
{
sizeTreat.ResultShow = frmMain3.inputtext;
}
if (!string.IsNullOrEmpty(frmMain3.outtext))
{
sizeTreat.OutResultShow = frmMain3.outtext;
}
break;
default:
MessageBox.Show("未定义的测量类型!");
break;
}
//使用clone可以防止table中的image被修改
//Preview.open(new Preview.Config(window, (Image)SizeParamLable.CellImages[0].Image.Clone()));
break;
}
}
}
private void BtnSizeDelete_Click(object? sender, EventArgs e)
{
if (detectionConfig.SizeTreatParamList.Count == 0 || !detectionConfig.SizeTreatParamList.Any(x => x.Selected))
{
AntdUI.Message.warn(window, "请选择要删除的行!", autoClose: 3);
return;
}
var result = Modal.open(window, "删除警告!", "确认要删除选择的数据吗?", TType.Warn);
if (result == DialogResult.OK)
{
// 使用反转for循环删除主列表中选中的项
for (int i = detectionConfig.SizeTreatParamList.Count - 1; i >= 0; i--)
{
// 删除选中的主列表项
if (detectionConfig.SizeTreatParamList[i].Selected)
{
detectionConfig.SizeTreatParamList.RemoveAt(i);
}
}
// 提示删除完成
AntdUI.Message.success(window, "删除成功!", autoClose: 3);
}
}
private void BtnSizeAdd_Click(object? sender, EventArgs e)
{
SizeTreatParam SizeParamLable = new SizeTreatParam()
{
//CellBadge = new CellBadge(SizeEnum.Circle.GetEnumDescription()),
CellLinks = new CellLink[] {
new CellButton(Guid.NewGuid().ToString(),"编辑",TTypeMini.Primary),
new CellButton(Guid.NewGuid().ToString(),"删除",TTypeMini.Error),
new CellButton(Guid.NewGuid().ToString(),"进行测量",TTypeMini.Primary)
}
};
var form = new SizeLabelEdit(window, SizeParamLable) { Size = new Size(450, 500) };
AntdUI.Modal.open(new AntdUI.Modal.Config(window, "", form, TType.None)
{
BtnHeight = 0,
});
if (form.submit)
{
detectionConfig.SizeTreatParamList.Add(SizeParamLable);
}
}
private void InitData()
{
SizeTable.Binding(detectionConfig.SizeTreatParamList);
if (detectionConfig.SizeTreatParamList.Count > 0)
{
foreach (var item in detectionConfig.SizeTreatParamList)
{
item.CellLinks = new CellLink[] {
new CellButton(Guid.NewGuid().ToString(), "编辑", TTypeMini.Primary) ,
new CellButton(Guid.NewGuid().ToString(), "删除", TTypeMini.Error),
new CellButton(Guid.NewGuid().ToString(),"进行测量",TTypeMini.Primary)
};
}
}
}
private void InitTableColumns()
{
SizeTable.Columns = new ColumnCollection() {
new ColumnCheck("Selected"){Fixed = true},
new ColumnSwitch("IsEnable", "是否启用", ColumnAlign.Center),
new Column("PreName", "测量名称",ColumnAlign.Center),
new Column("PreType", "测量类型", ColumnAlign.Center),
new Column("PrePix", "阈值", ColumnAlign.Center),
new Column("ResultShow", "输入参数", ColumnAlign.Center),
new Column("OutResultShow", "输出参数", ColumnAlign.Center),
new Column("CellLinks", "操作", ColumnAlign.Center)
};
}
}
}

View File

@ -0,0 +1,126 @@
<?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>
<data name="btnSizeDel.IconSvg" xml:space="preserve">
<value>&lt;svg t="1741939836774" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21349" width="200" height="200"&gt;&lt;path d="M1003.153333 404.96a52.933333 52.933333 0 0 0-42.38-20.96H896V266.666667a53.393333 53.393333 0 0 0-53.333333-53.333334H461.253333a10.573333 10.573333 0 0 1-7.54-3.126666L344.46 100.953333A52.986667 52.986667 0 0 0 306.746667 85.333333H53.333333a53.393333 53.393333 0 0 0-53.333333 53.333334v704a53.393333 53.393333 0 0 0 53.333333 53.333333h796.893334a53.453333 53.453333 0 0 0 51.453333-39.333333l110.546667-405.333334a52.953333 52.953333 0 0 0-9.073334-46.373333zM53.333333 128h253.413334a10.573333 10.573333 0 0 1 7.54 3.126667l109.253333 109.253333A52.986667 52.986667 0 0 0 461.253333 256H842.666667a10.666667 10.666667 0 0 1 10.666666 10.666667v117.333333H173.773333a53.453333 53.453333 0 0 0-51.453333 39.333333L42.666667 715.366667V138.666667a10.666667 10.666667 0 0 1 10.666666-10.666667zm917.726667 312.14l-110.546667 405.333333a10.666667 10.666667 0 0 1-10.286666 7.86H63.226667a10.666667 10.666667 0 0 1-10.286667-13.473333l110.546667-405.333333A10.666667 10.666667 0 0 1 173.773333 426.666667h787a10.666667 10.666667 0 0 1 10.286667 13.473333z" fill="#5C5C66" p-id="21350"/&gt;&lt;/svg&gt;</value>
</data>
<data name="btnSizeAdd.IconSvg" xml:space="preserve">
<value>&lt;svg t="1741939836774" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21349" width="200" height="200"&gt;&lt;path d="M1003.153333 404.96a52.933333 52.933333 0 0 0-42.38-20.96H896V266.666667a53.393333 53.393333 0 0 0-53.333333-53.333334H461.253333a10.573333 10.573333 0 0 1-7.54-3.126666L344.46 100.953333A52.986667 52.986667 0 0 0 306.746667 85.333333H53.333333a53.393333 53.393333 0 0 0-53.333333 53.333334v704a53.393333 53.393333 0 0 0 53.333333 53.333333h796.893334a53.453333 53.453333 0 0 0 51.453333-39.333333l110.546667-405.333334a52.953333 52.953333 0 0 0-9.073334-46.373333zM53.333333 128h253.413334a10.573333 10.573333 0 0 1 7.54 3.126667l109.253333 109.253333A52.986667 52.986667 0 0 0 461.253333 256H842.666667a10.666667 10.666667 0 0 1 10.666666 10.666667v117.333333H173.773333a53.453333 53.453333 0 0 0-51.453333 39.333333L42.666667 715.366667V138.666667a10.666667 10.666667 0 0 1 10.666666-10.666667zm917.726667 312.14l-110.546667 405.333333a10.666667 10.666667 0 0 1-10.286666 7.86H63.226667a10.666667 10.666667 0 0 1-10.286667-13.473333l110.546667-405.333333A10.666667 10.666667 0 0 1 173.773333 426.666667h787a10.666667 10.666667 0 0 1 10.286667 13.473333z" fill="#5C5C66" p-id="21350"/&gt;&lt;/svg&gt;</value>
</data>
</root>

View File

@ -49,7 +49,7 @@ namespace DHSoftware.Views
detect._window = this._windows;
// 添加尺寸测量控件
var sizeFrm = new SizeConfigControl();
//var sizeFrm = new SizeControl();
CameraConfigControl camConfigFrm = new CameraConfigControl();
@ -123,7 +123,7 @@ namespace DHSoftware.Views
panel2.Controls.Add(ptuc);
panel3.Controls.Add(flowmodel);
panel3.Controls.Add(detect);
panel4.Controls.Add(sizeFrm);
//panel4.Controls.Add(sizeFrm);
group1.Controls.Add(panel);
group2.Controls.Add(panel2);
group3.Controls.Add(panel3);