This commit is contained in:
liyaobang 2025-04-16 08:52:53 +08:00
parent 72b67b6a2f
commit 28e15a556d
17 changed files with 965 additions and 294 deletions

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;
@ -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("显示位置")]

View File

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

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">

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

@ -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);