在C#中制作组合控件

时间:2021-08-20 06:24:54

C#中制作组合控件

丽水市汽车运输集团有限公司信息中心 苟安廷


我们通常通过文本框、组合框等控件获取用户的数据输入,为告诉用户当前需要输入的内容,通常还要在上面加一个提示用的标签,如:
姓名

张三

 

 

如果窗体上待输入的内容很多,则要同时放大量标签,不仅工作量大,还不易于排版,本文介绍如何制作一个组合控件以简化操作,也就是将上面的标签和文本框做成一个整体,文本框移动时标签跟着移动,还可以设置提示用标签的位置、内容、字体、颜色等。

打开VS2003,新建一个windows控件库(不是windows项目),不妨取名为MultiControls吧。

将下面的代码:

    public class UserControl1 : System.Windows.Forms.UserControl

    {

       private System.ComponentModel.Container components = null;

       public UserControl1()

       {

修改为:

    public class TextBoxExt : System.Windows.Forms.TextBox

    {

       private System.ComponentModel.Container components = null;

 

       public TextBoxExt()

       {

也就是将默认的控件名称UserControl1修改为TextBoxExt,同时将基类修改为TextBox,表示该控件继承自TextBox

单击菜单“项目”→“属性”,在“配置”后的组合框中选择“所有配置”,点“配置属性”下的“生成”,为输出路径指定一个目录,也就是无论是Debug版还是Release版,都输出到同一个目录中,便于后面的引用,如下图所示:

在C#中制作组合控件编译一下,保证程序没有错误。Windows控件是无法直接调试的,为了调试方便,我们要新建一个windows项目。

单击菜单“文件”→“添加项目”→“新建项目”,选择“Windows 应用程序”,不妨取名为TestTextBox,并将该项目设为启动项目。单击菜单“项目”→“项目依赖项”,设置项目TestTextBox依赖于Multicontrols,如下图:

在C#中制作组合控件
切换到工具箱面板的“常规”选项卡中,点鼠标右键,选择“添加
/移除项”,打开自定义工具箱对话框,切换到“.Net FrameWork组件”,点“浏览”按钮,找到刚才编译生成的MultiControls.dll,选择后点“确定”按钮,此时工具箱中就有了自定义控件“TextBoxExt”,切换到TestTextBox项目的Form1窗口,随便拖几个放到窗口上,可以看到,目前的TextBoxExt同标准的TextBox控件没有什么区别,因为我们还没有开始编写代码。

切换到TextBoxExt的代码窗口中(以下大部分代码均指该窗口中的代码,特殊说明除外)。

先创建一个提示用的标签(Label),由于需要一些初始信息,我们先将创建过程空着。

       private System.Windows.Forms.Label m_lblPrompt=null;

       private System.Windows.Forms.Label myPrompt

       {

           get

           {

              //如果提示用的标签,没有则创建一个

              if((m_lblPrompt==null) && this.Parent!=null)

              {

                  //创建过程就在后面的补上

              }

              return m_lblPrompt;

           }

       }

添加一个变量,表示文本框和Label之间的位置关系。

       private System.Drawing.ContentAlignment m_lblPromptAlignment=System.Drawing.ContentAlignment.TopLeft;

       public System.Drawing.ContentAlignment LabelAlignment

       {

           get

           {

              return m_lblPromptAlignment;

           }

           set

           {

              m_lblPromptAlignment=value;

              this.LayoutCtrls();

           }

       }

上面代码中用到了一个函数this.LayoutCtrls(),表示如何具体实现文本框和标签的位置关系,代码如下:

       private void LayoutCtrls()

       {

           //根据提示文本的排列位置设置提示文本的位置

           Label lbl=myPrompt;

           if(lbl!=null)

           {

              switch(m_lblPromptAlignment)

              {

                  case System.Drawing.ContentAlignment.BottomCenter:

                     lbl.Top=this.Bottom;

                     lbl.Left=this.Left+(this.Width-lbl.Width)/2;

                     break;

                  case System.Drawing.ContentAlignment.BottomLeft:

                     lbl.Top=this.Bottom;

                     lbl.Left=this.Left;

                     break;

                  case System.Drawing.ContentAlignment.BottomRight:

                     lbl.Top=this.Bottom;

                     lbl.Left=this.Right-lbl.Width;

                     break;

 

                  case System.Drawing.ContentAlignment.MiddleCenter:

                  case System.Drawing.ContentAlignment.TopCenter:

                     lbl.Top=this.Top-lbl.Height;

                     lbl.Left=this.Left+(this.Width-lbl.Width)/2;

                     break;

                  case System.Drawing.ContentAlignment.TopLeft:

                     lbl.Top=this.Top-lbl.Height;

                     lbl.Left=this.Left;

                     break;

                  case System.Drawing.ContentAlignment.TopRight:

                     lbl.Top=this.Top-lbl.Height;

                     lbl.Left=this.Right-lbl.Width;

                     break;

                  case System.Drawing.ContentAlignment.MiddleLeft:

                     lbl.Left=this.Left-lbl.Width;

                     lbl.Top=this.Top+(this.Height-lbl.Height)/2;

                     break;

                  case System.Drawing.ContentAlignment.MiddleRight:

                     lbl.Left=this.Right;

                     lbl.Top=this.Top+(this.Height-lbl.Height)/2;

                     break;

              }

           }

 

       }

设置标签的内容:

         private string m_lblText="";

       public string LabelText

       {

           get

           {

              return this.m_lblText;

           }

           set

           {

              m_lblText=value;

              Label lbl=myPrompt;

              if(lbl!=null )

              {

                  lbl.Text=m_lblText;

                  LayoutCtrls();

              }

           }

       }

有了上面的准备,接下来我们来完成前面空着的创建Label的具体过程:

       private System.Windows.Forms.Label myPrompt

       {

           get

           {

               //如果提示用的标签,则创建一个

              if((m_lblPrompt==null) && this.Parent!=null)

              {

                  m_lblPrompt=new Label();

                  m_lblPrompt.Visible=true;

                  m_lblPrompt.AutoSize=true;

                  m_lblPrompt.BackColor= System.Drawing.Color.Transparent;

                  m_lblPrompt.Text=this.LabelText;

                  this.Parent.Controls.Add(m_lblPrompt);

                  this.Parent.ResumeLayout(false);

 

              }

              return m_lblPrompt;

           }

       }

可以参照LabelText的方法为标签设置前景、背景、字体等等。

重新编译一下解决方案,切换到TestTextBox项目的Form1窗口上,选中一个刚才添加的控件,在属性窗口中应该有LabelText属性了,如果没有找到,关闭解决方案后再重新打开一次,在属性窗口中修改一下LabelText属性的内容,看看窗口上的文本框上面是不是自动出现了提示?

同样,你还可以设置LabelAligment,调整提示标签和文本框之间的排列关系,如果移动文本框,发现标签不会跟着移动,下面我们来实现该功能。

切换到TextBoxExt的设计窗口,在属性窗口中切换到“事件”选项,双击LocationChanged事件,自动会在代码窗口中添加响应代码,为保证文本框大小改变后,不影响标签和文本框的排列,在属性窗口中找到Resize事件,此时不要双击,而是从右边的下拉框中选择刚才添加的LocationChanged事件,这样,两个事件对应同一段代码,编写的代码如下:

       private void TextBoxExt_LocationChanged(object sender, System.EventArgs e)

       {

           this.LayoutCtrls();

       }

添加文本框的Visablechanged事件如下:

       private void TextBoxExt_VisibleChanged(object sender, System.EventArgs e)

       {

           Label lbl=myPrompt;

           if(lbl!=null)

           {

              lbl.Visible=this.Visible;

              this.LayoutCtrls();

           }

       }

在设计时,如果一个文本框多余了,需要删除,此时,应该同时删除对应的标签,因此,修改Dispose函数如下:

       protected override void Dispose( bool disposing )

       {

           if( disposing )

           {

              //释放提示标签

              Label lbl=myPrompt;

              if(lbl!=null)

                  lbl.Dispose();

              if( components != null )

                  components.Dispose();

           }

           base.Dispose( disposing );

       }

到此为止,一个组合控件就完成了,你还可以根据需要制作ComboBoxExt等,也可以将更多的控件组合成一个。

本文的代码可以到ftp://202.107.251.26/下“苟安廷”文件夹中下载,文件名为“组合控件.rar”。