带有标题和内容的 UserControl - 允许在内容面板中放置控件并防止在设计时在标题中放置控件

UserControl with header and content - Allow dropping controls in content panel and Prevent dropping controls in header at design time(带有标题和内容的 UserControl - 允许在内容面板中放置控件并防止在设计时在标题中放置控件)
本文介绍了带有标题和内容的 UserControl - 允许在内容面板中放置控件并防止在设计时在标题中放置控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了用户控制(耶!).但我希望它表现得像一个容器.可是等等!我知道

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

诡计.

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

为了提供更广泛的上下文:我编写了一个具有网格、一些常用按钮、标签和功能的控件.但它也有一部分用户应该放弃他的自定义按钮/控件.只在这个特定的部分控制,别无他处.

有人知道吗?

解决方案

你应该做到以下几点:

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

    代码

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

    您的用户控制

    [Designer(typeof(MyUserControlDesigner))]公共部分类 MyUserControl:UserControl{公共 MyUserControl(){初始化组件();TypeDescriptor.AddAttributes(this.panel1,新的 DesignerAttribute(typeof(MyPanelDesigner)));}[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]公共面板 ContentsPanel{得到{返回面板1;}}}

    内面板设计器

    公共类 MyPanelDesigner : ParentControlDesigner{公共覆盖 SelectionRules SelectionRules{得到{选择规则 selectionRules = base.SelectionRules;selectionRules &= ~SelectionRules.AllSizeable;返回选择规则;}}protected override void PostFilterAttributes(IDictionary 属性){base.PostFilterAttributes(属性);属性[typeof(DockingAttribute)] =新的对接属性(对接行为.从不);}受保护的覆盖无效 PostFilterProperties(IDictionary 属性){base.PostFilterProperties(属性);var propertiesToRemove = 新字符串 [] {码头",锚点",尺寸",位置",宽度",高度",MinimumSize"、MaximumSize"、AutoSize"、AutoSizeMode"、可见"、启用"、};foreach(propertiesToRemove 中的 var 项){如果(属性.包含(项目))属性[项目] = TypeDescriptor.CreateProperty(this.Component.GetType(),(PropertyDescriptor)properties[item],新的 BrowsableAttribute(false));}}}

    用户控件设计器

    公共类 MyUserControlDesigner : ParentControlDesigner{公共覆盖无效初始化(IComponent 组件){base.Initialize(组件);var contentsPanel = ((MyUserControl)this.Control).ContentsPanel;this.EnableDesignMode(contentsPanel, "ContentsPanel");}public override bool CanParent(Control control){返回假;}受保护的覆盖无效 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){返回空值;}}

    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:

    • r-aghaei/ChildContainerControlDesignerSample
    • Download Zip

    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 - 允许在内容面板中放置控件并防止在设计时在标题中放置控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)