You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 08:56:10