using Check.Main.Camera; using Check.Main.Infer; using Check.Main.UI; using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing.Design; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms.Design; namespace Check.Main.Common { public class ProcessConfig { private string _logPath = Path.Combine(Application.StartupPath, "Logs"); private List _cameraSettings = new List(); private List _modelaSettings = new List(); [Category("常规设置"), DisplayName("日志路径"), Description("设置日志文件的保存目录。")] [Editor(typeof(FolderNameEditor), typeof(UITypeEditor))] // 使用内置的文件夹选择器 public string LogPath { get => _logPath; set => _logPath = value; } [Category("核心配置"), DisplayName("相机配置"), Description("点击 '...' 按钮来配置所有相机。")] [Editor(typeof(CameraConfigEditor), typeof(UITypeEditor))] // 【关键】指定使用我们自定义的编辑器 [TypeConverter(typeof(CameraConfigConverter))] // 【关键】指定使用我们自定义的类型转换器来显示文本 public List CameraSettings { get => _cameraSettings; set => _cameraSettings = value; } [Category("核心配置"), DisplayName("模型配置"), Description("点击 '...' 按钮来配置所有模型。")] [Editor(typeof(ModelConfigEditor), typeof(UITypeEditor))] // 【关键】指定使用我们自定义的编辑器 [TypeConverter(typeof(ModelConfigConverter))] // 【关键】指定使用我们自定义的类型转换器来显示文本 public List ModelSettings { get => _modelaSettings; set => _modelaSettings = value; } } /// /// 自定义TypeConverter,用于在PropertyGrid中自定义显示相机列表的文本。 /// public class CameraConfigConverter : TypeConverter { public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { // 声明可以将值转换为字符串 return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { // 如果目标类型是字符串,并且值是相机设置列表 if (destinationType == typeof(string) && value is List list) { // 返回自定义的描述性文本 return $"已配置 {list.Count} 个相机"; } return base.ConvertTo(context, culture, value, destinationType); } } /// /// 自定义TypeConverter,用于在PropertyGrid中自定义显示相机列表的文本。 /// public class ModelConfigConverter : TypeConverter { public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { // 声明可以将值转换为字符串 return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { // 如果目标类型是字符串,并且值是相机设置列表 if (destinationType == typeof(string) && value is List list) { // 返回自定义的描述性文本 return $"已配置 {list.Count} 个模型"; } return base.ConvertTo(context, culture, value, destinationType); } } /// /// 自定义UITypeEditor,用于在点击 "..." 时打开相机配置窗体。 /// public class CameraConfigEditor : UITypeEditor { // 1. 设置编辑样式为模态对话框 public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) { return UITypeEditorEditStyle.Modal; } // 2. 重写编辑方法 public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { // 'value' 就是当前属性的值,即 List var settingsList = value as List; // 使用 FrmCamConfig 作为对话框进行编辑 // 我们需要给 FrmCamConfig 添加一个新的构造函数 using (var camConfigForm = new FrmCamConfig(settingsList)) { // 以对话框形式显示窗体 if (camConfigForm.ShowDialog() == DialogResult.OK) { // 如果用户点击了“确定”,返回修改后的新列表 return camConfigForm._settingsList; } } // 如果用户点击了“取消”或直接关闭了窗口,返回原始值,不做任何更改 return value; } } /// /// 【新增】自定义UITypeEditor,用于在点击 "..." 时打开模型配置窗体。 /// public class ModelConfigEditor : UITypeEditor { // 1. 设置编辑样式为模态对话框 public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) { return UITypeEditorEditStyle.Modal; } // 2. 重写编辑方法 public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { // 'value' 就是当前属性的值,即 List var settingsList = value as List; // 使用ModelEditor 作为对话框进行编辑 // 我们需要给 FrmCamConfig 添加一个新的构造函数 using (var modelConfigForm = new ModelListEditor(settingsList)) { // 以对话框形式显示窗体 if (modelConfigForm.ShowDialog() == DialogResult.OK) { // 如果用户点击了“确定”,返回修改后的新列表 return modelConfigForm._settingsList; } } // 如果用户点击了“取消”或直接关闭了窗口,返回原始值,不做任何更改 return value; } } }