This commit is contained in:
liyaobang 2025-03-18 14:19:33 +08:00
parent 25cd61c5cb
commit 0dedff36fd
29 changed files with 2296 additions and 615 deletions

View File

@ -1,130 +1,300 @@
using System.ComponentModel;
using System;
using System.ComponentModel;
using System.Drawing.Imaging;
using AntdUI;
using OpenCvSharp;
namespace DH.Devices.Devices
{
public class CameraBase
public class CameraBase : NotifyProperty
{
// 私有字段 + 带通知的属性与DetectionLabel风格一致
private bool _isEnabled = false;
private bool _isContinueMode = false;
private bool _isSavePicEnabled = false;
private string _imageSaveDirectory;
private ImageFormat _imageFormat = ImageFormat.Jpeg;
private bool _isHardwareTrigger = false;
private string _serialNumber = string.Empty;
private string _cameraName = string.Empty;
private string _cameraIP = string.Empty;
private string _computerIP = string.Empty;
private bool _isDirectHardwareTrigger = false;
private float _gain = -1;
private float _rotateImage = 0;
private float _exposure = 200;
private float _triggerDelay = 0;
private decimal _roiX = 0;
private decimal _roiY = 0;
private decimal _roiW = 0;
private decimal _roiH = 0;
private int _lineDebouncerTime = 0;
public volatile int SnapshotCount = 0;
public virtual bool isEnabled { get; set; } = false;
[Category("采图模式")]
[Description("是否连续模式。true连续模式采图false触发模式采图")]
[DisplayName("连续模式")]
public bool IsContinueMode { get; set; } = false;
[Description("是否连续模式。true连续模式采图false触发模式采图")]
public bool IsContinueMode
{
get => _isContinueMode;
set
{
if (_isContinueMode == value) return;
_isContinueMode = value;
OnPropertyChanged(nameof(IsContinueMode));
}
}
public virtual bool IsEnabled
{
get => _isEnabled;
set
{
if (_isEnabled == value) return;
_isEnabled = value;
OnPropertyChanged(nameof(IsEnabled));
}
}
public virtual bool isSavePicEnabled { get; set; } = false;
public virtual bool IsSavePicEnabled
{
get => _isSavePicEnabled;
set
{
if (_isSavePicEnabled == value) return;
_isSavePicEnabled = value;
OnPropertyChanged(nameof(IsSavePicEnabled));
}
}
[Category("图片保存")]
[Description("图片保存文件夹")]
[DisplayName("图片保存文件夹")]
public virtual string ImageSaveDirectory { get; set; }
[Description("图片保存文件夹")]
public virtual string ImageSaveDirectory
{
get => _imageSaveDirectory;
set
{
if (_imageSaveDirectory == value) return;
_imageSaveDirectory = value;
OnPropertyChanged(nameof(ImageSaveDirectory));
}
}
[Category("图片保存")]
[Description("图片保存格式")]
[DisplayName("图片保存格式")]
public ImageFormat ImageFormat { get; set; } = ImageFormat.Jpeg;
[Description("图片保存格式")]
public ImageFormat ImageFormat
{
get => _imageFormat;
set
{
if (_imageFormat == value) return;
_imageFormat = value;
OnPropertyChanged(nameof(ImageFormat));
}
}
[Category("采图模式")]
[Description("是否硬触发模式。true硬触发false软触发")]
[DisplayName("硬触发")]
public bool IsHardwareTrigger { get; set; } = false;
[Description("是否硬触发模式。true硬触发false软触发")]
public bool IsHardwareTrigger
{
get => _isHardwareTrigger;
set
{
if (_isHardwareTrigger == value) return;
_isHardwareTrigger = value;
OnPropertyChanged(nameof(IsHardwareTrigger));
}
}
public string SerialNumber { get; set; } = string.Empty;
public string CameraName { get; set; } = string.Empty;
public string SerialNumber
{
get => _serialNumber;
set
{
if (_serialNumber == value) return;
_serialNumber = value;
OnPropertyChanged(nameof(SerialNumber));
}
}
public string CameraIP { get; set; } = string.Empty;
public string CameraName
{
get => _cameraName;
set
{
if (_cameraName == value) return;
_cameraName = value;
OnPropertyChanged(nameof(CameraName));
}
}
public string ComputerIP { get; set; } = string.Empty;
public string CameraIP
{
get => _cameraIP;
set
{
if (_cameraIP == value) return;
_cameraIP = value;
OnPropertyChanged(nameof(CameraIP));
}
}
public string ComputerIP
{
get => _computerIP;
set
{
if (_computerIP == value) return;
_computerIP = value;
OnPropertyChanged(nameof(ComputerIP));
}
}
// public StreamFormat dvpStreamFormat = dvpStreamFormat.;
[Category("采图模式")]
[Description("是否传感器直接硬触发。true传感器硬触发不通过软件触发false通过软件触发IO 的硬触发模式")]
[DisplayName("是否传感器直接硬触发")]
public bool IsDirectHardwareTrigger { get; set; } = false;
[Description("是否传感器直接硬触发。true传感器硬触发不通过软件触发false通过软件触发IO 的硬触发模式")]
public bool IsDirectHardwareTrigger
{
get => _isDirectHardwareTrigger;
set
{
if (_isDirectHardwareTrigger == value) return;
_isDirectHardwareTrigger = value;
OnPropertyChanged(nameof(IsDirectHardwareTrigger));
}
}
/// <summary>
/// 增益
/// </summary>
[Category("相机设置")]
[DisplayName("增益")]
[Description("Gain增益,-1:不设置不同型号相机的增益请参考mvs")]
public float Gain { get; set; } = -1;
public float Gain
{
get => _gain;
set
{
if (_gain.Equals(value)) return;
_gain = value;
OnPropertyChanged(nameof(Gain));
}
}
[Category("图像旋转")]
[Description("默认旋转,相机开启后默认不旋转")]
[DisplayName("默认旋转")]
public virtual float RotateImage { get; set; } = 0;
[Description("默认旋转,相机开启后默认不旋转")]
public virtual float RotateImage
{
get => _rotateImage;
set
{
if (_rotateImage.Equals(value)) return;
_rotateImage = value;
OnPropertyChanged(nameof(RotateImage));
}
}
[Category("取像配置")]
[Description("曝光")]
[DisplayName("曝光")]
public virtual float Exposure { get; set; } = 200;
[Description("曝光")]
public virtual float Exposure
{
get => _exposure;
set
{
if (_exposure.Equals(value)) return;
_exposure = value;
OnPropertyChanged(nameof(Exposure));
}
}
[Category("相机设置")]
[DisplayName("硬触发后的延迟")]
[Description("TriggerDelay:硬触发后的延迟,单位us 微秒")]
public float TriggerDelay { get; set; } = 0;
public float TriggerDelay
{
get => _triggerDelay;
set
{
if (_triggerDelay.Equals(value)) return;
_triggerDelay = value;
OnPropertyChanged(nameof(TriggerDelay));
}
}
public decimal ROIX
{
get => _roiX;
set
{
if (_roiX == value) return;
_roiX = value;
OnPropertyChanged(nameof(ROIX));
}
}
public decimal ROIY
{
get => _roiY;
set
{
if (_roiY == value) return;
_roiY = value;
OnPropertyChanged(nameof(ROIY));
}
}
public decimal ROIW
{
get => _roiW;
set
{
if (_roiW == value) return;
_roiW = value;
OnPropertyChanged(nameof(ROIW));
}
}
public decimal ROIH
{
get => _roiH;
set
{
if (_roiH == value) return;
_roiH = value;
OnPropertyChanged(nameof(ROIH));
}
}
/// <summary>
/// 滤波时间
/// </summary>
[Category("相机设置")]
[DisplayName("滤波时间")]
[Description("LineDebouncerTimeI/O去抖时间 单位us")]
public int LineDebouncerTime { get; set; } = 0;
public int LineDebouncerTime
{
get => _lineDebouncerTime;
set
{
if (_lineDebouncerTime == value) return;
_lineDebouncerTime = value;
OnPropertyChanged(nameof(LineDebouncerTime));
}
}
// 其他方法保持原有逻辑
public Action<DateTime, CameraBase, Mat> OnHImageOutput { get; set; }
/// <summary>
/// 相机连接
/// </summary>
/// <returns>是否成功</returns>
public virtual bool CameraConnect() { return false; }
/// <summary>
/// 相机断开
/// </summary>
/// <returns>是否成功</returns>
public virtual bool CameraDisConnect() { return false; }
/// <summary>
/// 抓取一张图像
/// </summary>
/// <returns>图像</returns>
//internal virtual HObject GrabOneImage(string cameraName) { return null; }
/// <summary>
/// 设置曝光时间
/// </summary>
/// <param name="exposureTime">曝光时间</param>
public virtual void SetExposure(int exposureTime, string cameraName) { }
/// <summary>
/// 设置增益
/// </summary>
/// <param name="exposure">增益</param>
public virtual void SetGain(int gain, string cameraName) { }
/// <summary>
/// 设置采集模式
/// </summary>
/// <param name="mode">0=连续采集,即异步采集 1=单次采集,即同步采集</param>
internal virtual void SetAcquisitionMode(int mode) { }
/// <summary>
/// 设置采集图像的ROI
/// </summary>
internal virtual void SetAcqRegion(int offsetV, int offsetH, int imageH, int imageW, string cameraName) { }
}
}
}

View File

@ -17,6 +17,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="AntdUI" Version="1.8.9" />
<PackageReference Include="OpenCvSharp4" Version="4.10.0.20241108" />
<PackageReference Include="OpenCvSharp4.Extensions" Version="4.10.0.20241108" />
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.10.0.20241108" />

View File

@ -542,5 +542,15 @@ namespace DH.Commons.Enums
//[Description("插补模式")]
//Coordinate = 11
}
public enum CameraAcquisitionMode
{
=0,
=1
}
public enum CameraTriggerMode
{
= 0,
= 1
}
}

View File

@ -78,92 +78,94 @@ namespace DH.Devices.Camera
//GC.KeepAlive(pCallBackFunc);
//// ch:设置采集连续模式 | en:Set Continues Aquisition Mode
//if (IIConfig.IsContinueMode)
//{
// // ch:设置触发模式为off || en:set trigger mode as off
// nRet = DVPCamera.dvpSetTriggerState(m_handle, false);
// if (dvpStatus.DVP_STATUS_OK != nRet)
// {
// throw new Exception("Set TriggerMode failed!");
// }
//}
//else
//{
// ch:设置触发模式为on || en:set trigger mode as on
nRet = DVPCamera.dvpSetTriggerState(m_handle, true);
if (dvpStatus.DVP_STATUS_OK != nRet)
if (IsContinueMode)
{
throw new Exception("Set TriggerMode failed!");
// ch:设置触发模式为off || en:set trigger mode as off
nRet = DVPCamera.dvpSetTriggerState(m_handle, false);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception("Set TriggerMode failed!");
}
}
// 硬触发
//if (IIConfig.IsHardwareTrigger)
//{
// ch:触发源选择:1 - Line1; | en:Trigger source select:1 - Line1;
nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_LINE1);
if (dvpStatus.DVP_STATUS_OK != nRet)
else
{
throw new Exception("Set Line1 Trigger failed!");
// ch:设置触发模式为on || en:set trigger mode as on
nRet = DVPCamera.dvpSetTriggerState(m_handle, true);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception("Set TriggerMode failed!");
}
// 硬触发
if (IsHardwareTrigger)
{
// ch:触发源选择:1 - Line1; | en:Trigger source select:1 - Line1;
nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_LINE1);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception("Set Line1 Trigger failed!");
}
// ch:注册回调函数 | en:Register image callback
ImageCallback = new DVPCamera.dvpStreamCallback(ImageCallbackFunc);
nRet = DVPCamera.dvpRegisterStreamCallback(m_handle, ImageCallback, dvpStreamEvent.STREAM_EVENT_PROCESSED, IntPtr.Zero);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception("Register image callback failed!");
}
}
else // 软触发
{
nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_SOFTWARE);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception("Set Software Trigger failed!");
}
}
// ch:开启抓图 || en: start grab image
nRet = DVPCamera.dvpStart(m_handle);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception($"Start grabbing failed:{nRet:x8}");
}
//// 曝光
//if (IIConfig.DefaultExposure != 0)
//{
// SetExposure(IIConfig.DefaultExposure);
//}
//// 增益
//if (IIConfig.Gain >= 0)
//{
// SetGain(IIConfig.Gain);
//}
//SetPictureRoi(IIConfig.VelocityPara.A_Pic_X, IIConfig.VelocityPara.A_Pic_Y, IIConfig.VelocityPara.Width, IIConfig.VelocityPara.Hight);
//// 设置 触发延迟
//if (IIConfig.TriggerDelay > 0)
//{
// nRet = DVPCamera.dvpSetTriggerDelay(m_handle, IIConfig.TriggerDelay);
// if (nRet != dvpStatus.DVP_STATUS_OK)
// {
// throw new Exception("Set TriggerDelay failed!");
// }
//}
//// 信号消抖
//if (IIConfig.LineDebouncerTime > 0)
//{
// nRet = DVPCamera.dvpSetTriggerJitterFilter(m_handle, IIConfig.LineDebouncerTime);
// if (nRet != dvpStatus.DVP_STATUS_OK)
// {
// throw new Exception($"LineDebouncerTime set failed:{nRet}");
// }
//}
//IIConfig.PropertyChanged -= IIConfig_PropertyChanged;
//IIConfig.PropertyChanged += IIConfig_PropertyChanged;
}
// ch:注册回调函数 | en:Register image callback
ImageCallback = new DVPCamera.dvpStreamCallback(ImageCallbackFunc);
nRet = DVPCamera.dvpRegisterStreamCallback(m_handle, ImageCallback, dvpStreamEvent.STREAM_EVENT_PROCESSED, IntPtr.Zero);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception("Register image callback failed!");
}
//}
//else // 软触发
//{
// nRet = DVPCamera.dvpSetTriggerSource(m_handle, dvpTriggerSource.TRIGGER_SOURCE_SOFTWARE);
// if (dvpStatus.DVP_STATUS_OK != nRet)
// {
// throw new Exception("Set Software Trigger failed!");
// }
//}
// ch:开启抓图 || en: start grab image
nRet = DVPCamera.dvpStart(m_handle);
if (dvpStatus.DVP_STATUS_OK != nRet)
{
throw new Exception($"Start grabbing failed:{nRet:x8}");
}
//// 曝光
//if (IIConfig.DefaultExposure != 0)
//{
// SetExposure(IIConfig.DefaultExposure);
//}
//// 增益
//if (IIConfig.Gain >= 0)
//{
// SetGain(IIConfig.Gain);
//}
//SetPictureRoi(IIConfig.VelocityPara.A_Pic_X, IIConfig.VelocityPara.A_Pic_Y, IIConfig.VelocityPara.Width, IIConfig.VelocityPara.Hight);
//// 设置 触发延迟
//if (IIConfig.TriggerDelay > 0)
//{
// nRet = DVPCamera.dvpSetTriggerDelay(m_handle, IIConfig.TriggerDelay);
// if (nRet != dvpStatus.DVP_STATUS_OK)
// {
// throw new Exception("Set TriggerDelay failed!");
// }
//}
//// 信号消抖
//if (IIConfig.LineDebouncerTime > 0)
//{
// nRet = DVPCamera.dvpSetTriggerJitterFilter(m_handle, IIConfig.LineDebouncerTime);
// if (nRet != dvpStatus.DVP_STATUS_OK)
// {
// throw new Exception($"LineDebouncerTime set failed:{nRet}");
// }
//}
//IIConfig.PropertyChanged -= IIConfig_PropertyChanged;
//IIConfig.PropertyChanged += IIConfig_PropertyChanged;
return true;
}
catch

View File

@ -11,6 +11,7 @@ namespace DH.Devices.PLC
/// </summary>
public bool connected = false;
public string PLCName;
/// <summary>
/// 类型
/// </summary>

View File

@ -12,6 +12,10 @@
<OutputType>WinExe</OutputType>
</PropertyGroup>

View File

@ -1005,7 +1005,7 @@ namespace DHSoftware
Gain = 60,
Exposure = 10,
RotateImage = 0,
isEnabled = false,
IsEnabled = false,
};
CameraBase cam2 = new CameraBase
{
@ -1015,7 +1015,7 @@ namespace DHSoftware
Gain = 60,
Exposure = 10,
RotateImage = 0,
isEnabled = false,
IsEnabled = false,
};
listCamBase.Add(cam1);
listCamBase.Add(cam2);

View File

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AntdUI;
namespace DHSoftware.Utils
{
public static class AdaptiveHelper
{
#region
public static void setTag(Control cons)
{
foreach (Control con in cons.Controls)
{
con.Tag = con.Width + ";" + con.Height + ";" + con.Left + ";" + con.Top + ";" + con.Font.Size;
if (con.Controls.Count > 0) setTag(con);
}
}
public static void setControls(float newx, float newy, Control cons)
{
//遍历窗体中的控件,重新设置控件的值
foreach (Control con in cons.Controls)
//获取控件的Tag属性值并分割后存储字符串数组
if (con.Tag != null)
{
var mytag = con.Tag.ToString().Split(';');
//根据窗体缩放的比例确定控件的值
con.Width = Convert.ToInt32(Convert.ToSingle(mytag[0]) * newx); //宽度
con.Height = Convert.ToInt32(Convert.ToSingle(mytag[1]) * newy); //高度
con.Left = Convert.ToInt32(Convert.ToSingle(mytag[2]) * newx); //左边距
con.Top = Convert.ToInt32(Convert.ToSingle(mytag[3]) * newy); //顶边距
var currentSize = Convert.ToSingle(mytag[4]) * newy; //字体大小
if (currentSize > 0) con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
con.Focus();
if (con.Controls.Count > 0) setControls(newx, newy, con);
}
}
#endregion
}
}

View File

@ -0,0 +1,155 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Windows.Forms;
using DH.Commons.Enums;
using DH.Devices.Devices;
using DH.Devices.PLC;
namespace DH.Commons.Helper
{
// 配置数据模型
public class AppConfig
{
public List<CameraBase> Cameras { get; set; } = new List<CameraBase>();
public List<PLCBase> PLCs { get; set; } = new List<PLCBase>();
public List<DetectionConfig> Detections { get; set; } = new List<DetectionConfig>();
}
// 配置管理工具类
public static class ConfigManager
{
private static readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
IgnoreNullValues = true
};
// 默认路径配置
private static readonly string DefaultConfigDir = Path.Combine(
Application.StartupPath,
"configs"
);
public static readonly string DefaultConfigPath = Path.Combine(
DefaultConfigDir,
"appsettings.json"
);
/// <summary>
/// 保存配置文件(自动处理目录和备份)
/// </summary>
/// <param name="config">配置对象</param>
/// <param name="filePath">可选文件路径</param>
public static void SaveConfig(AppConfig config, string filePath = null)
{
try
{
// 使用默认路径如果未指定
filePath ??= DefaultConfigPath;
// 确保配置目录存在
var configDir = Path.GetDirectoryName(filePath);
if (!Directory.Exists(configDir))
{
Directory.CreateDirectory(configDir);
}
// 备份已有配置
if (File.Exists(filePath))
{
BackupConfig(filePath);
}
// 序列化并保存
string json = JsonSerializer.Serialize(config, _jsonOptions);
File.WriteAllText(filePath, json);
}
catch (Exception ex)
{
throw new InvalidOperationException("配置保存失败", ex);
}
}
/// <summary>
/// 加载配置文件
/// </summary>
/// <param name="filePath">可选文件路径</param>
/// <returns>配置对象</returns>
public static AppConfig LoadConfig(string filePath = null)
{
try
{
filePath ??= DefaultConfigPath;
if (!File.Exists(filePath))
{
return new AppConfig(); // 返回空配置而不是null
}
string json = File.ReadAllText(filePath);
return JsonSerializer.Deserialize<AppConfig>(json, _jsonOptions);
}
catch (Exception ex)
{
throw new InvalidOperationException("配置加载失败", ex);
}
}
/// <summary>
/// 创建带时间戳的备份文件
/// </summary>
private static void BackupConfig(string originalPath)
{
try
{
// 创建备份目录
var backupDir = Path.Combine(
Path.GetDirectoryName(originalPath),
"backups"
);
if (!Directory.Exists(backupDir))
{
Directory.CreateDirectory(backupDir);
}
// 生成带时间戳的文件名
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
string fileName = $"{Path.GetFileNameWithoutExtension(originalPath)}_" +
$"{timestamp}" +
$"{Path.GetExtension(originalPath)}";
// 执行备份
File.Copy(
originalPath,
Path.Combine(backupDir, fileName),
overwrite: true
);
}
catch (Exception ex)
{
throw new InvalidOperationException("配置备份失败", ex);
}
}
/// <summary>
/// 创建新的配置对象
/// </summary>
public static AppConfig CreateConfig(
List<CameraBase> cameras = null,
List<PLCBase> plcs = null,
List<DetectionConfig> detections = null)
{
return new AppConfig
{
Cameras = cameras ?? new List<CameraBase>(),
PLCs = plcs ?? new List<PLCBase>(),
Detections = detections ?? new List<DetectionConfig>()
};
}
}
}

View File

@ -0,0 +1,162 @@
namespace DHSoftware.Views
{
partial class AddCameraControl
{
/// <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()
{
panel1 = new AntdUI.Panel();
input_name = new AntdUI.Input();
label3 = new AntdUI.Label();
divider1 = new AntdUI.Divider();
stackPanel1 = new AntdUI.StackPanel();
button_cancel = new AntdUI.Button();
button_ok = new AntdUI.Button();
divider2 = new AntdUI.Divider();
label1 = new AntdUI.Label();
panel1.SuspendLayout();
stackPanel1.SuspendLayout();
SuspendLayout();
//
// panel1
//
panel1.Controls.Add(input_name);
panel1.Controls.Add(label3);
panel1.Controls.Add(divider1);
panel1.Controls.Add(stackPanel1);
panel1.Controls.Add(divider2);
panel1.Controls.Add(label1);
panel1.Dock = DockStyle.Fill;
panel1.Location = new Point(0, 0);
panel1.Name = "panel1";
panel1.Padding = new Padding(12);
panel1.Shadow = 6;
panel1.Size = new Size(500, 194);
panel1.TabIndex = 0;
panel1.Text = "panel1";
//
// input_name
//
input_name.Dock = DockStyle.Top;
input_name.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
input_name.Location = new Point(18, 134);
input_name.Name = "input_name";
input_name.Radius = 3;
input_name.Size = new Size(464, 38);
input_name.TabIndex = 22;
//
// label3
//
label3.Dock = DockStyle.Top;
label3.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
label3.Location = new Point(18, 110);
label3.Name = "label3";
label3.Size = new Size(464, 24);
label3.TabIndex = 21;
label3.Text = "相机名称";
//
// divider1
//
divider1.Dock = DockStyle.Top;
divider1.Location = new Point(18, 98);
divider1.Name = "divider1";
divider1.Size = new Size(464, 12);
divider1.TabIndex = 20;
//
// stackPanel1
//
stackPanel1.Controls.Add(button_cancel);
stackPanel1.Controls.Add(button_ok);
stackPanel1.Dock = DockStyle.Top;
stackPanel1.Location = new Point(18, 54);
stackPanel1.Name = "stackPanel1";
stackPanel1.RightToLeft = RightToLeft.No;
stackPanel1.Size = new Size(464, 44);
stackPanel1.TabIndex = 19;
stackPanel1.Text = "stackPanel1";
//
// button_cancel
//
button_cancel.BorderWidth = 1F;
button_cancel.Font = new Font("Microsoft YaHei UI", 9F);
button_cancel.Ghost = true;
button_cancel.Location = new Point(84, 3);
button_cancel.Name = "button_cancel";
button_cancel.Size = new Size(75, 38);
button_cancel.TabIndex = 1;
button_cancel.Text = "取消";
//
// button_ok
//
button_ok.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
button_ok.Location = new Point(3, 3);
button_ok.Name = "button_ok";
button_ok.Size = new Size(75, 38);
button_ok.TabIndex = 0;
button_ok.Text = "确定";
button_ok.Type = AntdUI.TTypeMini.Primary;
//
// divider2
//
divider2.Dock = DockStyle.Top;
divider2.Location = new Point(18, 42);
divider2.Name = "divider2";
divider2.Size = new Size(464, 12);
divider2.TabIndex = 18;
//
// label1
//
label1.Dock = DockStyle.Top;
label1.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
label1.Location = new Point(18, 18);
label1.Name = "label1";
label1.Size = new Size(464, 24);
label1.TabIndex = 17;
label1.Text = "新增相机操作";
//
// AddCameraControl
//
Controls.Add(panel1);
Name = "AddCameraControl";
Size = new Size(500, 194);
panel1.ResumeLayout(false);
stackPanel1.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private AntdUI.Panel panel1;
private AntdUI.Label label1;
private AntdUI.Input input_name;
private AntdUI.Label label3;
private AntdUI.Divider divider1;
private AntdUI.StackPanel stackPanel1;
private AntdUI.Button button_cancel;
private AntdUI.Button button_ok;
private AntdUI.Divider divider2;
}
}

View File

@ -0,0 +1,47 @@

namespace DHSoftware.Views
{
public partial class AddCameraControl : UserControl
{
private AntdUI.Window window;
public bool submit;
public string CubicleName;
public AddCameraControl(AntdUI.Window _window)
{
this.window = _window;
InitializeComponent();
// 绑定事件
BindEventHandler();
}
private void BindEventHandler()
{
button_ok.Click += Button_ok_Click;
button_cancel.Click += Button_cancel_Click;
}
private void Button_cancel_Click(object sender, EventArgs e)
{
submit = false;
this.Dispose();
}
private void Button_ok_Click(object sender, EventArgs e)
{
input_name.Status = AntdUI.TType.None;
//检查输入内容
if (String.IsNullOrEmpty(input_name.Text))
{
input_name.Status = AntdUI.TType.Error;
AntdUI.Message.warn(window, "相机名称不能为空!", autoClose: 3);
return;
}
CubicleName=input_name.Text;
submit = true;
this.Dispose();
}
}
}

View File

@ -1,81 +0,0 @@
namespace DHSoftware.Views
{
partial class AddCameraWindow
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
btnOK = new AntdUI.Button();
btnCancel = new AntdUI.Button();
stName = new AntdUI.Select();
SuspendLayout();
//
// btnOK
//
btnOK.Location = new Point(170, 136);
btnOK.Name = "btnOK";
btnOK.Size = new Size(75, 40);
btnOK.TabIndex = 1;
btnOK.Text = "确定";
btnOK.Click += btnOK_Click;
//
// btnCancel
//
btnCancel.Location = new Point(259, 136);
btnCancel.Name = "btnCancel";
btnCancel.Size = new Size(75, 40);
btnCancel.TabIndex = 2;
btnCancel.Text = "取消";
btnCancel.Click += btnCancel_Click;
//
// stName
//
stName.Location = new Point(39, 46);
stName.Name = "stName";
stName.PlaceholderText = "请选择关联相机";
stName.Size = new Size(281, 50);
stName.TabIndex = 3;
//
// AddCameraWindow
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(369, 188);
Controls.Add(stName);
Controls.Add(btnCancel);
Controls.Add(btnOK);
Name = "AddCameraWindow";
StartPosition = FormStartPosition.CenterParent;
Text = "AddCubicleWindow";
ResumeLayout(false);
}
#endregion
private AntdUI.Button btnOK;
private AntdUI.Button btnCancel;
private AntdUI.Select stName;
}
}

View File

@ -1,61 +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;
using System.Xml.Linq;
using AntdUI;
namespace DHSoftware.Views
{
public partial class AddCameraWindow : Window
{
public AddCameraWindow()
{
InitializeComponent();
btnOK.DialogResult = DialogResult.OK;
btnCancel.DialogResult = DialogResult.Cancel;
this.AcceptButton = btnOK;
this.CancelButton = btnCancel;
stName.Items.Clear();
for(int i = 1; i <= 8; i++)
{
stName.Items.Add($"Cam{i}");
}
}
public string CubicleName { get; private set; }
private void btnOK_Click(object sender, EventArgs e)
{
if (ValidateInput())
{
this.DialogResult = DialogResult.OK;
this.Close();
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
private bool ValidateInput()
{
if (string.IsNullOrWhiteSpace(stName.Text))
{
MessageBox.Show("请选择关联相机", "输入错误",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return false;
}
CubicleName = stName.Text.Trim();
return true;
}
}
}

View File

@ -0,0 +1,162 @@
namespace DHSoftware.Views
{
partial class AddCubicleControl
{
/// <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()
{
panel1 = new AntdUI.Panel();
input_name = new AntdUI.Input();
label3 = new AntdUI.Label();
divider1 = new AntdUI.Divider();
stackPanel1 = new AntdUI.StackPanel();
button_cancel = new AntdUI.Button();
button_ok = new AntdUI.Button();
divider2 = new AntdUI.Divider();
label1 = new AntdUI.Label();
panel1.SuspendLayout();
stackPanel1.SuspendLayout();
SuspendLayout();
//
// panel1
//
panel1.Controls.Add(input_name);
panel1.Controls.Add(label3);
panel1.Controls.Add(divider1);
panel1.Controls.Add(stackPanel1);
panel1.Controls.Add(divider2);
panel1.Controls.Add(label1);
panel1.Dock = DockStyle.Fill;
panel1.Location = new Point(0, 0);
panel1.Name = "panel1";
panel1.Padding = new Padding(12);
panel1.Shadow = 6;
panel1.Size = new Size(500, 194);
panel1.TabIndex = 0;
panel1.Text = "panel1";
//
// input_name
//
input_name.Dock = DockStyle.Top;
input_name.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
input_name.Location = new Point(18, 134);
input_name.Name = "input_name";
input_name.Radius = 3;
input_name.Size = new Size(464, 38);
input_name.TabIndex = 22;
//
// label3
//
label3.Dock = DockStyle.Top;
label3.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
label3.Location = new Point(18, 110);
label3.Name = "label3";
label3.Size = new Size(464, 24);
label3.TabIndex = 21;
label3.Text = "工位名称";
//
// divider1
//
divider1.Dock = DockStyle.Top;
divider1.Location = new Point(18, 98);
divider1.Name = "divider1";
divider1.Size = new Size(464, 12);
divider1.TabIndex = 20;
//
// stackPanel1
//
stackPanel1.Controls.Add(button_cancel);
stackPanel1.Controls.Add(button_ok);
stackPanel1.Dock = DockStyle.Top;
stackPanel1.Location = new Point(18, 54);
stackPanel1.Name = "stackPanel1";
stackPanel1.RightToLeft = RightToLeft.No;
stackPanel1.Size = new Size(464, 44);
stackPanel1.TabIndex = 19;
stackPanel1.Text = "stackPanel1";
//
// button_cancel
//
button_cancel.BorderWidth = 1F;
button_cancel.Font = new Font("Microsoft YaHei UI", 9F);
button_cancel.Ghost = true;
button_cancel.Location = new Point(84, 3);
button_cancel.Name = "button_cancel";
button_cancel.Size = new Size(75, 38);
button_cancel.TabIndex = 1;
button_cancel.Text = "取消";
//
// button_ok
//
button_ok.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
button_ok.Location = new Point(3, 3);
button_ok.Name = "button_ok";
button_ok.Size = new Size(75, 38);
button_ok.TabIndex = 0;
button_ok.Text = "确定";
button_ok.Type = AntdUI.TTypeMini.Primary;
//
// divider2
//
divider2.Dock = DockStyle.Top;
divider2.Location = new Point(18, 42);
divider2.Name = "divider2";
divider2.Size = new Size(464, 12);
divider2.TabIndex = 18;
//
// label1
//
label1.Dock = DockStyle.Top;
label1.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
label1.Location = new Point(18, 18);
label1.Name = "label1";
label1.Size = new Size(464, 24);
label1.TabIndex = 17;
label1.Text = "新增工位操作";
//
// AddCubicleControl
//
Controls.Add(panel1);
Name = "AddCubicleControl";
Size = new Size(500, 194);
panel1.ResumeLayout(false);
stackPanel1.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private AntdUI.Panel panel1;
private AntdUI.Label label1;
private AntdUI.Input input_name;
private AntdUI.Label label3;
private AntdUI.Divider divider1;
private AntdUI.StackPanel stackPanel1;
private AntdUI.Button button_cancel;
private AntdUI.Button button_ok;
private AntdUI.Divider divider2;
}
}

View File

@ -0,0 +1,47 @@

namespace DHSoftware.Views
{
public partial class AddCubicleControl : UserControl
{
private AntdUI.Window window;
public bool submit;
public string CubicleName;
public AddCubicleControl(AntdUI.Window _window)
{
this.window = _window;
InitializeComponent();
// 绑定事件
BindEventHandler();
}
private void BindEventHandler()
{
button_ok.Click += Button_ok_Click;
button_cancel.Click += Button_cancel_Click;
}
private void Button_cancel_Click(object sender, EventArgs e)
{
submit = false;
this.Dispose();
}
private void Button_ok_Click(object sender, EventArgs e)
{
input_name.Status = AntdUI.TType.None;
//检查输入内容
if (String.IsNullOrEmpty(input_name.Text))
{
input_name.Status = AntdUI.TType.Error;
AntdUI.Message.warn(window, "工位名称不能为空!", autoClose: 3);
return;
}
CubicleName=input_name.Text;
submit = true;
this.Dispose();
}
}
}

View File

@ -1,82 +0,0 @@
namespace DHSoftware.Views
{
partial class AddCubicleWindow
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
txtName = new AntdUI.Input();
btnOK = new AntdUI.Button();
btnCancel = new AntdUI.Button();
SuspendLayout();
//
// txtName
//
txtName.Location = new Point(35, 47);
txtName.Name = "txtName";
txtName.PlaceholderText = "请输入新增工位名称";
txtName.Size = new Size(299, 48);
txtName.TabIndex = 0;
//
// btnOK
//
btnOK.Location = new Point(170, 136);
btnOK.Name = "btnOK";
btnOK.Size = new Size(75, 40);
btnOK.TabIndex = 1;
btnOK.Text = "确定";
btnOK.Click += btnOK_Click;
//
// btnCancel
//
btnCancel.Location = new Point(259, 136);
btnCancel.Name = "btnCancel";
btnCancel.Size = new Size(75, 40);
btnCancel.TabIndex = 2;
btnCancel.Text = "取消";
btnCancel.Click += btnCancel_Click;
//
// AddCubicleWindow
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(369, 188);
Controls.Add(btnCancel);
Controls.Add(btnOK);
Controls.Add(txtName);
Name = "AddCubicleWindow";
StartPosition = FormStartPosition.CenterParent;
Text = "AddCubicleWindow";
ResumeLayout(false);
}
#endregion
private AntdUI.Input txtName;
private AntdUI.Button btnOK;
private AntdUI.Button btnCancel;
}
}

View File

@ -1,55 +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;
using System.Xml.Linq;
using AntdUI;
namespace DHSoftware.Views
{
public partial class AddCubicleWindow : Window
{
public AddCubicleWindow()
{
InitializeComponent();
btnOK.DialogResult = DialogResult.OK;
btnCancel.DialogResult = DialogResult.Cancel;
this.AcceptButton = btnOK;
this.CancelButton = btnCancel;
}
public string CubicleName { get; private set; }
private void btnOK_Click(object sender, EventArgs e)
{
if (ValidateInput())
{
this.DialogResult = DialogResult.OK;
this.Close();
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
private bool ValidateInput()
{
if (string.IsNullOrWhiteSpace(txtName.Text))
{
MessageBox.Show("请输入有效的名称", "输入错误",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
txtName.Focus();
return false;
}
CubicleName = txtName.Text.Trim();
return true;
}
}
}

View File

@ -0,0 +1,197 @@
namespace DHSoftware.Views
{
partial class AddMotionControl
{
/// <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()
{
panel1 = new AntdUI.Panel();
input_name = new AntdUI.Input();
label3 = new AntdUI.Label();
divider1 = new AntdUI.Divider();
stackPanel1 = new AntdUI.StackPanel();
button_cancel = new AntdUI.Button();
button_ok = new AntdUI.Button();
divider2 = new AntdUI.Divider();
label1 = new AntdUI.Label();
label2 = new AntdUI.Label();
divider3 = new AntdUI.Divider();
select_type = new AntdUI.Select();
panel1.SuspendLayout();
stackPanel1.SuspendLayout();
SuspendLayout();
//
// panel1
//
panel1.Controls.Add(select_type);
panel1.Controls.Add(label2);
panel1.Controls.Add(divider3);
panel1.Controls.Add(input_name);
panel1.Controls.Add(label3);
panel1.Controls.Add(divider1);
panel1.Controls.Add(stackPanel1);
panel1.Controls.Add(divider2);
panel1.Controls.Add(label1);
panel1.Dock = DockStyle.Fill;
panel1.Location = new Point(0, 0);
panel1.Name = "panel1";
panel1.Padding = new Padding(12);
panel1.Shadow = 6;
panel1.Size = new Size(500, 260);
panel1.TabIndex = 0;
panel1.Text = "panel1";
//
// input_name
//
input_name.Dock = DockStyle.Top;
input_name.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
input_name.Location = new Point(18, 134);
input_name.Name = "input_name";
input_name.Radius = 3;
input_name.Size = new Size(464, 38);
input_name.TabIndex = 22;
//
// label3
//
label3.Dock = DockStyle.Top;
label3.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
label3.Location = new Point(18, 110);
label3.Name = "label3";
label3.Size = new Size(464, 24);
label3.TabIndex = 21;
label3.Text = "运动控制名称";
//
// divider1
//
divider1.Dock = DockStyle.Top;
divider1.Location = new Point(18, 98);
divider1.Name = "divider1";
divider1.Size = new Size(464, 12);
divider1.TabIndex = 20;
//
// stackPanel1
//
stackPanel1.Controls.Add(button_cancel);
stackPanel1.Controls.Add(button_ok);
stackPanel1.Dock = DockStyle.Top;
stackPanel1.Location = new Point(18, 54);
stackPanel1.Name = "stackPanel1";
stackPanel1.RightToLeft = RightToLeft.No;
stackPanel1.Size = new Size(464, 44);
stackPanel1.TabIndex = 19;
stackPanel1.Text = "stackPanel1";
//
// button_cancel
//
button_cancel.BorderWidth = 1F;
button_cancel.Font = new Font("Microsoft YaHei UI", 9F);
button_cancel.Ghost = true;
button_cancel.Location = new Point(84, 3);
button_cancel.Name = "button_cancel";
button_cancel.Size = new Size(75, 38);
button_cancel.TabIndex = 1;
button_cancel.Text = "取消";
//
// button_ok
//
button_ok.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
button_ok.Location = new Point(3, 3);
button_ok.Name = "button_ok";
button_ok.Size = new Size(75, 38);
button_ok.TabIndex = 0;
button_ok.Text = "确定";
button_ok.Type = AntdUI.TTypeMini.Primary;
//
// divider2
//
divider2.Dock = DockStyle.Top;
divider2.Location = new Point(18, 42);
divider2.Name = "divider2";
divider2.Size = new Size(464, 12);
divider2.TabIndex = 18;
//
// label1
//
label1.Dock = DockStyle.Top;
label1.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
label1.Location = new Point(18, 18);
label1.Name = "label1";
label1.Size = new Size(464, 24);
label1.TabIndex = 17;
label1.Text = "新增运动控制操作";
//
// label2
//
label2.Dock = DockStyle.Top;
label2.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
label2.Location = new Point(18, 184);
label2.Name = "label2";
label2.Size = new Size(464, 24);
label2.TabIndex = 24;
label2.Text = "运动控制类型";
//
// divider3
//
divider3.Dock = DockStyle.Top;
divider3.Location = new Point(18, 172);
divider3.Name = "divider3";
divider3.Size = new Size(464, 12);
divider3.TabIndex = 23;
//
// select_type
//
select_type.Dock = DockStyle.Top;
select_type.Location = new Point(18, 208);
select_type.Name = "select_type";
select_type.Size = new Size(464, 37);
select_type.TabIndex = 25;
//
// AddMotionControl
//
Controls.Add(panel1);
Name = "AddMotionControl";
Size = new Size(500, 260);
panel1.ResumeLayout(false);
stackPanel1.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private AntdUI.Panel panel1;
private AntdUI.Label label1;
private AntdUI.Input input_name;
private AntdUI.Label label3;
private AntdUI.Divider divider1;
private AntdUI.StackPanel stackPanel1;
private AntdUI.Button button_cancel;
private AntdUI.Button button_ok;
private AntdUI.Divider divider2;
private AntdUI.Select select_type;
private AntdUI.Label label2;
private AntdUI.Divider divider3;
}
}

View File

@ -0,0 +1,49 @@

namespace DHSoftware.Views
{
public partial class AddMotionControl : UserControl
{
private AntdUI.Window window;
public bool submit;
public string MotionName;
public string MotionType;
public AddMotionControl(AntdUI.Window _window)
{
this.window = _window;
InitializeComponent();
// 绑定事件
BindEventHandler();
}
private void BindEventHandler()
{
button_ok.Click += Button_ok_Click;
button_cancel.Click += Button_cancel_Click;
}
private void Button_cancel_Click(object sender, EventArgs e)
{
submit = false;
this.Dispose();
}
private void Button_ok_Click(object sender, EventArgs e)
{
input_name.Status = AntdUI.TType.None;
//检查输入内容
if (String.IsNullOrEmpty(input_name.Text))
{
input_name.Status = AntdUI.TType.Error;
AntdUI.Message.warn(window, "运动控制名称不能为空!", autoClose: 3);
return;
}
MotionName = input_name.Text;
MotionType = select_type.Text;
submit = true;
this.Dispose();
}
}
}

View File

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

313
DHSoftware/Views/CameraControl.Designer.cs generated Normal file
View File

@ -0,0 +1,313 @@
namespace DHSoftware.Views
{
partial class CameraControl
{
/// <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()
{
swhEnable = new AntdUI.Switch();
label18 = new AntdUI.Label();
label1 = new AntdUI.Label();
label2 = new AntdUI.Label();
label3 = new AntdUI.Label();
iptExposure = new AntdUI.InputNumber();
iptGain = new AntdUI.InputNumber();
iptRevolve = new AntdUI.InputNumber();
label4 = new AntdUI.Label();
sltAcquisitionMode = new AntdUI.Select();
label5 = new AntdUI.Label();
sltTriggerMode = new AntdUI.Select();
label7 = new AntdUI.Label();
iptROIW = new AntdUI.InputNumber();
iptROIY = new AntdUI.InputNumber();
iptROIX = new AntdUI.InputNumber();
iptROIH = new AntdUI.InputNumber();
pictureBox1 = new PictureBox();
btnSizeAdd = new AntdUI.Button();
button1 = new AntdUI.Button();
button2 = new AntdUI.Button();
button3 = new AntdUI.Button();
((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit();
SuspendLayout();
//
// swhEnable
//
swhEnable.CheckedText = "启用";
swhEnable.Location = new Point(84, 13);
swhEnable.Name = "swhEnable";
swhEnable.Size = new Size(93, 33);
swhEnable.TabIndex = 13;
swhEnable.UnCheckedText = "关闭";
//
// label18
//
label18.Location = new Point(28, 23);
label18.Name = "label18";
label18.Size = new Size(59, 23);
label18.TabIndex = 12;
label18.Text = "状 态";
//
// label1
//
label1.Location = new Point(28, 71);
label1.Name = "label1";
label1.Size = new Size(59, 23);
label1.TabIndex = 14;
label1.Text = "曝 光";
//
// label2
//
label2.Location = new Point(28, 113);
label2.Name = "label2";
label2.Size = new Size(59, 23);
label2.TabIndex = 15;
label2.Text = "增 益";
//
// label3
//
label3.Location = new Point(28, 155);
label3.Name = "label3";
label3.Size = new Size(59, 23);
label3.TabIndex = 16;
label3.Text = "旋转角度";
//
// iptExposure
//
iptExposure.Location = new Point(84, 57);
iptExposure.Name = "iptExposure";
iptExposure.Size = new Size(93, 37);
iptExposure.TabIndex = 17;
iptExposure.Tag = "";
iptExposure.Text = "0";
//
// iptGain
//
iptGain.Location = new Point(84, 100);
iptGain.Name = "iptGain";
iptGain.Size = new Size(93, 37);
iptGain.TabIndex = 18;
iptGain.Text = "0";
//
// iptRevolve
//
iptRevolve.Location = new Point(84, 143);
iptRevolve.Name = "iptRevolve";
iptRevolve.Size = new Size(93, 37);
iptRevolve.TabIndex = 19;
iptRevolve.Text = "0";
//
// label4
//
label4.Location = new Point(28, 199);
label4.Name = "label4";
label4.Size = new Size(59, 23);
label4.TabIndex = 20;
label4.Text = "采图模式";
//
// sltAcquisitionMode
//
sltAcquisitionMode.List = true;
sltAcquisitionMode.Location = new Point(84, 186);
sltAcquisitionMode.Name = "sltAcquisitionMode";
sltAcquisitionMode.Size = new Size(93, 36);
sltAcquisitionMode.TabIndex = 21;
//
// label5
//
label5.Location = new Point(28, 244);
label5.Name = "label5";
label5.Size = new Size(59, 23);
label5.TabIndex = 22;
label5.Text = "触发模式";
//
// sltTriggerMode
//
sltTriggerMode.List = true;
sltTriggerMode.Location = new Point(84, 231);
sltTriggerMode.Name = "sltTriggerMode";
sltTriggerMode.Size = new Size(93, 36);
sltTriggerMode.TabIndex = 26;
//
// label7
//
label7.Location = new Point(28, 354);
label7.Name = "label7";
label7.Size = new Size(59, 23);
label7.TabIndex = 28;
label7.Text = "ROI范围";
//
// iptROIW
//
iptROIW.Location = new Point(84, 371);
iptROIW.Name = "iptROIW";
iptROIW.Size = new Size(93, 37);
iptROIW.TabIndex = 31;
iptROIW.Text = "0";
//
// iptROIY
//
iptROIY.Location = new Point(84, 328);
iptROIY.Name = "iptROIY";
iptROIY.Size = new Size(93, 37);
iptROIY.TabIndex = 30;
iptROIY.Text = "0";
//
// iptROIX
//
iptROIX.Location = new Point(84, 285);
iptROIX.Name = "iptROIX";
iptROIX.Size = new Size(93, 37);
iptROIX.TabIndex = 29;
iptROIX.Tag = "";
iptROIX.Text = "0";
//
// iptROIH
//
iptROIH.Location = new Point(84, 414);
iptROIH.Name = "iptROIH";
iptROIH.Size = new Size(93, 37);
iptROIH.TabIndex = 32;
iptROIH.Text = "0";
//
// pictureBox1
//
pictureBox1.BorderStyle = BorderStyle.FixedSingle;
pictureBox1.Location = new Point(219, 23);
pictureBox1.Name = "pictureBox1";
pictureBox1.Size = new Size(659, 429);
pictureBox1.TabIndex = 33;
pictureBox1.TabStop = false;
//
// btnSizeAdd
//
btnSizeAdd.BorderWidth = 2F;
btnSizeAdd.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
btnSizeAdd.Ghost = true;
btnSizeAdd.IconRatio = 0F;
btnSizeAdd.IconSvg = "";
btnSizeAdd.Location = new Point(280, 458);
btnSizeAdd.Name = "btnSizeAdd";
btnSizeAdd.Size = new Size(80, 38);
btnSizeAdd.TabIndex = 34;
btnSizeAdd.Text = "连接相机";
//
// button1
//
button1.BorderWidth = 2F;
button1.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
button1.Ghost = true;
button1.IconRatio = 0F;
button1.IconSvg = "";
button1.Location = new Point(438, 458);
button1.Name = "button1";
button1.Size = new Size(80, 38);
button1.TabIndex = 35;
button1.Text = "断开相机";
//
// button2
//
button2.BorderWidth = 2F;
button2.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
button2.Ghost = true;
button2.IconRatio = 0F;
button2.IconSvg = "";
button2.Location = new Point(593, 458);
button2.Name = "button2";
button2.Size = new Size(80, 38);
button2.TabIndex = 36;
button2.Text = "单次触发";
//
// button3
//
button3.BorderWidth = 2F;
button3.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
button3.Ghost = true;
button3.IconRatio = 0F;
button3.IconSvg = "";
button3.Location = new Point(741, 458);
button3.Name = "button3";
button3.Size = new Size(80, 38);
button3.TabIndex = 37;
button3.Text = "连续触发";
//
// CameraControl
//
AutoScaleDimensions = new SizeF(7F, 17F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(button3);
Controls.Add(button2);
Controls.Add(button1);
Controls.Add(btnSizeAdd);
Controls.Add(pictureBox1);
Controls.Add(iptROIH);
Controls.Add(iptROIW);
Controls.Add(iptROIY);
Controls.Add(iptROIX);
Controls.Add(label7);
Controls.Add(sltTriggerMode);
Controls.Add(label5);
Controls.Add(sltAcquisitionMode);
Controls.Add(label4);
Controls.Add(iptRevolve);
Controls.Add(iptGain);
Controls.Add(iptExposure);
Controls.Add(label3);
Controls.Add(label2);
Controls.Add(label1);
Controls.Add(swhEnable);
Controls.Add(label18);
Name = "CameraControl";
Size = new Size(909, 505);
((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit();
ResumeLayout(false);
}
#endregion
private AntdUI.Switch swhEnable;
private AntdUI.Label label18;
private AntdUI.Label label1;
private AntdUI.Label label2;
private AntdUI.Label label3;
private AntdUI.InputNumber iptExposure;
private AntdUI.InputNumber iptGain;
private AntdUI.InputNumber iptRevolve;
private AntdUI.Label label4;
private AntdUI.Select sltAcquisitionMode;
private AntdUI.Label label5;
private AntdUI.Select sltTriggerMode;
private AntdUI.Label label7;
private AntdUI.InputNumber iptROIW;
private AntdUI.InputNumber iptROIY;
private AntdUI.InputNumber iptROIX;
private AntdUI.InputNumber iptROIH;
private PictureBox pictureBox1;
private AntdUI.Button btnSizeAdd;
private AntdUI.Button button1;
private AntdUI.Button button2;
private AntdUI.Button button3;
}
}

View File

@ -0,0 +1,97 @@
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;
using AntdUI;
using DH.Commons.Enums;
using DH.Devices.Devices;
namespace DHSoftware.Views
{
public partial class CameraControl : UserControl
{
Window window;
CameraBase CameraBase;
public CameraControl(Window _window,CameraBase cameraBase)
{
window= _window;
CameraBase = cameraBase;
InitializeComponent();
InitData();
BindData();
}
private void SltAcquisitionMode_SelectedIndexChanged(object sender, IntEventArgs e)
{
switch (e.Value)
{
case (int)CameraAcquisitionMode.:
sltTriggerMode.Enabled = false;
break;
case (int)CameraAcquisitionMode.:
sltTriggerMode.Enabled = true;
break;
default:
break;
}
}
private void BindData()
{
// 启用状态绑定
swhEnable.DataBindings.Add(nameof(swhEnable.Checked), CameraBase, nameof(CameraBase.IsEnabled),
true, DataSourceUpdateMode.OnPropertyChanged);
// 曝光时间绑定假设iptExposure是NumericUpDown
iptExposure.DataBindings.Add(nameof(iptExposure.Value), CameraBase, nameof(CameraBase.Exposure),
true, DataSourceUpdateMode.OnPropertyChanged, 0M, "N2");
// 增益绑定
iptGain.DataBindings.Add(nameof(iptGain.Value), CameraBase, nameof(CameraBase.Gain),
true, DataSourceUpdateMode.OnPropertyChanged, 0M, "N2");
// 旋转角度绑定
iptRevolve.DataBindings.Add(nameof(iptRevolve.Value), CameraBase, nameof(CameraBase.RotateImage),
true, DataSourceUpdateMode.OnPropertyChanged, 0M, "N2");
// ROI坐标绑定
iptROIX.DataBindings.Add(nameof(iptROIX.Value), CameraBase, nameof(CameraBase.ROIX));
iptROIY.DataBindings.Add(nameof(iptROIY.Value), CameraBase, nameof(CameraBase.ROIY));
iptROIW.DataBindings.Add(nameof(iptROIW.Value), CameraBase, nameof(CameraBase.ROIW));
iptROIH.DataBindings.Add(nameof(iptROIH.Value), CameraBase, nameof(CameraBase.ROIH));
// 采集模式下拉框处理
sltAcquisitionMode.SelectedIndexChanged += (s, e) =>
{
CameraBase.IsContinueMode = sltAcquisitionMode.SelectedIndex == 0;
};
// 触发模式下拉框处理
sltTriggerMode.SelectedIndexChanged += (s, e) =>
{
CameraBase.IsHardwareTrigger = sltTriggerMode.SelectedIndex == 1;
};
}
private void InitData()
{
// 初始化下拉框选项
sltAcquisitionMode.Items.AddRange(new[] { "连续模式", "触发模式" });
sltTriggerMode.Items.AddRange(new[] { "软触发", "硬触发" });
// 设置初始选择
sltAcquisitionMode.SelectedIndex = CameraBase.IsContinueMode ? 0 : 1;
sltTriggerMode.SelectedIndex = CameraBase.IsHardwareTrigger ? 1 : 0;
}
}
}

View File

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

View File

@ -57,29 +57,7 @@ namespace DHSoftware.Views
IconSvg = "VideoCameraAddOutlined"
}
};
AntdUI.ContextMenuStrip.open(menu1, it =>
{
if (it.Text == "关联相机")
{
using (var dlg = new AddCameraWindow())
{
if (dlg.ShowDialog() == DialogResult.OK)
{
var newItem = new MenuItem(dlg.CubicleName);
newItem.IconSvg = "VideoCameraOutlined";
//// 防止重复添加
//if (!menu1.Items.Cast<MenuItem>().Any(m => m.Text == newItem.Text))
//{
clickedItem.Sub.Add(newItem);
//}
//else
//{
// AntdUI.Notification.warn(this, "新增失败", $"{dlg.CubicleName}已存在!", autoClose: 3, align: TAlignFrom.TR);
//}
}
}
}
}, menulist);
}
}
}
@ -106,23 +84,28 @@ namespace DHSoftware.Views
private void btnAdd_Click(object sender, EventArgs e)
{
using (var dlg = new AddCubicleWindow())
var form = new AddCubicleControl(this) { Size = new Size(400, 300) };
AntdUI.Modal.open(new AntdUI.Modal.Config(this, "", form, TType.None)
{
if (dlg.ShowDialog() == DialogResult.OK)
BtnHeight = 0,
});
if (form.submit)
{
var newItem = new MenuItem(form.CubicleName);
newItem.IconSvg = "AppstoreOutlined";
// 防止重复添加
if (!menu1.Items.Cast<MenuItem>().Any(m => m.Text == newItem.Text))
{
var newItem = new MenuItem(dlg.CubicleName);
newItem.IconSvg = "AppstoreOutlined";
// 防止重复添加
if (!menu1.Items.Cast<MenuItem>().Any(m => m.Text == newItem.Text))
{
menu1.Items.Add(newItem);
}
else
{
AntdUI.Notification.warn(this, "新增工位失败", $"{dlg.CubicleName}已存在!", autoClose: 3, align: TAlignFrom.TR);
}
menu1.Items.Add(newItem);
}
else
{
AntdUI.Notification.warn(this, "新增工位失败", $"{form.CubicleName}已存在!", autoClose: 3, align: TAlignFrom.TR);
}
}
}
private void menu1_MouseClick(object sender, MouseEventArgs e)

View File

@ -28,14 +28,15 @@
/// </summary>
private void InitializeComponent()
{
AntdUI.MenuItem menuItem1 = new AntdUI.MenuItem();
AntdUI.MenuItem menuItem2 = new AntdUI.MenuItem();
AntdUI.MenuItem menuItem3 = new AntdUI.MenuItem();
AntdUI.Tabs.StyleCard styleCard1 = new AntdUI.Tabs.StyleCard();
AntdUI.MenuItem menuItem4 = new AntdUI.MenuItem();
AntdUI.MenuItem menuItem5 = new AntdUI.MenuItem();
AntdUI.MenuItem menuItem6 = new AntdUI.MenuItem();
AntdUI.Tabs.StyleCard styleCard2 = new AntdUI.Tabs.StyleCard();
pageHeader1 = new AntdUI.PageHeader();
panel1 = new AntdUI.Panel();
panel2 = new AntdUI.Panel();
btnAdd = new AntdUI.Button();
panel2 = new AntdUI.StackPanel();
btnSave = new AntdUI.Dropdown();
btnAdd = new AntdUI.Dropdown();
menu1 = new AntdUI.Menu();
panel3 = new AntdUI.Panel();
tabs1 = new AntdUI.Tabs();
@ -71,46 +72,62 @@
//
// panel2
//
panel2.Back = SystemColors.Window;
panel2.BackColor = SystemColors.Window;
panel2.Controls.Add(btnSave);
panel2.Controls.Add(btnAdd);
panel2.Dock = DockStyle.Fill;
panel2.Location = new Point(0, 497);
panel2.Location = new Point(0, 632);
panel2.Name = "panel2";
panel2.Size = new Size(141, 169);
panel2.Size = new Size(141, 34);
panel2.TabIndex = 1;
panel2.Text = "panel2";
//
// btnSave
//
btnSave.BackActive = SystemColors.Control;
btnSave.BackColor = SystemColors.Control;
btnSave.Dock = DockStyle.Right;
btnSave.Font = new Font("Microsoft YaHei UI", 10.5F, FontStyle.Regular, GraphicsUnit.Point, 134);
btnSave.ForeColor = Color.Black;
btnSave.IconSvg = "SaveOutlined";
btnSave.Location = new Point(72, 3);
btnSave.Name = "btnSave";
btnSave.Size = new Size(63, 28);
btnSave.TabIndex = 2;
btnSave.Text = "保存";
//
// btnAdd
//
btnAdd.BackActive = SystemColors.Control;
btnAdd.BackColor = SystemColors.Control;
btnAdd.Dock = DockStyle.Bottom;
btnAdd.Dock = DockStyle.Left;
btnAdd.Font = new Font("Microsoft YaHei UI", 10.5F, FontStyle.Regular, GraphicsUnit.Point, 134);
btnAdd.ForeColor = Color.Black;
btnAdd.IconRatio = 1F;
btnAdd.IconSvg = "AppstoreAddOutlined";
btnAdd.Location = new Point(0, 138);
btnAdd.Location = new Point(3, 3);
btnAdd.Name = "btnAdd";
btnAdd.Size = new Size(141, 31);
btnAdd.Placement = AntdUI.TAlignFrom.TL;
btnAdd.Size = new Size(63, 28);
btnAdd.TabIndex = 1;
btnAdd.Click += btnAdd_Click;
btnAdd.Text = "新增";
btnAdd.Trigger = AntdUI.Trigger.Hover;
//
// menu1
//
menu1.BackColor = SystemColors.Window;
menu1.Dock = DockStyle.Top;
menuItem1.IconSvg = "VideoCameraOutlined";
menuItem1.Text = "相机设置";
menuItem2.IconSvg = "AppstoreOutlined";
menuItem2.Text = "工位设置";
menuItem3.IconSvg = "ControlOutlined";
menuItem3.Text = "运控设置";
menu1.Items.Add(menuItem1);
menu1.Items.Add(menuItem2);
menu1.Items.Add(menuItem3);
menuItem4.IconSvg = "VideoCameraOutlined";
menuItem4.Text = "相机设置";
menuItem5.IconSvg = "AppstoreOutlined";
menuItem5.Text = "工位设置";
menuItem6.IconSvg = "ControlOutlined";
menuItem6.Text = "运控设置";
menu1.Items.Add(menuItem4);
menu1.Items.Add(menuItem5);
menu1.Items.Add(menuItem6);
menu1.Location = new Point(0, 0);
menu1.Name = "menu1";
menu1.Size = new Size(141, 497);
menu1.Size = new Size(141, 632);
menu1.TabIndex = 0;
menu1.Text = "menu1";
menu1.MouseDown += menu1_MouseDown;
@ -135,7 +152,8 @@
tabs1.Location = new Point(151, 33);
tabs1.Name = "tabs1";
tabs1.Size = new Size(891, 666);
tabs1.Style = styleCard1;
styleCard2.Closable = true;
tabs1.Style = styleCard2;
tabs1.TabIndex = 5;
tabs1.Text = "tabs1";
tabs1.Type = AntdUI.TabType.Card;
@ -171,11 +189,12 @@
private AntdUI.PageHeader pageHeader1;
private AntdUI.Panel panel1;
private AntdUI.Panel panel2;
private AntdUI.Button btnAdd;
private AntdUI.StackPanel panel2;
private AntdUI.Menu menu1;
private AntdUI.Panel panel3;
private AntdUI.Tabs tabs1;
private AntdUI.Divider divider1;
private AntdUI.Dropdown btnAdd;
private AntdUI.Button btnSave;
}
}

View File

@ -5,53 +5,139 @@ using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Forms;
using AntdUI;
using AntdUI.Svg;
using DH.Commons.Enums;
using DH.Commons.Helper;
using DH.Devices.Devices;
using DH.Devices.PLC;
using DHSoftware.Utils;
namespace DHSoftware.Views
{
public partial class SettingWindow1 : Window
{
private UserControl currControl;
List<CameraBase> CameraBaseList = new List<CameraBase>();
List<PLCBase> PLCBaseList = new List<PLCBase>();
List<DetectionConfig> DetectionList = new List<DetectionConfig>();
public SettingWindow1()
{
InitializeComponent();
AntdUI.TooltipComponent tooltip = new AntdUI.TooltipComponent()
{
Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134))),
};
tooltip.ArrowAlign = AntdUI.TAlign.Right;
tooltip.SetTip(btnAdd, "新增工位");
BindEventHandler();
InitData();
}
private void btnAdd_Click(object sender, EventArgs e)
private void BindEventHandler()
{
// 查找工位设置项
var workstationItem = FindMenuItem(menu1.Items, "工位设置");
Resize += SettingWindow1_Resize;
btnAdd.SelectedValueChanged += btnAdd_SelectedValueChanged;
btnSave.Click += BtnSave_Click;
if (workstationItem != null)
}
private float x; //定义当前窗体的宽度
private float y; //定义当前窗体的高度
private void InitData()
{
btnAdd.Items.Clear();
btnAdd.Items.Add("相机设置");
btnAdd.Items.Add("工位设置");
btnAdd.Items.Add("运控设置");
x = Width;
y = Height;
AdaptiveHelper.setTag(this);
// 从文件加载配置
var loadedConfig = ConfigManager.LoadConfig();
if (loadedConfig != null)
{
using (var dlg = new AddCubicleWindow())
// 更新当前列表
CameraBaseList = loadedConfig.Cameras;
PLCBaseList = loadedConfig.PLCs;
DetectionList = loadedConfig.Detections;
if (CameraBaseList.Count > 0)
{
if (dlg.ShowDialog() == DialogResult.OK)
var workstationItem = FindMenuItem(menu1.Items, "相机设置");
if (workstationItem != null)
{
AddSubItem(workstationItem, dlg.CubicleName);
foreach (var item in CameraBaseList)
{
var newItem = new MenuItem();
newItem.Text = item.CameraName;
newItem.IconSvg = "VideoCameraOutlined";
workstationItem.Sub.Add(newItem);
}
}
else
}
if (DetectionList.Count > 0)
{
var workstationItem = FindMenuItem(menu1.Items, "工位设置");
if (workstationItem != null)
{
AntdUI.Notification.error(this, "操作失败", "未找到工位设置项", TAlignFrom.TR);
foreach (var item in DetectionList)
{
var newItem = new MenuItem();
newItem.Text = item.Name;
newItem.IconSvg = "AppstoreOutlined";
workstationItem.Sub.Add(newItem);
}
}
}
if (PLCBaseList.Count > 0)
{
var workstationItem = FindMenuItem(menu1.Items, "运控设置");
if (workstationItem != null)
{
foreach (var item in PLCBaseList)
{
var newItem = new MenuItem();
newItem.Text = item.PLCName;
newItem.IconSvg = "ControlOutlined";
workstationItem.Sub.Add(newItem);
}
}
}
}
}
private void BtnSave_Click(object? sender, EventArgs e)
{
var config = ConfigManager.CreateConfig(CameraBaseList, PLCBaseList, DetectionList);
ConfigManager.SaveConfig(config);
MessageBox.Show("保存成功!");
}
private void SettingWindow1_Resize(object? sender, EventArgs e)
{
var newx = Width / x;
var newy = Height / y;
AdaptiveHelper.setControls(newx, newy, this);
}
// 递归查找菜单项
private MenuItem FindMenuItem(MenuItemCollection items, string targetText)
{
@ -67,101 +153,197 @@ namespace DHSoftware.Views
return null;
}
// 添加子项方法
private void AddSubItem(MenuItem parentItem, string cubicleName)
{
// 创建带图标的菜单项
var newItem = new MenuItem(cubicleName)
{
IconSvg = "AppstoreOutlined",
Tag = Guid.NewGuid() // 添加唯一标识
};
// 检查重复项根据名称和ID
if (!parentItem.Sub.Cast<MenuItem>().Any(m =>
m.Text == cubicleName &&
m.Tag?.ToString() == newItem.Tag.ToString()))
{
parentItem.Sub.Add(newItem);
// 自动展开父项
if (!parentItem.Expand) parentItem.Expand = true;
// 刷新菜单布局
menu1.Invalidate();
}
else
{
AntdUI.Notification.warn(this, "添加失败", "工位名称已存在", TAlignFrom.TR);
}
}
bool isUpdatingTabs = false;
private void menu1_MouseDown(object sender, MouseEventArgs e)
{
// 转换坐标到控件内部坐标系(考虑滚动条)
Point clickPoint = new Point(e.X, e.Y + menu1.ScrollBar.Value);
// 递归查找命中的菜单项
MenuItem clickedItem = FindClickedItem(menu1.Items, clickPoint);
if (clickedItem != null)
if (e.Button == MouseButtons.Left)
{
if (clickedItem.PARENTITEM == null)
{
return;
}
// 转换坐标到控件内部坐标系(考虑滚动条)
Point clickPoint = new Point(e.X, e.Y + menu1.ScrollBar.Value);
switch (clickedItem.PARENTITEM.Text)
{
case "相机设置":
// 递归查找命中的菜单项
MenuItem clickedItem = FindClickedItem(menu1.Items, clickPoint);
break;
case "工位设置":
// 检查是否已存在同名 TabPage
foreach (var tab in tabs1.Pages)
{
if (tab is AntdUI.TabPage existingTab && existingTab.Text == $"{clickedItem.PARENTITEM.Text}-{clickedItem.Text}")
if (clickedItem != null)
{
if (clickedItem.PARENTITEM == null)
{
return;
}
switch (clickedItem.PARENTITEM.Text)
{
case "相机设置":
foreach (var tab in tabs1.Pages)
{
isUpdatingTabs = true;
tabs1.SelectedTab = existingTab; // 直接跳转到已存在的 TabPage
isUpdatingTabs = false;
currControl = existingTab.Controls.Count > 0 ? existingTab.Controls[0] as UserControl : null;
return;
if (tab is AntdUI.TabPage existingTab && existingTab.Text == $"{clickedItem.PARENTITEM.Text}-{clickedItem.Text}")
{
isUpdatingTabs = true;
tabs1.SelectedTab = existingTab; // 直接跳转到已存在的 TabPage
isUpdatingTabs = false;
currControl = existingTab.Controls.Count > 0 ? existingTab.Controls[0] as UserControl : null;
return;
}
}
}
UserControl control = null;
control = new DetectControl(this);
if (control != null)
{
//容器添加控件需要调整dpi
control.Dock = DockStyle.Fill;
AutoDpi(control);
AntdUI.TabPage tabPage = new AntdUI.TabPage()
//先获取是否存在该名称的配置
//如果没有新建项
CameraBase? CameraBase= CameraBaseList.Where(c => c.CameraName == clickedItem.Text).FirstOrDefault();
if (CameraBase == null)
{
Text = $"{clickedItem.PARENTITEM.Text}-{clickedItem.Text}",
};
tabPage.Controls.Add(control);
tabs1.Pages.Add(tabPage);
isUpdatingTabs = true;
tabs1.SelectedTab = tabPage;
isUpdatingTabs = false;
currControl = control;
}
break;
CameraBase=new CameraBase();
}
UserControl control = null;
control = new CameraControl(this, CameraBase);
if (control != null)
{
//容器添加控件需要调整dpi
control.Dock = DockStyle.Fill;
AutoDpi(control);
AntdUI.TabPage tabPage = new AntdUI.TabPage()
{
Text = $"{clickedItem.PARENTITEM.Text}-{clickedItem.Text}",
ReadOnly = false,
case "运控设置":
};
tabPage.Controls.Add(control);
tabs1.Pages.Add(tabPage);
isUpdatingTabs = true;
tabs1.SelectedTab = tabPage;
isUpdatingTabs = false;
currControl = control;
}
break;
case "工位设置":
// 检查是否已存在同名 TabPage
foreach (var tab in tabs1.Pages)
{
if (tab is AntdUI.TabPage existingTab && existingTab.Text == $"{clickedItem.PARENTITEM.Text}-{clickedItem.Text}")
{
isUpdatingTabs = true;
tabs1.SelectedTab = existingTab; // 直接跳转到已存在的 TabPage
isUpdatingTabs = false;
currControl = existingTab.Controls.Count > 0 ? existingTab.Controls[0] as UserControl : null;
return;
}
}
break;
UserControl control1 = null;
control1 = new DetectControl(this);
if (control1 != null)
{
//容器添加控件需要调整dpi
control1.Dock = DockStyle.Fill;
AutoDpi(control1);
AntdUI.TabPage tabPage = new AntdUI.TabPage()
{
Text = $"{clickedItem.PARENTITEM.Text}-{clickedItem.Text}",
ReadOnly = false ,
};
tabPage.Controls.Add(control1);
tabs1.Pages.Add(tabPage);
isUpdatingTabs = true;
tabs1.SelectedTab = tabPage;
isUpdatingTabs = false;
currControl = control1;
}
break;
case "运控设置":
break;
}
}
}
}
else if (e.Button == MouseButtons.Right)
{
// 转换坐标到控件内部坐标系(考虑滚动条)
Point clickPoint = new Point(e.X, e.Y + menu1.ScrollBar.Value);
// 递归查找命中的菜单项
MenuItem clickedItem = FindClickedItem(menu1.Items, clickPoint);
if (clickedItem != null)
{
if (clickedItem.PARENTITEM == null)
{
return;
}
switch (clickedItem.PARENTITEM.Text)
{
case "相机设置":
var menulist = new AntdUI.IContextMenuStripItem[]
{
new AntdUI.ContextMenuStripItem("删除相机", "")
{
IconSvg = "DeleteOutlined"
}
};
AntdUI.ContextMenuStrip.open(menu1, it =>
{
menu1.Remove(clickedItem);
foreach (var tab in tabs1.Pages)
{
if (tab is AntdUI.TabPage existingTab && existingTab.Text == $"{clickedItem.PARENTITEM.Text}-{clickedItem.Text}")
{
isUpdatingTabs = true;
tabs1.Pages.Remove(tab);
CameraBaseList.RemoveAll(c => c.CameraName == clickedItem.Text);
isUpdatingTabs = false;
currControl = existingTab.Controls.Count > 0 ? existingTab.Controls[0] as UserControl : null;
return;
}
}
CameraBaseList.RemoveAll(c => c.CameraName == clickedItem.Text);
}, menulist);
break;
case "工位设置":
var menulist1 = new AntdUI.IContextMenuStripItem[]
{
new AntdUI.ContextMenuStripItem("删除工位", "")
{
IconSvg = "DeleteOutlined"
}
};
AntdUI.ContextMenuStrip.open(menu1, it =>
{
menu1.Remove(clickedItem);
foreach (var tab in tabs1.Pages)
{
if (tab is AntdUI.TabPage existingTab && existingTab.Text == $"{clickedItem.PARENTITEM.Text}-{clickedItem.Text}")
{
isUpdatingTabs = true;
//tabs1.SelectedTab = existingTab; // 直接跳转到已存在的 TabPage
tabs1.Pages.Remove(tab);
isUpdatingTabs = false;
currControl = existingTab.Controls.Count > 0 ? existingTab.Controls[0] as UserControl : null;
return;
}
}
}, menulist1);
break;
case "运控设置":
break;
}
}
}
}
private MenuItem FindClickedItem(MenuItemCollection items, Point clickPoint)
@ -183,6 +365,76 @@ namespace DHSoftware.Views
}
return null;
}
private void btnAdd_SelectedValueChanged(object sender, ObjectNEventArgs e)
{
string selectedValue = e.Value.ToString();
switch (selectedValue)
{
case "相机设置":
var workstationItem = FindMenuItem(menu1.Items, "相机设置");
if (workstationItem != null)
{
var form = new AddCameraControl(this) { Size = new Size(300, 200) };
AntdUI.Modal.open(new AntdUI.Modal.Config(this, "", form, TType.None)
{
BtnHeight = 0,
});
if (form.submit)
{
var newItem = new MenuItem(form.CubicleName);
newItem.IconSvg = "VideoCameraOutlined";
// 防止重复添加
if (!menu1.Items.Cast<MenuItem>().Any(m => m.Text == newItem.Text))
{
workstationItem.Sub.Add(newItem);
CameraBase cameraBase = new CameraBase();
cameraBase.CameraName = form.CubicleName;
CameraBaseList.Add(cameraBase);
}
else
{
AntdUI.Notification.warn(this, "新增相机失败", $"{form.CubicleName}已存在!", autoClose: 3, align: TAlignFrom.TR);
}
}
}
break;
case "工位设置":
// 查找工位设置项
var workstationItem1= FindMenuItem(menu1.Items, "工位设置");
if (workstationItem1 != null)
{
var form = new AddCubicleControl(this) { Size = new Size(300, 200) };
AntdUI.Modal.open(new AntdUI.Modal.Config(this, "", form, TType.None)
{
BtnHeight = 0,
});
if (form.submit)
{
var newItem = new MenuItem(form.CubicleName);
newItem.IconSvg = "AppstoreOutlined";
// 防止重复添加
if (!menu1.Items.Cast<MenuItem>().Any(m => m.Text == newItem.Text))
{
workstationItem1.Sub.Add(newItem);
}
else
{
AntdUI.Notification.warn(this, "新增工位失败", $"{form.CubicleName}已存在!", autoClose: 3, align: TAlignFrom.TR);
}
}
}
break;
case "运控设置":
break;
}
}
}
}

View File

@ -236,23 +236,23 @@ namespace DHSoftware.Views
private void btnAdd_Click(object sender, EventArgs e)
{
using (var dlg = new AddCubicleWindow())
{
if (dlg.ShowDialog() == DialogResult.OK)
{
var newItem = new MenuItem(dlg.CubicleName);
//newItem.IconSvg = "AppstoreOutlined";
// 防止重复添加
if (!menu.Items.Cast<MenuItem>().Any(m => m.Text == newItem.Text))
{
menu.Items.Add(newItem);
}
else
{
// AntdUI.Notification.warn(this, "新增工位失败", $"{dlg.CubicleName}已存在!", autoClose: 3, align: TAlignFrom.TR);
}
}
}
//using (var dlg = new AddCubicleWindow())
//{
// if (dlg.ShowDialog() == DialogResult.OK)
// {
// var newItem = new MenuItem(dlg.CubicleName);
// //newItem.IconSvg = "AppstoreOutlined";
// // 防止重复添加
// if (!menu.Items.Cast<MenuItem>().Any(m => m.Text == newItem.Text))
// {
// menu.Items.Add(newItem);
// }
// else
// {
// // AntdUI.Notification.warn(this, "新增工位失败", $"{dlg.CubicleName}已存在!", autoClose: 3, align: TAlignFrom.TR);
// }
// }
//}
}
}
}