具有标题和内容的UserControl-允许在设计时在内容面板中放置控件,并防止在设计时在标题中放置控件 [英] UserControl with header and content - Allow dropping controls in content panel and Prevent dropping controls in header at design time

查看:132
本文介绍了具有标题和内容的UserControl-允许在设计时在内容面板中放置控件,并防止在设计时在标题中放置控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了用户控件(是的!)。但是我希望它表现为一个容器。可是等等!我知道

  [Designer( System.Windows.Forms.Design.ParentControlDesigner,System.Design,
typeof(IDesigner))]

Trick。



问题是-我不希望我的所有控件都像容器一样,而只希望其中一部分起作用。一个-实际上是面板;)



给出更广泛的上下文:我编写了一个控件,该控件具有Grid,一些常用按钮,标签和功能。但是它也有一部分,用户应该放下其自定义按钮/控件。仅在控件的这一特定部分,无处不在。



有人有什么主意吗?

解决方案

您应该执行以下操作:




  • 对于用户控件,您需要创建一个新的设计器,该设计器通过调用



    代码



    这是解决方案不同元素的代码。



    您的用户控制ol

      [Designer(typeof(MyUserControlDesigner))] 
    公共局部类MyUserControl:UserControl
    {
    public MyUserControl()
    {
    InitializeComponent();
    TypeDescriptor.AddAttributes(this.panel1,
    new DesignerAttribute(typeof(MyPanelDesigner)));
    }
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public Panel ContentsPanel
    {
    get {return panel1; }
    }
    }

    内部面板设计器

     公共类MyPanelDesigner:ParentControlDesigner 
    {
    公共替代SelectionRules SelectionRules
    {
    get
    {
    SelectionRules selectionRules = base.SelectionRules;
    selectionRules& =〜SelectionRules.AllSizeable;
    返回选择规则;
    }
    }
    受保护的覆盖无效PostFilterAttributes(IDictionary属性)
    {
    base.PostFilterAttributes(attributes);
    属性[typeof(DockingAttribute)] =
    新的DockingAttribute(DockingBehavior.Never);
    }
    受保护的覆盖无效PostFilterProperties(IDictionary properties)
    {
    base.PostFilterProperties(properties);
    var propertiesToRemove =新字符串[] {
    Dock, Anchor, Size, Location, Width, Height,
    MinimumSize, MaximumSize , AutoSize, AutoSizeMode,
    可见,已启用,
    };
    foreach(propertiesToRemove中的可变项)
    {
    if(properties.Contains(item))
    properties [item] = TypeDescriptor.CreateProperty(this.Component.GetType(),
    (PropertyDescriptor)properties [item],
    new BrowsableAttribute(false));
    }
    }
    }

    您的设计师用户控件

     公共类MyUserControlDesigner:ParentControlDesigner 
    {
    公共重写void Initialize(IComponent component)
    {
    base.Initialize(component);
    var contentsPanel =(((MyUserControl)this.Control).ContentsPanel;
    this.EnableDesignMode(contentsPanel, ContentsPanel);
    }
    公共替代布尔值CanParent(Control control)
    {
    return false;
    }
    受保护的覆盖无效OnDragOver(DragEventArgs de)
    {
    de.Effect = DragDropEffects.None;
    }
    受保护的重写IComponent [] CreateToolCore(ToolboxItem tool,int x,
    int y,int width,int height,bool hasLocation,bool hasSize)
    {
    返回null;
    }
    }


    I wrote User Control (yay!). But I want it to behave as a container. But wait! I know about

    [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", 
        typeof(IDesigner))]
    

    Trick.

    The problem is - I don't want all of my control to behave like container, but only one part. One - de facto - panel ;)

    To give wider context: I wrote a control that has Grid, some common buttons, labels and functionalities. But it also has a part where the user is supposed to drop his custom buttons/controls whatever. Only in this particular part of the control, nowhere else.

    Anyone had any idea?

    解决方案

    You should do the following :

    • For your user control, you need to create a new designer which enables the inner panel on design-time by calling EnableDesignMode method.
    • For the inner panel, you need to create a designer which disables moving, resizing and removes some properties from designer.
    • You should register the designers.

    Example

    You can read a blog post about this topic here and clone or download a working example:

    Code

    Here is the code for different elements of the solution.

    Your user control

    [Designer(typeof(MyUserControlDesigner))]
    public partial class MyUserControl : UserControl
    {
        public MyUserControl()
        {
            InitializeComponent();
            TypeDescriptor.AddAttributes(this.panel1,
                new DesignerAttribute(typeof(MyPanelDesigner)));
        }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public Panel ContentsPanel
        {
            get { return panel1; }
        }
    }
    

    Designer for the inner panel

    public class MyPanelDesigner : ParentControlDesigner
    {
        public override SelectionRules SelectionRules
        {
            get
            {
                SelectionRules selectionRules = base.SelectionRules;
                selectionRules &= ~SelectionRules.AllSizeable;
                return selectionRules;
            }
        }
        protected override void PostFilterAttributes(IDictionary attributes)
        {
            base.PostFilterAttributes(attributes);
            attributes[typeof(DockingAttribute)] = 
                new DockingAttribute(DockingBehavior.Never);
        }
        protected override void PostFilterProperties(IDictionary properties)
        {
            base.PostFilterProperties(properties);
            var propertiesToRemove = new string[] {
                "Dock", "Anchor", "Size", "Location", "Width", "Height",
                "MinimumSize", "MaximumSize", "AutoSize", "AutoSizeMode",
                "Visible", "Enabled",
            };
            foreach (var item in propertiesToRemove)
            {
                if (properties.Contains(item))
                    properties[item] = TypeDescriptor.CreateProperty(this.Component.GetType(),
                        (PropertyDescriptor)properties[item],
                        new BrowsableAttribute(false));
            }
        }
    }
    

    Designer for your user control

    public class MyUserControlDesigner : ParentControlDesigner
    {
        public override void Initialize(IComponent component)
        {
            base.Initialize(component);
            var contentsPanel = ((MyUserControl)this.Control).ContentsPanel;
            this.EnableDesignMode(contentsPanel, "ContentsPanel");
        }
        public override bool CanParent(Control control)
        {
            return false;
        }
        protected override void OnDragOver(DragEventArgs de)
        {
            de.Effect = DragDropEffects.None;
        }
        protected override IComponent[] CreateToolCore(ToolboxItem tool, int x,
            int y, int width, int height, bool hasLocation, bool hasSize)
        {
            return null;
        }
    }
    

    这篇关于具有标题和内容的UserControl-允许在设计时在内容面板中放置控件,并防止在设计时在标题中放置控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆