using Check.Main.Common; using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing.Design; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms.Design; namespace Check.Main.Camera { // 相机触发方式枚举 public enum TriggerModeType { [Description("连续采集")] Continuous, [Description("软件触发")] Software, [Description("硬件触发")] Hardware } public enum CheckType { [Description("传统算法")] Traditional, [Description("深度学习")] DeepLearning } /// /// 相机配置信息类CameraSettings,用于PropertyGrid显示和编辑(****核心!****) /// public class CameraSettings : INotifyPropertyChanged, ICloneable { // 1. 实现 INotifyPropertyChanged 接口所要求的事件 public event PropertyChangedEventHandler PropertyChanged; private int _cameraIndex = 0; private string _name = "Camera-1"; private string _ipAddress = "169.254.51.253"; private string _ipDeviceAddress = "169.254.51.45"; private TriggerModeType _triggerMode = TriggerModeType.Continuous; private bool _isEnabled = true; private CheckType _checkType = CheckType.DeepLearning; private int _modelID = 0; [Category("基本信息"), DisplayName("相机编号"), Description("相机的唯一标识符,用于与模型编号对应。")] public int CameraIndex { get => _cameraIndex; set { if (_cameraIndex != value) { _cameraIndex = value; OnPropertyChanged(); } } } [Category("基本信息"), DisplayName("相机名称"), Description("给相机起一个唯一的别名")] public string Name { get => _name; set { // 2. 在setter中检查值是否真的改变了 if (_name != value) { _name = value; // 3. 如果改变了,就调用通知方法,广播“Name”属性已变更的消息 OnPropertyChanged(); } } } [Category("网络信息"), DisplayName("相机IP地址"), Description("相机的IP地址(GigE相机需要)")] public string IPAddress { get => _ipAddress; set { if (_ipAddress != value) { _ipAddress = value; OnPropertyChanged(); } } } [Category("网络信息"), DisplayName("上位机IP地址"), Description("相机对应的上位机的IP地址(GigE相机需要)")] public string IPDeviceAddress { get => _ipDeviceAddress; set { if (_ipDeviceAddress != value) { _ipDeviceAddress = value; OnPropertyChanged(); } } } [Category("采集控制"), DisplayName("触发模式"), Description("设置相机的图像采集触发方式")] [TypeConverter(typeof(EnumDescriptionTypeConverter))] public TriggerModeType TriggerMode { get => _triggerMode; set { if (_triggerMode != value) { _triggerMode = value; OnPropertyChanged(); } } } [Category("采集控制"), DisplayName("是否启用"), Description("是否在程序启动时初始化并使用此相机")] public bool IsEnabled { get => _isEnabled; set { if (_isEnabled != value) { _isEnabled = value; OnPropertyChanged(); } } } [Category("检测配置"), DisplayName("检测类型"), Description("使用传统算法或深度学习")] [TypeConverter(typeof(EnumDescriptionTypeConverter))] public CheckType CheckType { get => _checkType; set { if (_checkType != value) { _checkType = value; OnPropertyChanged(); } } } [Category("基本信息"), DisplayName("模型编号"), Description("相机调用的模型编号")] [TypeConverter(typeof(ModelSelectionConverter))] public int ModelID { get => _modelID; set { if (_modelID != value) { _modelID = value; OnPropertyChanged(); } } } /// /// 4. 触发 PropertyChanged 事件的辅助方法 /// [CallerMemberName] 特性是一个“语法糖”,它会自动获取调用此方法的属性的名称。 /// 例如,在Name属性的setter中调用OnPropertyChanged(),C#编译器会自动传入"Name"作为参数。 /// protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public object Clone() { // MemberwiseClone() 会创建一个新对象,并将当前对象的所有非静态字段的值 // 复制到新对象中。对于值类型,这是值的拷贝;对于引用类型,这是引用的拷贝。 // 在本类中,这已经足够了。 return this.MemberwiseClone(); } } }