日期:2014-05-17 浏览次数:21282 次
上一篇博客里说到,当我们编写一个控件直接继承于Control,并且里面Add了一个ComboBox的时候的问题。
今天继续接着这个说。
有的人可能会觉得奇怪,自定义控件不是直接新建一个UserControl就好了吗,干嘛用代码直接写,直接继承Control?
这个我就不多说了,总之制作自定义控件不光可以使用UserControl。有的时候用Control会更好一些。
那么今天的问题是,当我们按照以下的代码写了一个控件,并且将之拖到到窗体上的时候,我们会发现。
即使在设计试图下(还没有运行程序的时候),我们的鼠标也依然可以直接点进这个Control里的ComboBox。并且还可以用键盘输入值。
这个是非常诡异的一个表现,如果你是要做控件给别人用的话,这个现象就会显示出你不够专业。
示例代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Data;
using System.ComponentModel;
namespace WindowsFormsApplication1
{
public class TestComboBox : Control
{
private ComboBox m_combo;
public Control GetInnerControl()
{
return m_combo;
}
public TestComboBox()
{
//创建一个comboBox
m_combo = new ComboBox();
m_combo.Size = new System.Drawing.Size(100, 20);
m_combo.Location = new System.Drawing.Point(0, 0);
m_combo.FormattingEnabled = true;
m_combo.Name = "comboBox1";
m_combo.TabIndex = 0;
//构造用于绑定到comboBox的DataSource的假数据
DataTable table = new DataTable();
table.Columns.Add("code");
table.Columns.Add("name");
table.Rows.Add("1", "AA");
table.Rows.Add("2", "BB");
//设定绑定方式
m_combo.DataSource = table;
m_combo.DisplayMember = "name";
m_combo.ValueMember = "code";
this.Controls.Add(m_combo);
}
}
}

嗯,非常神奇的一个效果。但是这并不是我们想要的。
该怎么解决这个问题呢?
这个是属于设计视图下的问题,对程序实际运行起来之后,并没有什么影响。
所以我们该从设计器下手,替换掉微软默认的设计器。
我们为这个TestComboBox类指定一个设计器。
添加
[Designer(typeof(TestDesigner))]
如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Data;
using System.ComponentModel;
namespace WindowsFormsApplication1
{
[Designer(typeof(TestDesigner))]
public class TestComboBox : Control
{
private ComboBox m_combo;
public Control GetInnerControl()
{
return m_combo;
}
...
接着,新建一个类,写下如下代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
namespace WindowsFormsApplication1
{
public class TestDesigner : System.Windows.Forms.Design.ControlDesigner
{
Control mask = new Control();
public override void Initialize(IComponent component)
{
base.Initialize(component);
if (this.Control is TestComboBox)
{
Control p = mask.Parent;
mask.Parent = (this.Control as TestComboBox).GetInnerControl();
}
}
protected override void OnPaintAdornments(PaintEventArgs pe)
{
base.OnPaintAdornments(pe);
if (this.Control is TestComboBox)
{
if ((this.Control as TestComboBox).GetInnerControl().Enabled == false)
{
mask.Dispose();
}
}
}
}
}
然后将控件的设计器指定成它。
现在编译,关掉窗体设计视图,再打开
现在是不是已经不会让焦点进去其中了呢?
转摘请注明出处