将控件添加到设计器中用户控件上的面板上

时间:2018-08-27 22:21:34

标签: c# winforms user-controls

我有创建具有特定常用功能的用户控件的特定要求。对于该控件,我还要求允许其他开发人员在设计器模式下添加控件以制作特定的UI。为此,我创建了一个用户控件,添加了(样本)标签和按钮。我还添加了一个面板,以允许在控件的特定区域中添加其他控件。

然后,通过添加[Designer]标记和[ControlDesigner],使该类在设计器模式下可见。这样可以达到添加具有某些固定内容的User控件并向页面添加更多控件的预期效果。问题在于用户可以在设计模式下移动面板,VisualStudio感到困惑,创建了循环引用。即使我需要启用设计模式,也可以关闭面板的调整大小/位置吗?

注意:我还尝试只在设计模式下使用用户控件,但是添加的控件一直消失在用户控件上的固定控件后面。

代码和示例如下。欢迎任何建议/修复。

上面是面板上用户控件的外观

enter image description here

上面是一个包含用户控件的窗体,并向该面板添加了自定义按钮。.请注意,启用了面板拖动,如果触摸,则会在form.designer.cs文件中创建一个循环引用,并且该项目变为不稳定。

最后是用户控制的类

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;

using System.Windows.Forms.Design;

namespace wfcLib
{

    [DesignerAttribute(typeof(MyControlDesigner))]
    [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
    public partial class ucInput : UserControl
    {

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public Panel InternalPanel
        {
            get { return pnlContent; }
            set { pnlContent = value; }
        }
        public ucInput()
        {
            InitializeComponent();

        }

    }
    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    public class MyControlDesigner : System.Windows.Forms.Design.ControlDesigner
    {
        public override void Initialize(IComponent c)
        {
            base.Initialize(c);
            ucInput ctl = (ucInput)c;
            EnableDesignMode(ctl.InternalPanel, "InternalPanel");
        }
    }
}

1 个答案:

答案 0 :(得分:0)

除了我的评论有关将派生的Panel与覆盖了SelectionRules属性的自己的设计器一起使用之外,另一种方法是利用设计器的ISelectionService来检测更改。选择组件,并删除面板(如果已选择)。

这是通过重写控件的Site属性来设置钩子来实现的。还要注意,我将InternalPanel属性更改为只读,因为您确实不希望该属性可写。

[DesignerAttribute(typeof(MyControlDesigner))]
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
public partial class ucInput : UserControl
{

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public Panel InternalPanel
    {
        get { return pnlContent; }
    }

    public ucInput()
    {
        InitializeComponent();
    }

    private ISelectionService selectionService;
    private IDesignerHost host;
    public override ISite Site
    {
        get
        {
            return base.Site;
        }
        set
        {
            host = null;
            UnSubscribeFromSelectionService();
            base.Site = value;
            if (value != null)
            {
                host = (IDesignerHost)this.Site.GetService(typeof(IDesignerHost));
                if (host != null)
                {
                    if (host.Loading)
                    {
                        // defer subscription to selection service until fully loaded
                        host.Activated += Host_Activated;
                    }
                    else
                    {
                        SubscribeToSelectionService();
                    }
                }
            }
        }
    }

    private void Host_Activated(object sender, EventArgs e)
    {
        host.Activated -= Host_Activated;
        SubscribeToSelectionService();
    }

    private void SubscribeToSelectionService()
    {
        selectionService = (ISelectionService)this.Site.GetService(typeof(ISelectionService));
        if (selectionService != null)
        {
            selectionService.SelectionChanging += OnSelectionChanging;
        }
    }

    private void UnSubscribeFromSelectionService()
    {
        if (selectionService != null)
        {
            selectionService.SelectionChanging -= OnSelectionChanging;
        }
    }

    private void OnSelectionChanging(object sender, EventArgs e)
    {
        if (selectionService.GetComponentSelected(pnlContent))
        {
            selectionService.SelectionChanging -= OnSelectionChanging;
            selectionService.SetSelectedComponents(new[] { pnlContent }, SelectionTypes.Remove);
            selectionService.SelectionChanging += OnSelectionChanging;
        }
    }
}

编辑:在加载SelectionService时被忽略的原始代码无法解决IDesignerHost的问题。添加了代码以延迟订阅,直到激活IDesignerHost为止。