从 GridView 事件获取模态显示的问题

Posted

技术标签:

【中文标题】从 GridView 事件获取模态显示的问题【英文标题】:Problem getting modal to display from GridView event 【发布时间】:2021-08-30 15:24:51 【问题描述】:

在任何人说之前,我已经尝试了所有我能找到的示例,但到目前为止似乎没有任何效果,所以我发布了一个新问题。

我正在处理一个 ASP.NET Web 表单项目,并且我有一个包含 GridView 控件的页面,该控件为每个记录提供多个命令按钮,代表不同的选项。其中之一是“订阅”,我想用它在引导模式对话框中显示订阅记录的详细信息。我将模态对话框代码精简到最低限度:

        <asp:Panel ID="pnlSubscriptionPopUp" runat="server" Visible="false">
            <div id="SubscriptionPopUp" class="modal fade" role="dialog">
                <div class="modal-dialog modal-dialog-scrollable modal-dialog-centered modal-lg">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h4 class="modal-title">Subscription Details</h4>
                        </div>
                        <div class="modal-body">
                            
                        </div>
                        <div class="modal-footer">
                            <button id="Button1" runat="server" onclick="btnCancel_Click" cssclass="btn btn-primary">Cancel</button>
                            <button id="btnClose" class="btn btn-success">Close</button>
                        </div>
                    </div>
                </div>
            </div>
        </asp:Panel>

这是我正在使用的 javascript 代码:

    <script type="text/javascript">
        $(document).ready(function () 
            $("#SubscriptionPopUp").modal("show");

            $("#btnClose").click(function () 
                $("#SubscriptionPopUp").modal("hide");
            );
        );
        function ShowStatus() 
            console.log("got here!");
            $("#SubscriptionPopUp").modal("show");
        

    </script>

现在,当我单击 GridView 中的按钮时,它会触发 RowCommand 事件,这是我包含的用于注册和调用客户端脚本的代码:

ScriptManager.RegisterStartupScript ( this.Page, this.GetType ( ), "ShowSubscriptionStatus", "ShowStatus();", true );

所以,所有代码都会触发,如果您注意到的话,我会检测 JavaScript 函数来记录一条消息,这确实有效。问题是,模态形式永远不会出现。控制台中没有任何类型的错误或消息,没有调试错误……什么都没有。

我很困惑为什么它没有正确触发,或者为什么我至少没有收到任何类型的错误消息。

【问题讨论】:

pnlSubscriptionPopUp 是否曾经设置为 Visible = True ?如果需要,最好将其默认设置为True,然后在代码隐藏中设置为False 如果我在初始页面加载时将其设置为 true,它会显示出来。后续操作不会做任何事情。 “如果我在初始页面加载时将其设置为 true,它会显示出来”——如果您将 pnlSubscriptionPopUp 设置为 True,则模式会在初始加载时自动弹出打开?或者你的意思是 JS 函数可以在按钮点击初始加载后弹出模态框,但之后就不能再工作了? 它会在初始加载时打开模式($(document) 函数中的脚本会这样做),但是当我尝试在其他任何时候加载它时它什么也不做。我在控制台中根本没有收到任何消息 可以在浏览器中调试吗?在ShowStatus() 上设置断点,看看它是否被击中。 【参考方案1】:

好的,已经这样做了很多次了?

我真的很喜欢 bootstrap 做很多事情。但是,对于对话框,我跳到了 jQuery.UI。

我发现添加此类和该类以使此类对话框正常工作的标记过多。

你在下面有一个非常好的答案——(我投票赞成这个答案)。

我也尽量避免记录“就绪”的代码(除非我必须——它总是很难调试)。

然而,我发现 jQuery.UI 只是你放在页面上的简单“div”(显示:无隐藏)。就是这样!

所以,假设我们有一个网格,单击一行,我们想在该 div 中显示该行数据。

所以,我们的网格是这样的:

  <div style="width:40%">

      <asp:GridView ID="MyGrid" runat="server" CssClass="table table-hover" 
          DataKeyNames="ID" AutoGenerateColumns="false"
          OnSelectedIndexChanged="MyGrid_SelectedIndexChanged" >

        <Columns>
           <asp:BoundField DataField="FirstName" HeaderText="FirstName"  />
           <asp:BoundField DataField="LastName" HeaderText="Last Name" />
           <asp:BoundField DataField="HotelName" HeaderText="Hotel Name" />
           <asp:BoundField DataField="City" HeaderText="City" />
           <asp:BoundField DataField="Province" HeaderText="Porvince" />


            <asp:Templatefield HeaderText ="View">
                <ItemTemplate>
                    <asp:Button ID="cmdView" runat="server" Text="View"
                        CommandName = "Select"/>
                </ItemTemplate>
            </asp:Templatefield>
        </Columns>
    
      </asp:GridView>

没什么特别的。 注意:我没有使用模板化字段。如果你这样做了,那么你必须使用查找控件来代替“本示例简单”的 .cells 集合。

所以,以上是标记。

这是我们要在上面加载的代码:

    protected void Page_Load(object sender, EventArgs e)
    
        if (IsPostBack == false)
        
            LoadGrid();
        
    

    public void LoadGrid()
    
        using (SqlCommand cmdSQL = new SqlCommand("SELECT TOP 12 * from tblHotels ORDER BY HotelName",
            new SqlConnection(Properties.Settings.Default.TEST3)))
        
            cmdSQL.Connection.Open();
            MyGrid.DataSource = cmdSQL.ExecuteReader();
            MyGrid.DataBind();

        
    

好的,到目前为止一切都很好。

因此我们现在有了这个:

现在让我们添加我们的 pop div。

  <div id="mypop" style="display:none">
          <br />
          <div style="text-align:right">

            <p>Hotel Name:<asp:TextBox ID="txtHotel" runat="server"></asp:TextBox></p>
            <p>First Name:<asp:TextBox ID="txtFirst" runat="server"></asp:TextBox></p>
            <p>Last Name:<asp:TextBox ID="txtLast" runat="server"></asp:TextBox></p>
            <p>City:<asp:TextBox ID="txtCity" runat="server"></asp:TextBox></p>
            <p>Province:<asp:TextBox ID="txtProvince" runat="server"></asp:TextBox></p>

           </div>

        </div>

再次,很好 - 只是简单和漂亮的飞机 jane div,这将是我们的弹出窗口。 (请注意我们没有 gazzllion 类和设置 - 真是太好了又简单)。

现在,该按钮具有“神奇”CommandName =“Select”,因此将触发 Selected 索引更改事件。

所以,我们弹出对话框的代码是这样的:

    protected void MyGrid_SelectedIndexChanged(object sender, EventArgs e)
    
        // fill out dialog boxes
        GridViewRow dG = MyGrid.SelectedRow;

        txtFirst.Text = dG.Cells[0].Text;
        txtLast.Text = dG.Cells[1].Text; ;
        txtHotel.Text = dG.Cells[2].Text; ;
        txtCity.Text = dG.Cells[3].Text; ;
        txtProvince.Text = dG.Cells[4].Text; ;

        // call our js routine to pop
        ScriptManager.RegisterStartupScript(this.Page, this.GetType(),"my test","poptest()", true);

    

最后但同样重要的是,上面调用的 jQuery.UI pop 例程。

     <script>

            function poptest() 
                var mydiv = $('#mypop')
                mydiv.dialog(
                    autoOpen: false, modal: true, title: 'Hotel Information', width: '400px',
                    position:  my: 'top', at: 'top+150' ,
                    closeText: '',
                    buttons: 
                        'ok': function () 
                            // $('#cmdAdd').click() - click standard asp button
                            mydiv.dialog('close')
                        ,
                        'cancel': function () 
                            mydiv.dialog('close')
                        
                    
                );
                // Open the dialog
                // mydiv.parent().appendTo($("form:first")) - only add if editing in div
                mydiv.dialog('open')
            
        </script>

现在上面的好处是我们有两个按钮 - 我展示了如何关闭对话框 - 但我们也可以调用/单击表单上的一个按钮来根据任一选择运行代码(我建议设置为那些按钮 ClientIDMode="Static",因此上面非常简单的 ok 或 cancel 代码可以因此只是“click()”那个按钮。这样你就不必做花哨的脚力来根据选择调用代码.

当对话框弹出时,它会自动将页面的其余部分“阴影”掉,并启用除对话框之外的所有其他控件。

现在,结果如下所示:

如您所见,我们在这方面的努力取得了很大成效。一个简单的 div 变成了那个相当不错的对话框。我们有一组简单的按钮,它们是对话框的一部分,然后可以根据您单击对话框支持的按钮执行操作。

对于提出不同的道路,我有点抱歉。我发现 jQuery.UI 对话框可以正常工作,非常简单。如果有人只是建立一个可爱的小库来使用带有引导对话框的简单 div - 注册我! - 但我在尝试让引导对话框工作时发现了太多“问题”。这很可能是我的缺点 - 但通常只有一个简单的 div + jQuery.UI 对话框的简单方法效果很好。

【讨论】:

【参考方案2】:

这是我写的一个小例子,希望能给你一些关于如何修复你的问题的见解,因为我真的不知道你的 GridView 设置。虽然可能只是将document.ready() 添加到您的ShowStatus() 可能会解决此问题。

前端

<asp:Content ContentPlaceHolderID="headcontent" runat="server">
    <script type="text/javascript">
        function ShowStatus() 
            $(document).ready(function () 
                $("#SubscriptionPopUp").modal("show");
            )
        

        function closeModal(e) 
            e.preventDefault();
            $("#SubscriptionPopUp").modal("hide");
            return false;  // don't want a post back
        
    </script>
</asp:Content>

<asp:Content ContentPlaceHolderID="MainContentHolder" runat="server">
    <asp:GridView ID="gvTest" runat="server" AutoGenerateColumns="false" OnRowDataBound="gvTest_RowDataBound" OnRowCommand="gvTest_RowCommand">
        <Columns>
            <asp:TemplateField>
                <ItemTemplate>
                    <div class="row">
                        <asp:Button ID="btnShowSubscription" runat="server" CommandName="Subscription" Text="Show Subscription Data" />
                    </div>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>


    <div id="SubscriptionPopUp" class="modal fade" role="dialog">
        <div class="modal-dialog modal-dialog-scrollable modal-dialog-centered modal-lg">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title">Subscription Details</h4>
                </div>
                <div class="modal-body">
                    <asp:Label ID="lblTestOutput" runat="server" />
                </div>
                <div class="modal-footer">
                    <button id="btnClose" onclick="closeModal(event)" class="btn btn-success">Close</button>
                </div>
            </div>
        </div>
    </div>
</asp:Content>

代码隐藏

protected void Page_Load(object sender, EventArgs e)

    if (!Page.IsPostBack)
    
        List<String> names = new List<string>()  "Kobe", "Jordan", "Wilt" ;
        gvTest.DataSource = names;
        gvTest.DataBind();
    


protected void gvTest_RowDataBound(object sender, GridViewRowEventArgs e)

    if (e.Row.RowType == DataControlRowType.DataRow)
    
        Button btnShowSubscription = (Button)e.Row.FindControl("btnShowSubscription");
        if (btnShowSubscription != null)
        
            // usually if my DataItem is an object, I'll cast it first and make sure it's not null
            btnShowSubscription.CommandArgument = (string)e.Row.DataItem;
        
    


protected void gvTest_RowCommand(object sender, GridViewCommandEventArgs e)

    if (string.Equals(e.CommandName, "Subscription"))
    
        // again, probably cast this and do a !string.IsNullOrWhiteSpace() check
        switch ((string)e.CommandArgument)
        
            case "Kobe":
                this.lblTestOutput.Text = "Kobe is the best";
                break;
            case "Wilt":
                this.lblTestOutput.Text = "Wilt is the best";
                break;
            case "Jordan":
                this.lblTestOutput.Text = "Jordan is the best";
                break;
        

        ClientScript.RegisterClientScriptBlock(typeof(string), "ShowSubscriptionStatus", "ShowStatus();", true);
    

【讨论】:

我收到“未捕获的引用错误,未定义 ShowStatus”错误。 您的包含ShowStatus() 的脚本在页面上? 正如您将在我的示例中看到的那样。 ShowStatus() 在标题中。你没有UpdatePanels吗? 看起来您可能已经进入了 jQuery UI 对话框路径。希望有效!祝你好运

以上是关于从 GridView 事件获取模态显示的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在 c# ASP.NET 中使用 GridView_RowCommand 事件从 GridView 获取图像

从 GridView 获取正在编辑的行的 id

winform dev的GridView双击事件怎么实现

从 RowDataBound 事件的 gridview 从单元格中获取值

在使用pjax重新加载gridview后,在gridview上的Yii2模态表单更新没有显示

如何在`GridView`中启用显示突出显示