ModalPopupExtender控件学习笔记


ModalPopupExtender控件主要有两种使用方式:客户端使用方式和服务器端使用方式。这两种使用方式在ModalPopup的官方例子中都有介绍。
1、客户端使用方式
客户端使用方式又可以分为两种
A.直接设置OKControlID的方式
ModalPopupExtender控件在使用时必须要设置TargetControlID和PopupControlID这两个属性,我的理解是,对于ExtenderControl而言TargetControlID属性必须指定,否则就不知道在哪个DOM元素上附加客户端行为了。PopupControlID表示要弹出的仿模式窗口的DOM元素,常见的是Panel控件,这个如果不指定,也没有意义。有时,在执行上下文中可能要在确认这个模式窗口时,执行一些脚本,则可以设置OnOKScript属性,指明确认时要执行的脚本函数。
B.获取一个ModalPopupBehavior实例的方式。
如果页面上放置了ModalPopupExtender控件则可以用$find方法得到一个ModalPopupBehavior实例,这样就可以调用ModalPopupBehavior实例的任何方法了,如hide、show等,此时客户端的行为可以完全自己控制了。这种情况下ModalPopupExtender控件必须要设置BehaviorID属性,否则无法用$find方法来获取ModalPopupBehavior实例。
有时,我们会感觉直接调用ModalPopupBehavior实例的方法比较麻烦,可以给ModalPopupBehavior实例添加一些事件,以方便我们添加一些自定义控制,如下图,
我们在编辑一个文本框的内容时,在模式窗弹出之后,同时让CheckBox选中文本框中的值,这是需要一个OnAfterShown事件。有时在点击确认时,需要验证录入数据的正确性,需要一个OnBeforeOK事件,如果验证不能通过就取消提交。要实现这样的功能我们需要给ModalPopupExtender控件添加相应属性,我们以OnBeforeOK事件为例说明具体步骤:
第一步,给ModalPopupExtender控件添加OnBeforeOK属性
/// <summary>
/// 确认之前发生的事件
/// </summary>
[DefaultValue("")]
[ExtenderControlEvent]
[ClientPropertyName("beforeOK")]
public string OnBeforeOK
{
    get { return GetPropertyValue("OnBeforeOK", string.Empty); }
    set { SetPropertyValue("OnBeforeOK", value); }
}
这里要注意ExtenderControlEvent Attribute的使用。
第二步,给ModalPopupBehavior添加相应方法,来订阅、取消相应事件,及触发事件的方法。
add_beforeOK: function(handler) {
    this.get_events().addHandler('beforeOK', handler);
},
remove_beforeOK: function(handler) {
    this.get_events().removeHandler('beforeOK', handler);
},
raiseBeforeOK: function(eventArgs) {
    var handler = this.get_events().getHandler('beforeOK');
    if (handler) {
        handler(this, eventArgs);
    }
},

第三步,修改相应方法的代码,触发事件
_onOk: function(e) {
    var element = $get(this._OkControlID);
    if (element && !element.disabled) {
        var eventArgs = new Sys.CancelEventArgs();
        this.raiseBeforeOK(eventArgs);
        if (!eventArgs.get_cancel()) {
            if (this.hide() && this._OnOkScript) {
                window.setTimeout(this._OnOkScript, 0);
            }
            e.preventDefault();
            return false;
        }
    }
},
这里修改了_onOk方法,也可以根据情况修改其他方法。
第四步,使用ModalPopupExtender控件时,为OnBeforeOK属性赋值,此属性为一个脚本函数。这个函数中,我们可以执行args.set_cancel(true);从而阻止hide方法和OnOkScript脚本的执行。
客户端使用的方式可以任意发挥,OnOKScript属性挂接的函数完全可以使用Sys.Net.WebRequest发起异步请求,获取服务器端的信息。
2、服务器端使用方式
这种方式与传统的服务器控件的使用方式相同,就是直接调用ModalPopupExtender控件的Show()方法和Hide()方法来控制模式窗口的现实与隐藏,其实也是通过在客户端生成这样一句脚本来实现的:
(function() {
    var fn = function() {
    AjaxControlToolkit.ModalPopupBehavior.invokeViaServer('programmaticModalPopupBehavior', true);
    Sys.Application.remove_load(fn);
    };
    Sys.Application.add_load(fn);
})();
在服务器端调用ModalPopupExtender控件的Show()方法或Hide()方法有个缺点,就是会引起回发,用户体验不好。我们可以将弹出的模式窗口(一个panel控件)放到一个UpdatePanel控件中,并将触发按钮注册为异步回发按钮来改善用户体验。一个常见的例子是GridView配合FormView或者 DetailView进行业务对象的修改,页面数据用GridView显示,修改时,用模式窗弹出一个FormView,修改完毕保存到数据库,并更新GridView(当然就地编辑的话,直接用UpdatePanel即可)。 具体实现步骤如下:
第一步:建立GridView
<asp:UpdatePanel UpdateMode="Conditional" ID="upXXXXX" runat="server">
<ContentTemplate>

<xx:XXGridView id="gvDDDDDD" runat="server" DataKeyNames="Id" AllowSorting="True" skinid="PagingGridView" DataSourceID="ods" EnableViewState="False">
   <Columns>
       <asp:BoundField DataField="CreatedDate" HeaderText="XXXXXX" SortExpression="CreatedTime" />
       <asp:BoundField DataField="CreatedBy" HeaderText="CCCCCC" SortExpression="CreatedBy" />
       <asp:BoundField DataField="Name" HeaderText="CCCCC" />
       <asp:BoundField DataField="Comment" HeaderText="CCCCCC" />

       <asp:TemplateField><ItemTemplate>
<asp:LinkButton id="btnEdit" runat="server" CommandName="Select" OnClick="btnEdit_Click">编辑</asp:LinkButton>
</ItemTemplate></asp:TemplateField>
       <asp:CommandField ShowDeleteButton="True" DeleteText="删除" />
   </Columns>
</xx:XXGridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnSave" />
<asp:AsyncPostBackTrigger ControlID="btnOK" />
</Triggers>
</asp:UpdatePanel>

<asp:ObjectDataSource id="ods" runat="server" EnablePaging="True"
TypeName="XXXXXX"
SelectMethod="GetPaged" SelectCountMethod="GetCount"
SortParameterName="sortExpression"
DeleteMethod="DeleteById">
    <SelectParameters>      
        <huag:WhereClauseParameter Name="whereClause" QueryStringField="id" Type="String" DataField="XXId"></huag:WhereClauseParameter>
    </SelectParameters>
</asp:ObjectDataSource>

第二步:建立弹出的层,仿模式窗口
<asp:Panel ID="pnlPopup" runat="server" CssClass="x-pne" Width="460px" style="display:none;">
<asp:UpdatePanel ID="updDetail" runat="server" UpdateMode="Conditional">
<ContentTemplate>

<asp:Button id="btnShowPopup" runat="server" style="display:none" />
<ajaxToolKit:ModalPopupExtender ID="mdlPopup" runat="server"
    BehaviorID="xxxEdit"
    TargetControlID="btnShowPopup"
    PopupControlID="pnlPopup"
    CancelControlID="btnClose" BackgroundCssClass="modalBackground"
    PopupDragHandleControlID="pnlDrag"
/>
    <asp:Panel ID="pnlDrag" runat="server" CssClass="corner-bg x-pne-lt x-pne-left dragTitle">
         <div class="corner-bg x-pne-rt x-pne-right">
              <div class="corner-bg x-pne-t">
                   <div class="x-pne-btn" οnclick="$find('xxxEdit').hide();"></div>
                   <div class="x-pne-caption font dragTitle"><span>标题</span></div>
              </div>
         </div>
     </asp:Panel>

     <div class="side-bg x-pne-l">
         <div class="side-bg x-pne-r">
              <div class="x-pne-c" style="width: 448px; height: 300px">
                   <div id="contentPanel" style="padding-left:10px;"><br />
                  
                   这里是FormView的内容,完全可以使用一个FormView控件,这里没有给出
                    <table width="100%">
                        <tr>
                            <td style="width: 100px">内容1</td><td><asp:TextBox ID="txtEdit1" runat="server" CssClass="textField text-bg border-blur" Width="90%"></asp:TextBox></td>
                        </tr>
                        <tr>
                            <td style="width: 100px">内容2</td><td><asp:TextBox ID="txtEdit2" runat="server" CssClass="text-bg border-blur" TextMode="MultiLine" Rows="14" Width="92%"></asp:TextBox></td>
                        </tr>
                        <tr >
                            <td colspan="2" align="center" style="padding-top:10px;">
                            <table width="60%" >
                            <tr align="center">
                            <td>
                                <div class="btn-side btn-bg"></div>
                                <div class="btn-body btn-bg" style="background-position: 0px 168px; width: 66px"><asp:Button ID="btnOK" runat="server" Text=" 确定 " CssClass="font" OnClick="btnOK_Click" /></div>
                                <div class="btn-side btn-bg" style="background-position: 0px 189px"></div>
                            </td>
                            <td>
                                <div class="btn-side btn-bg"></div>
                                <div class="btn-body btn-bg" style="background-position: 0px 168px; width: 66px"><asp:Button ID="btnClose" runat="server" Text=" 取消 " CssClass="font" /></div>
                                <div class="btn-side btn-bg" style="background-position: 0px 189px"></div>
                            </td>
                            </tr>
                            </table>
                           </td>
                        </tr>
                    </table>

<br />
                    </div>
              </div>
         </div>
     </div>

     <div class="corner-bg x-pne-lb x-pne-left">
         <div class="corner-bg x-pne-rb x-pne-right">
              <div class="corner-bg x-pne-b"></div>
         </div>
     </div>

</ContentTemplate>                
</asp:UpdatePanel>
</asp:Panel>
每一个ExtenderControl都需要挂靠一个Dom元素,<asp:Button id="btnShowPopup" runat="server" style="display:none" />就是起这个作用,其本身没有意义,所以这里要隐藏之。
第三步:写编辑按钮的代码btnEdit_Click,弹出模式窗口
// 得到GridView当前行的信息,更新FormView上相应控件的值,或者FormView.databind。
。。。。。。其他语句
updPnlDetail.Update();
mdlPopup.Show();
第四步:弹出窗口编辑完成保持时的代码 btnOK
// 保存修改,更新到数据库
gvDDDD.DataBind();// 同时更新到界面。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值