Asp.net中模仿Winform的MessageBox

版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。 http://www.cnblogs.com/jintan/archive/2008/10/25/1319308.html

      早晨不经意间看到园子里 Bēniaǒ同学的《由var js = confirm("确认操作?");引发的技术难题》的文章,给我的第一感觉就是:哦,原来有这么多人希望在webform中使用messageBox就像Winform中调用一样方便。我一直以为没有多少人去关注这么一个小小的细节问题的,一年前正是因为我有同样的想法,所以就决定做成服务器端控件,方便以后的项目中复用。

     首先看看WinForm中的MessageBox.Show():

DialogResult result  =  MessageBox.Show( " 确定删除吗? " " 提示 " , MessageBoxButtons.YesNo, MessageBoxIcon.Information);
if  (result  ==  DialogResult.Yes)
{
    
// 相应的逻辑处理
}
else
{
    
// 相应的逻辑处理
}

 

      由于Winform中调用MessageBox.Show的时候会引起主线程挂起,直到用户确认后才执行下面的代码,而在javascript的windown.confirm()同样可以实现这个功能,
if(window.confirm("你确定删除吗?"))
{
     .....
}

     如果要在服务器端来实现,只需要用RegisterClientScriptBlock()注册客户脚本就可以了。
现在又遇到2个问题:
客户端点击“确定”或“取消”的时候,服务器端如何接收?有人说利用__dopostback('',''),没错,但是我们总不能在每个页面都手工去写这样的代码吧?那就得封装成自定义控件吧,只需实现IPostBackEventHandler接口。
客户端show出confirm()消息对话框后,只是让客户端的当前浏览器的主线程阻塞,并不会使服务器端的主线程阻塞,这是肯定的!这也是我们遇到的最大难题,既然我们不能阻塞服务器端的主线程,那我们能不能提供另一种代替的方式呢?就像下面的这段C#代码:

         protected   void  Button1_Click( object  sender, EventArgs e)
        {
            
// MsgBox是我们封装的服务器控件
            MsgBox.Show( " 需要删除吗? " , (mSender, arg)  =>
              {
                  
if  (arg.Result  ==  DialogResult.Yes)
                  {
                      Label1.Text 
=   " OK,服务器端执行的逻辑结果 " ;
                  }
                  
else
                  {
                      Label1.Text 
=   " No,服务器端执行的逻辑结果 " ;
                  }
              }
            );

        }

Show()方法的原型:

///   <summary>
///  客户端显示confirm的消息框
///   </summary>
///   <param name="message"> 消息内容 </param>
///   <param name="Message"> 回传后处理的委托. </param>
public   void  Show( string  message, Message objEventHandler)

 

       实际上就是,在Show的第2个参数传递一个委托,其返回值包含在arg中,说白了就是一个回调方法,该方法只有在客户端点击了“确定”或 “取消”后触发。这样客户端点击确定或取消时,把点击的结果值回传到服务器端,服务器端判断并做相应的处理就OK了。这样又带来了另一个问题,这个委托到底是保存在ViewState中还是Session中??如果保存在ViewState,就会涉及到序列化、反序列化的问题,委托是可以序列化的,但是不能保证其引用的对象可以序列化啊(即.Target有可能是Page等,这种不能序列化的对象),而且很多对象放入ViewState中效率的确有点差。如果用Session呢?虽然能避免序列化带来的问题,但是就涉及到Session的键名的问题,因为要确保页面上的每个独立的控件键名不能重复,否则会引发很多问题。

 

        public   delegate   void  Message( object  sender, MessageBoxEventHandler e);
        
// 回调处理的委托
         private  Message MessageBoxCallBack
        {
            
get
            {
                
return   this .Page.Session[GetSessionKey( " MessageBoxCallBack " )]  as  Message;
            }
            
set
            {
                
if  (value  ==   null )
                {
                    
this .Page.Session.Remove(GetSessionKey( " MessageBoxCallBack " ));
                }
                
else
                {
                    
this .Page.Session[GetSessionKey( " MessageBoxCallBack " )]  =  value;
                }
            }
        }

        
// 产生一个控件唯一的Session键
         private   string  GetSessionKey( string  key)
        {
            
return  key  +   this .Page.GetType().FullName  +   this .ClientID;
        }

 

    这样,主要问题就基本解决了。希望大家多提意见。

Updated:2008-10-25,修改了Session key的获取方法,对于不同页面的分配不同的key

ContractedBlock.gif ExpandedBlockStart.gif Code
        //回调处理的委托
        private Message MessageBoxCallBack
        {
            
get
            {
                
return this.Page.Session[GetSessionKey("MessageBoxCallBack")] as Message;
            }
            
set
            {
                
if (value == null)
                {
                    
this.Page.Session.Remove(GetSessionKey("MessageBoxCallBack"));
                }
                
else
                {
                    
this.Page.Session[GetSessionKey("MessageBoxCallBack")] = value;
                }
            }
        }

        
private string PageIdentify
        {
            
get
            {
                
if (ViewState["PageIdentify"]==null)
                {
                    ViewState[
"PageIdentify"= System.Guid.NewGuid().ToString();
                }
                
return ViewState["PageIdentify"].ToString();
            }
        }

        
//产生一个控件唯一的Session键
        private string GetSessionKey(string key)
        {
            
return key + PageIdentify + this.ClientID;
        }


demo演示地址:http://www.webcontrols.com.cn/msg/
源码下载:http://files.cnblogs.com/jintan/TestMessageBox.rar

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值