我正在创建一个自定义C#控件(窗体的标题栏)。一个表单只能有一个标题栏,这就是为什么我想知道一些事情:当用户(程序员)将我的标题栏添加到他的表单时,是否有任何方法可以检查ParentForm是否已经包含我的标题栏,如果可以的话我取消添加我的控制的另一个实例?检查自定义控件是否已添加到窗体中
我知道如何执行检查以查看ParentForm包含的控件类型,但是当我的控件从工具箱放置到窗体时以及如何在必要时“取消”控件布局时引发了什么事件?
我正在创建一个自定义C#控件(窗体的标题栏)。一个表单只能有一个标题栏,这就是为什么我想知道一些事情:当用户(程序员)将我的标题栏添加到他的表单时,是否有任何方法可以检查ParentForm是否已经包含我的标题栏,如果可以的话我取消添加我的控制的另一个实例?检查自定义控件是否已添加到窗体中
我知道如何执行检查以查看ParentForm包含的控件类型,但是当我的控件从工具箱放置到窗体时以及如何在必要时“取消”控件布局时引发了什么事件?
您应该使用read in-depth关于在.NET中提供的designer technologies,因为这些不是我称之为生产就绪的示例。然而,这给你一个坚实的开始,并且这两个代码片段都能完成你所要求的功能。
对于设计时,可以覆盖设计的网站在你的控制,并做到以下几点:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel.Design;
using System.Diagnostics;
namespace WindowsFormsControlLibrary1 {
public partial class DebugControl : UserControl {
public DebugControl() {
InitializeComponent();
}
public override ISite Site
{
get
{
return base.Site;
}
set
{
base.Site = value;
IComponentChangeService service = (IComponentChangeService)GetService(typeof(IComponentChangeService));
service.ComponentAdding += (sender, e) => {
IDesignerHost host = (IDesignerHost)value.Container;
Component component = (Component)host.RootComponent;
if (component as Form != null)
{
Form form = (Form)component;
foreach (Control c in form.Controls)
{
if (c.GetType() == this.GetType())
{
throw new System.ArgumentException("You cannot add two of these controls to a form!");
}
}
}
};
}
}
}
}
对于您的形式运行时,您可以覆盖OnControlAdded并执行以下操作:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using WindowsFormsControlLibrary1;
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
protected override void OnShown(EventArgs e)
{
Controls.Add(new DebugControl());
}
protected override void OnControlAdded(ControlEventArgs e)
{
base.OnControlAdded(e);
if (e.Control.GetType() == typeof(DebugControl))
{
int count = 0;
foreach (Control c in Controls)
{
if (c is DebugControl)
{
count++;
}
}
if (count > 1)
{
Controls.Remove(e.Control);
Debug.Assert(false, "Cannot add two of these controls!");
}
}
}
}
}
有多种方法可以做到这一点,但这些都是粗糙的例子,介意你。阅读关于.NET框架的设计时支持,它非常丰富,并且有大量文档。另一种方法是实现自定义设计器并实现CanBeParentedTo和CanParent,但是请注意,当您的控件是从ToolBox到您的窗体的药物时,CanBeParentedTo不会被调用。
干得不错,我对此毫不知情! :) tnx – guest86
您可以通过为您的控件和表单实现自定义设计器来实现同样的目的。问题在于表单使用BCL内部的FormDocumentDesigner,因此您必须重新创建相当多的工作。这是一个体面的方法,只需很少的工作。 –
您可以使用Controls
收集有效的form
。
处理ParentChanged
事件,检查父级的Controls
,并在必要时抛出异常。
您是否关注使用设计器或手动添加代码的人? – SLaks
设计师和代码! – guest86