Winform自定义MessageBox

来源:互联网 发布:埙淘宝 编辑:程序博客网 时间:2024/05/16 09:17

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

程序下载:点击打开链接

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

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


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

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


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


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



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

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


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();}

0 0
原创粉丝点击