转自:点击打开链接
最近在设计一个带标题栏的自定义控件时候,遇到很奇怪的问题——不能向组合控件中添加组件。原以为不存在或是很简单的问题,竟然被拦住好久。这个问题导致的主要问题包括:
1. 不能向组合控件中添加组件。
2. 部分方法如重载OnControlAdded方法等,会导致添加到子容器中的组件设计时或运行时不可见等问题。
虽然最终发现问题很简单,不过在google中没有发现中文的资料(可能搜索水平太差),先将Henry Minute 写在CodeProject的文章标记如此,以作备忘。
答案是在这里找到的,http://stackoverflow.com/questions/2322847/winforms-designer-add-control-and-make-it-visible-for-the-designer
谢谢BillW @stackoverflow.com
If you are dealing with the problem of how a "child" Control of a UserControl placed on a Form at Design-Time can be made to function as a container onto which you can drag-and-drop other controls from the Toolbox : this CodeProject article by Henry Minute may be helpful : Designing Nested Controls. For example : you have a UserControl with a Panel inside it : an instance of the UserControl is placed on a Form : in the Design-time view of the Form : you want to be able to drag-drop controls onto the Panel in the UserControl and have them become child controls of the Panel : Henry's article will show you how to do that.
This from Microsoft : How to make a UserControl object acts as a control container design-time by using Visual C#
解决方案(代码来自Henry Minute):
1. 为自定义控件添加Panel子控件,并将该控件公开。同时将属性的DesignerSerializationVisibility特性设置为DesignerSerializationVisibility.Content.
2. 自定义设计器。看上面代码中的UserControl的特性。
namespace NestedControlDesignerLibrary.Designers
{
public class TestControlDesigner : ParentControlDesigner
{
public override void Initialize(System.ComponentModel.IComponent component)
{
base.Initialize(component);
if (this.Control is TestControl)
{
this.EnableDesignMode((
(TestControl)this.Control).WorkingArea, "WorkingArea");
}
}
}
}
通过使用EnableDesignMode可以指定要公开的子容器,具体可以看该方法的介绍。如果要添加多个子容器,将其他的都写在这里就好了。
3. 最后的问题,子容器控件被公开,意味着我们可以再设计时更改其属性。虽然也不是完全没用,但很多时候会给人带来困扰,或者改变了原本的组合关系,变的乱糟糟,因此有必要隐藏部分属性,如Dock等。Minute也提到了一些方法。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace ImprovedNestedControlDesignerLibrary
{
[
Designer(typeof(ImprovedNestedControlDesignerLibrary.Designers.WorkingAreaDesigner))
]
public partial class WorkingAreaControl : Panel
{
public WorkingAreaControl()
{
InitializeComponent();
base.Dock = DockStyle.Fill;
}
}
}
就是通过将子容器从Panel继承,在子容器的设计器里面屏蔽Dock属性。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms.Design;
namespace ImprovedNestedControlDesignerLibrary.Designers
{
public class WorkingAreaDesigner : ScrollableControlDesigner
{
protected override void PreFilterProperties(
System.Collections.IDictionary properties)
{
properties.Remove("Dock");
base.PreFilterProperties(properties);
}
}
}
依次,可以实现一个能很好的支持子容器控件的UserControl了。
------------------------------------------------------------------
来自微软的解释和方案:
默认情况下,UserControl 对象只有在您创建它时才可以用作控件容器。在将 UserControl 放在 Windows 窗体上之后,为让 UserControl 承载构成控件,您必须更改 UserControl 的默认设计器。如要为一个组件实现设计时服务,请使用 System.ComponentModel 名称空间的 DesignerAttribute 类。DesignerAttribute 出现在类声明前面。通过传递 designerTypeName 和 DesignerAttribute 参数初始化 designerTypeName。
designerTypeName 是提供设计时服务的设计器类型的完全合格的名称。传递 designerTypeName 参数的System.Windows.Forms.Design.ParentControlDesigner 和 System.Design 的组合。ParentControlDesigner 类扩展了 UserControl 的设计时行为。
designerBaseType 是设计器的基类的名称。用于设计时服务的类必须实现 IDesigner 接口。
将 UserControl 创建为设计时控件容器
- 创建一个新的 Visual C# .NET Windows 控件库项目。为此,请按照下列步骤操作:
- 启动 Visual Studio .NET。
- 在“文件”菜单上,指向“新建”,然后单击“项目”。
- 在“项目类型”下,单击 “Visual C# 项目”,然后单击“模板”下的 “Windows 控件库”。
- 将该项目命名为 ContainerUserControl。默认情况下将创建出 “UserControl1.cs”。
- 在解决方案资源管理器中,右键单击 “UserControl1.cs”,然后单击“查看代码”。
- 将下面的代码添加到 Declarations 部分:
using System.ComponentModel.Design;
- 如下所示将 System.ComponentModel.DesignerAttribute 属性应用到该控件:
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))] public class UserControl1 :System.Windows.Forms.UserControl {
...
}
- 在“生成”菜单上,单击“生成解决方案”。
文章内容来自:
Henry Minute:
http://www.codeproject.com/KB/miscctrl/NestedControlDesigner.aspx
微软资料来自于:
http://support.microsoft.com/kb/813450
隐藏属性的资料:
Shaun Wilde:
http://www.codeproject.com/KB/webforms/HidingProperties.aspx