Winform自定义MessageBox

       在使用Winform的MessageBox作为消息提示时,会有一些不方便的地方。如,MessageBox消息框弹出之后,如果不关闭就会阻塞函数的继续执行;不能自动关闭等。因此,子丰就自己仿照MessageBox的样式写了一个InformationBox提示框,可以实现自动关闭、永远显示在所有窗口的最上方等。首先,贴出几张图片展示一下InformationBox的效果;然后,具体介绍InformationBox的实现方式。

程序下载:点击打开链接

http://download.csdn.net/detail/softimite_zifeng/9731930

1. InformationBox增加了自动关闭功能。消息框的右下角会进行倒计时,倒计时时间可以根据自己的需要设定。倒计到0时,消息框自动关闭。当然,在倒计时的过程中,单击“确定”按钮或窗口关闭按钮,同样能够关闭消息框。

Winform自定义MessageBox_第1张图片 Winform自定义MessageBox_第2张图片

2. InformationBox对“确定”按钮设置了快捷键Ctrl+O。也就是说只需要按下Ctrl+O就相当于单击了“确定”按钮。

3. InformationBox的倒计时实现暂停和开始。只需要双击右下角的暂停或开始按钮即可。这样方便用户有足够的时间对较长或较复杂的提示消息进行查看。

Winform自定义MessageBox_第3张图片 Winform自定义MessageBox_第4张图片

4. 和MessageBox一样,InformationBox可以更改消息框显示的图标,包括消息、错误、询问、警告这4种图标。并 且根据不同的图标,在消息框弹出时,其提示音也不同。

Winform自定义MessageBox_第5张图片Winform自定义MessageBox_第6张图片 Winform自定义MessageBox_第7张图片

5. InformationBox能够根据标题和内容的长度的增大,自动改变提示框的宽度;并且当内容的长度增大一定程度时,能够实现自动转行。基本做到了与MessageBox无差别。

Winform自定义MessageBox_第8张图片 Winform自定义MessageBox_第9张图片

Winform自定义MessageBox_第10张图片 Winform自定义MessageBox_第11张图片

下面具体介绍一下InformationBox的实现方式:

1. 新建Windows窗口,进行如下的设计。

Winform自定义MessageBox_第12张图片

2. 实现“确定”按钮的快捷方式Ctrl+O。只需要给窗口在的KeyPress事件中编写即可,注意,这里需要将窗口的KeyPreview属性设置为True,否则,无法检测到键盘按下Ctrl+O。

//快捷键
private void InformationBox_KeyPress(object sender, KeyPressEventArgs e)
{
    e.Handled = true;
    if (e.KeyChar == 15) //确定:Ctrl + O
    {
        OKButton.PerformClick();
    }
}
3. 定义一个枚举(InformationBoxIcon)用于图标的选择。

//图标
public enum InformationBoxIcon
{
    Error = 0,          //错误
    Information = 1,    //消息
    Question = 2,       //询问
    Warning = 3         //警告
}
4. 使用线程自动关闭提示框,定义线程函数autoCloseThread。

//自动关闭线程
private void autoCloseThread(object timeObj)
{
    try
    {
        int time = 10 * 5;       //默认时间
        try
        {
            time = (int)timeObj * 5;
        }
        catch
        {
            time = 10 * 5;
        }
        while (time > 0)
        {
            if(!pause)
            {
                Thread.Sleep(200);
                time--;
                //更新倒计时
                if (time % 5 == 0)
                {
                    TimeLab2.Invoke((EventHandler)(delegate
                    {
                        TimeLab2.Text = (time / 5).ToString();
                    }));
                }
            }
        }
        //Thread.Sleep(1000);
        TimeLab3.Invoke((EventHandler)(delegate
        {
            TimeLab1.Visible = false;
            TimeLab2.Visible = false;
            TimeLab3.Visible = false;
            TimeLab4.Visible = true;
        }));
        Thread.Sleep(500);
        this.Invoke((EventHandler)(delegate
        {
            autoclose = true;   //自动关闭
            this.Close();
        }));
    }
    catch { }
}
5. 重写窗口InformationBox的Show函数,实现窗口的布局以及自动关闭线程。

//显示
public void Show(IWin32Window owner, string text = "", string caption = "", InformationBoxIcon icon = InformationBoxIcon.Information, int secondsTimeout = 10)
{
    if (text == null)
        text = "";
    if (caption == null)
        caption = "";
    if (secondsTimeout < 2)     //最小倒计时为2
        secondsTimeout = 2;
    if (secondsTimeout > 99)     //最大倒计时为99
        secondsTimeout = 99;
    //提示框的宽和高
    testLab.Text = caption;     //标题长度比较
    int width = 206;
    width = (testLab.Width + 50 > width) ? testLab.Width + 50 : width;      //最小宽度为206
    testLab.Text = "";
    this.Text = caption;
    width = (width < 498) ? width : 498;        //最大宽度为498
    InformationTxt.Text = text;
    width = (498 - 380 + InformationTxt.Width > width) ? 498 - 380 + InformationTxt.Width : width;      //内容长度比较。这里不需要比较最大宽度,由于InformationTxt设置了最大宽度390
    int height = 188;
    if (InformationTxt.Height / 17 > 2)     //最小高度为188
    {
        height += 17 * (InformationTxt.Height / 17 - 2);    //内容高度比较
    }
    this.Size = new System.Drawing.Size(width, height);     //重绘提示框大小
    //倒计时
    TimeLab2.Text = secondsTimeout.ToString();
    //按钮提示
    OKTip.SetToolTip(OKButton, OKButton.Text + "  快捷键: Ctrl+O");    //Ctrl+O:15
    PauseTip.SetToolTip(PausePb, "双击暂停倒计时");
    //图标,提示音
    if(icon == InformationBoxIcon.Error)
    {
        IconPb.Image = Properties.Resources.ErrorIcon;
        System.Media.SystemSounds.Hand.Play();
    }
    else if (icon == InformationBoxIcon.Information)
    {
        IconPb.Image = Properties.Resources.InformationIcon;
        System.Media.SystemSounds.Asterisk.Play();
    }
    else if (icon == InformationBoxIcon.Question)
    {
        IconPb.Image = Properties.Resources.QuestionIcon;
        System.Media.SystemSounds.Beep.Play();
    }
    else if (icon == InformationBoxIcon.Warning)
    {
        IconPb.Image = Properties.Resources.WarningIcon;
        System.Media.SystemSounds.Exclamation.Play();
    }
    //显示在所有窗体的最上方
    this.TopMost = true;
    //弹出提示框
    base.Show(owner);
    //开启倒计时
    timeoutThread = new Thread(autoCloseThread);
    timeoutThread.IsBackground = true;
    timeoutThread.Start(secondsTimeout);
}
6. 实现双击暂停或开始倒计时。

//双击暂停或开始
private void pausePb_DoubleClick(object sender, EventArgs e)
{
    //判断当前状态是否暂停
    if (pause)
    {
        pause = false;
        PausePb.Image = Properties.Resources.PauseIcon;
        PauseTip.RemoveAll();
        PauseTip.SetToolTip(PausePb, "双击暂停倒计时");
    }
    else
    {
        pause = true;
        PausePb.Image = Properties.Resources.StartIcon;
        PauseTip.RemoveAll();
        PauseTip.SetToolTip(PausePb, "双击开始倒计时");
    }
}

7. 编写窗口的FormClosing事件。当倒计时还没有结束时关闭窗口,就将自动关闭窗口线程杀死。

//关闭的操作
private void InformationBox_FormClosing(object sender, FormClosingEventArgs e)
{
    if (timeoutThread != null)
    {
        if (timeoutThread.IsAlive && !autoclose)
        {
            try
            {
                timeoutThread.Abort();
            }
            catch { }
        }
    }
    this.Dispose();
}

你可能感兴趣的:(程序)