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

.NET 8 WinForms:从UserControl属性在设计器中打开窗体/控件

.NET 8 WinForms 属性网格打开Form/UserControl的实现方案

问题背景

基于.NET 8 WinForms框架,现有ucMHK用户控件,需要实现:

  • 为ucMHK添加两个属性
  • 属性网格中点击第一个属性时打开frmProps窗体
  • 点击第二个属性时打开ucProps用户控件

此前在.NET Framework 4.8.1中通过自定义UITypeEditor实现,但.NET 8中遇到问题。

.NET 8 WinForms设计器的关键变化

.NET 8的WinForms设计器采用了新的基于.NET的设计器引擎(替代旧的.NET Framework设计器),但核心的UITypeEditor机制依然兼容,需注意两点:

  1. 必须安装System.Design NuGet包(.NET 8中该包为独立依赖,非框架内置)
  2. 设计时需通过IUIService确保窗口在设计器线程中正确启动,避免线程冲突

完整实现代码

1. 安装依赖包

在项目中安装System.Design包:

Install-Package System.Design

2. 自定义UITypeEditor类

创建两个编辑器类,分别处理窗体和用户控件的打开逻辑:

using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;

namespace mhk__SandBox
{
    // 打开frmProps的编辑器
    public class FormPropsEditor : UITypeEditor
    {
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }

        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            if (provider != null)
            {
                var uiService = provider.GetService(typeof(IUIService)) as IUIService;
                using var form = new frmProps();
                
                // 通过设计器服务打开窗口,适配设计时上下文
                uiService?.ShowDialog(form) ?? form.ShowDialog();
                
                return value;
            }
            return base.EditValue(context, provider, value);
        }
    }

    // 打开ucProps的编辑器(需承载在Form中)
    public class UserControlPropsEditor : UITypeEditor
    {
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }

        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            if (provider != null)
            {
                var uiService = provider.GetService(typeof(IUIService)) as IUIService;
                // 设计器无法直接显示单独UserControl,需用Form承载
                using var hostForm = new Form();
                var uc = new ucProps();
                uc.Dock = DockStyle.Fill;
                hostForm.Controls.Add(uc);
                hostForm.Text = "ucProps Editor";
                hostForm.Size = new System.Drawing.Size(400, 300);
                
                uiService?.ShowDialog(hostForm) ?? hostForm.ShowDialog();
                
                return value;
            }
            return base.EditValue(context, provider, value);
        }
    }
}

3. 修改ucMHK添加属性

为ucMHK添加带编辑器标记的属性:

using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;

namespace mhk__SandBox
{
    public partial class ucMHK : UserControl
    {
        public ucMHK()
        {
            InitializeComponent();
        }

        [Category("Custom")]
        [DisplayName("Open Form Props")]
        [Description("点击打开frmProps")]
        [Editor(typeof(FormPropsEditor), typeof(UITypeEditor))]
        public bool OpenFormProps { get; set; }

        [Category("Custom")]
        [DisplayName("Open UC Props")]
        [Description("点击打开ucProps")]
        [Editor(typeof(UserControlPropsEditor), typeof(UITypeEditor))]
        public bool OpenUCProps { get; set; }
    }
}

注意事项

  • UserControl必须承载在Form中才能在设计器中打开,无法直接显示独立的UserControl
  • 若设计器报错,尝试清理项目并重新生成,确保设计器能正确加载自定义编辑器
  • 非设计模式下,代码会直接调用窗口的ShowDialog方法,不影响运行时逻辑

内容的提问来源于stack exchange,提问作者Murat Kocan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 17:04:52