65.9K
CodeProject 正在变化。 阅读更多。
Home

C# ASP.NET 风格的复选框控件

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.09/5 (5投票s)

2006年2月28日

3分钟阅读

viewsIcon

58366

downloadIcon

280

一篇关于创建自定义控件的文章,该控件的行为类似于基于 Web 的电子邮件服务中找到的“全部删除”复选框。

MyCheckBox image

引言

我在一家为大型政府客户提供环境和大气危害评估的小公司工作。对于我开发的一个应用程序,允许用户绘制代表危害的结构,我需要一种方法,让用户从数据记录中删除一个或多个特征。在我看来,最好的方法是模仿 ASP.NET 附带的“全部删除”复选框的行为,该复选框可以在基于 Web 的电子邮件程序中找到。换句话说,我需要能够选择动态列表中的单个项目,或者选择列表中的所有项目。

我绝不是 Web 开发人员(除了一些非常基本的 HTML 和 JavaScript;我一直在开发桌面应用程序),我认为学习 ASP.NET 来完成我应用程序的一小部分工作会过度。而且,冒险使用标准的 CheckBox 控件,除了“全部删除”复选框,似乎也不切实际。因此,我决定编写自己的自定义控件,这将允许我控制哪些项目可以设置为删除,而不必担心“全部删除”复选框的行为出乎意料。

那么,为了您的乐趣,这是我的 MyCheckBox 控件。

使用代码

由于 MyCheckBox 是一个用户控件,您可以将其编译成 DLL 并在您的项目中包含对它的引用。在我的应用程序中,实际上我没有在设计时将控件的实例添加到表单中,但如果需要,您可以这样做。

我在应用程序中放置 MyCheckBox 的表单是一个模态对话框,其使用者调用 AddCheckboxes() 方法,但在这里我将其设置为独立表单。此方法提供 MyCheckBox 的实际格式。

int topLoc = 12;
//Set to next value after highest tab order on form.
int tabIdx = 4;
try
{
    foreach(string s in items)
    {
        //Set the parameters for each of the 
        //MyCheckBoxes that appears on the Form.
        MyCheckBox.MyCheckBox mc = new MyCheckBox.MyCheckBox();
        mc.CanGrow = true;
        mc.CanShrink = true;
        mc.Font = new Font("Microsoft Sans Serif", 
                           10, GraphicsUnit.Point);
        mc.Height = 32;
        mc.Location = new Point(16, topLoc + mc.Height);
        mc.Caption = s.ToString();
        mc.TabStop = true;
        mc.TabIndex = tabIdx;
        mc.BoxCheckedChanged += new 
            MyCheckBox.MyCheckBox.BoxCheckedChangedEventHandler(
            mc_BoxCheckedChanged);
        this.Controls.Add(mc);

        //Set up spacing between boxes.
        topLoc += 28;
        tabIdx++;
    }
}

topLoctabIdx 变量分别用于格式化和制表。我将 28 添加到 topLoc 的值,以便每个 MyCheckBox 在表单上均匀分布。

加载表单后,您可以尝试选中不同的复选框以观察控件及其父表单的行为。

当用户单击“确定”按钮并确认删除时,将调用 GetNewList() 方法来收集未删除的项目,以供父表单使用。

ArrayList retval = new ArrayList();

try
{
    for(int i = 0; i < this.Controls.Count; i++)
    {
        if(this.Controls[i].GetType() == typeof(MyCheckBox.MyCheckBox))
        {
            MyCheckBox.MyCheckBox mc = 
                      (MyCheckBox.MyCheckBox)this.Controls[i];
            if(!mc.BoxChecked) retval.Add(mc.Caption);
        }
    }
}
catch(Exception e)
{
    MessageBox.Show("Error in " + e.TargetSite + ":  " +
                                  e.Message);
    retval = null;
}
            
//The ArrayList is returned for further 
//processing prior to dismissal of the dialog.
return retval;

正如您所看到的,它是一个相当简单的控件。我欢迎任何关于改进的建议。

关注点

我想要实现的一个功能是,MyCheckBox 控件能够根据其中显示的文本的大小进行增长或收缩。我看到的最好方法是指定控件的尺寸行为应该是什么。正如您从第一个代码片段(上面)中看到的那样,每次实例化控件时,我都将 CanShrinkCanGrow 属性设置为 true。这样,控件的大小将根据其 Caption 属性中存储的文本而改变。当调用 Caption 属性的 set 块时,我启动一个名为 ChangeSize 的方法。

//Pad the edges of the control.
int height = (textHeight * 2) + 
             Convert.ToInt32(checkBox.Font.Size);
int width = textWidth + 
            Convert.ToInt32(checkBox.Font.Size * 2) + 
    (inputtext.Length * 10);

bool changeHeight = false;
bool changeWidth = false;

//Both of these are necessary in order 
//to reflect the user's selection
//at design time. For example, the user 
//might want the control to expand
//to fit text that is larger than 
//the designed size but not to shrink below it.

if(CanGrow)
{
    if(height > this.Height) changeHeight = true;
    if(width > this.Width) changeWidth = true;
}
            
if(CanShrink)
{
    if(height < this.Height) changeHeight = true;
    if(width < this.Width) changeWidth = true;
}

if(changeHeight) this.Height = height;
if(changeWidth) this.Width = width;

该方法将控件的大小与输入文本的长度(以像素为单位,我认为)进行比较。然后,它会根据实例化时设置的选项来缩小或增大控件。

如果有人知道更好的方法来测试输入文本的大小,因为 .NET 似乎在点和像素之间进行某种内部转换,请告诉我。

历史

  • 2006 年 2 月 27 日 - 文章的初稿。
© . All rights reserved.