具有标题和内容的UserControl-允许在设计时在内容面板中放置控件,并防止在设计时在标题中放置控件 [英] UserControl with header and content - Allow dropping controls in content panel and Prevent dropping controls in header at design time
问题描述
我写了用户控件(是的!)。但是我希望它表现为一个容器。可是等等!我知道
[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屋!
- For your user control, you need to create a new designer which enables the inner panel on design-time by calling