Windows Form设计模式下自定义属性值无法保存至Designer.cs的问题
解决方案
针对自定义用户控件中User属性无法在设计器保存值的问题,可通过以下步骤修复:
1. 为UserModel添加无参构造函数
设计器序列化需要无参构造函数来创建实例,在UserModel中补充:
[Serializable] [ComVisible(true)] [TypeConverter(typeof(UserTypeConverter))] [Editor(typeof(UserTypeEditor), typeof(UITypeEditor))] public class UserModel { // 新增无参构造函数 public UserModel() : this(string.Empty, 0) { } public UserModel(string name, int age) { Name = name; Age = age; } public string Name { get; set; } public int Age { get; set; } public override string ToString() { return Name; } }
2. 修正User属性的setter,触发属性变化通知
在UserManagement控件的User属性中,添加值变化判断并触发属性变更事件,让设计器感知到值已更新:
public partial class UserManagement: UserControl { private UserModel _userModel = new UserModel("DefaultName", 0); [Category("Behavior"), Description("Instance of a user model")] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public UserModel User { get => _userModel; set { if (_userModel != value) { _userModel = value; // 触发属性变化通知,告知设计器值已更改 OnPropertyChanged(new PropertyChangedEventArgs(nameof(User))); } } } public UserManagement() { InitializeComponent(); } }
3. 确保自定义类型编辑器返回新实例
修改UserTypeEditor的EditValue方法,必须返回新的UserModel实例,而非修改原有实例(否则属性引用未变,设计器不会触发setter):
public class UserTypeEditor : UITypeEditor { public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) { return UITypeEditorEditStyle.Modal; } public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { var editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService)); if (editorService != null) { // 替换为你的选择窗体类 using (var selectionForm = new UserSelectionForm()) { if (editorService.ShowDialog(selectionForm) == DialogResult.OK) { // 返回新创建的UserModel实例 return new UserModel(selectionForm.SelectedName, selectionForm.SelectedAge); } } } // 未确认则返回原有值 return value; } }
4. 完善类型转换器实现
确保UserTypeConverter能正确将UserModel转换为字符串,让属性窗口正确显示值,同时辅助设计器识别对象变化:
public class UserTypeConverter : TypeConverter { public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(string) && value is UserModel user) { return $"[{user.Name}, Age: {user.Age}]"; } return base.ConvertTo(context, culture, value, destinationType); } }
完成以上修改后,重新生成项目,在设计器中设置User属性后,值会被正确写入Designer.cs文件,关闭重开后不会丢失。
内容的提问来源于stack exchange,提问作者Manu
相关产品推荐
相关产品推荐

