如何在 asp.net 网络应用程序中制作 PopUp window?

How to make PopUp window in asp.net web application?

我正在使用ASP.NET Forms.
制作食堂管理系统 所以我想要一个 Pop-Up window 或框,它将从下拉列表和文本框中输入以实现 Filter 选项。
那么如何制作它以及如何从后台代码访问收集的数据?
欢迎任何教程链接或建议。感谢您的帮助:)

您可以创建固定位置 DIV 并使用 JS 显示它,JQuery,...只要您想显示对话框。 然后你可以读取输入数据。

How to generate a simple popup using jQuery

有很多方法可以做到这一点。如果你使用 AjaxControlToolKit,他们有一个很棒的弹出扩展器,它不需要 JavaScript.

但是,最好的选择可能是使用 jQuery.UI。毫无疑问,您的站点和应用程序具有 jQuery,因此,我将添加 jQuery.UI。您可以使用 nueget 来安装它,或者直接转到 jquery 站点并下载 jQuery.UI 文件。它们很常见。

因此,我们这样做的方法是您(通常)在弹出页面上创建一个“div”。这很好用,因为它对“点击”的响应非常快(您甚至不必点击服务器即可打开对话框 pop-up。但是,您弹出的表单可能是编辑数据。

接下来要考虑的是弹出窗体不能有post-backs。 (嗯,好吧,它可以有一个)。因此,如果您弹出的表单是要有一些丰富的验证码,或者需要一些服务器端事件代码才能 运行 的代码?你往往不走运。因此,您可以轻松弹出一个表单,用户可以编辑(或输入数据),但是您只允许一个 post-back 按钮事件(比如“确定 - 保存”)。所以在大多数情况下,这样的弹出窗体是可以的,但请记住这个限制。如果您确实需要在该对话框中响应某些内容,那么在大多数情况下您必须编写 ajax 调用 - 这对开发人员来说是额外的痛苦和工作量。

所以,假设我们要弹出一个对话框来过滤网格。弹出窗口将允许用户输入酒店名称的前几个字符,或者我们可以 select 从下拉列表中选择一个城市以按城市过滤网格。

我们在一个仅显示“活动”记录的复选框中投入使用。

那么,它的工作原理和外观如何? (并牢记上述注意事项(弹出对话框中只允许一个 post-back)。

好了,我们先搭建网格。但是,我们需要在标题中添加一些按钮。所以我必须删除一些数据绑定字段,并为该列使用模板。这让我们可以使用按钮或任何我们喜欢的方式来设置 header。

我对城市标题也做了同样的事情。

所以,我们有这个标记:

 <div id="HotelGrid" runat="server" style="width:50%">

        <asp:GridView ID="GHotels" runat="server" AutoGenerateColumns="False" DataKeyNames="ID"  CssClass="table table-hover" 
            style="vertical-align:middle" ShowHeaderWhenEmpty="true">
            <Columns>
                <asp:BoundField DataField="FirstName"   HeaderText="FirstName"  />
                <asp:BoundField DataField="LastName"    HeaderText="LastName"   />
                <asp:TemplateField>

                    <HeaderTemplate>
                        <asp:LinkButton ID="btnSearchCity" 
                        runat="server" 
                        CssClass="btn-default btn-sm"
                        >City
                        <span aria-hidden="true" class="glyphicon glyphicon-search"></span>
                        </asp:LinkButton>
                    </HeaderTemplate>

                    <ItemTemplate>
                        <asp:Label ID="lblCity" runat="server" Text='<%# Eval("City") %>'></asp:Label>
                    </ItemTemplate>

                </asp:TemplateField>

                <asp:BoundField DataField="Province"    HeaderText="Province"   />

      <asp:TemplateField HeaderStyle-Width="200px">
         <HeaderTemplate>
          <asp:LinkButton ID="cmdSearchHotel" 
              runat="server" 
              CssClass="btn-default btn-sm"
              OnClientClick="return mysearch(this);"
              OnClick="cmdSearchHotel_Click"

              >Hotel 
              <span aria-hidden="true" class="glyphicon glyphicon-search"></span>                                
           </asp:LinkButton>
        </HeaderTemplate>

        <ItemTemplate>
            <asp:Label ID="lblHotel" runat="server" Text='<%# Eval("HotelName") %>'></asp:Label>
         </ItemTemplate>
       </asp:TemplateField>

      <asp:BoundField DataField="Description"HeaderText="Description" />
      
      <asp:TemplateField HeaderText="Active"  ItemStyle-HorizontalAlign="Center"  >
      <ItemTemplate>
          <asp:CheckBox ID="chkActive" runat="server" Checked='<%# Eval("Active") %>'  />
      </ItemTemplate>

       <ItemStyle HorizontalAlign="Center"></ItemStyle</asp:TemplateField>

                <asp:TemplateField HeaderText="Edit">
                    <ItemTemplate>
                        <asp:Button ID="cmdEdit" runat="server" Text="Edit"class="btn" OnClick="cmdEdit_Click"/>
                    </ItemTemplate>

                </asp:TemplateField>
            </Columns>
        </asp:GridView>

现在,您可以在上面看到,标记开始增长 - 这是由于 gridview 需要围绕每组控件的“模板”。 (我经常建议使用列表视图,因为您不需要模板。但这没什么大不了的。

好的,所以我们有了上面的标记。

我的页面加载代码加载网格?好吧,我们想让标题显示出来,所以我们这样做:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not IsPostBack Then
        GHotels.DataSource = MyRst("select * from tblHotels where id = 0")
        GHotels.DataBind()

        ' load the city combo box
        cboCity.DataSource = MyRst("SELECT City from tblCity ORDER BY City")
        cboCity.DataBind()
        cboCity.Items.Insert(0, "")  ' allow blank selection

    End If
End Sub

Public Function MyRst(strSQL As String) As DataTable

    Dim rstData As New DataTable
    Using MyCon As SqlConnection = New SqlConnection(My.Settings.TEST3)
        Using cmdSQL As New SqlCommand(strSQL, MyCon)
            cmdSQL.Connection.Open()
            rstData.Load(cmdSQL.ExecuteReader)
        End Using
    End Using
    Return rstData

End Function

好的,所以我们现在 see/have 这个:

现在,网格标题中的两个按钮将分为两部分。

弹出对话框的部分(jQuery.UI),然后是服务器端的标准代码。

好的,我们必须创建一个 div 来容纳我们的弹出窗口。

这将相当简单,只有组合框(城市)、酒店名称的文本框和“仅限活动”过滤器的复选框。

所以,div很简单。并注意当我们对 div 布局感到满意时,我们添加 display:none 来隐藏 div.

所以我们有这个:

        <div id="mysearchdiv" style="border:solid;width:300px;text-align:right;padding:15px;font-size:large;display:NONE">
            <p>Select City
            <asp:DropDownList ID="cboCity" runat="server" width="150px"
                DataTextField="City"
                DataValueField="City"
                ></asp:DropDownList>
            </p>
            <p>
                Hotel Name
                <asp:TextBox ID="txtSearchHotel" runat="server" Width="150" Height="25"></asp:TextBox>
            </p>
            <p>
                Include Only Active
                <asp:CheckBox ID="chkActiveOnly" runat="server" />
            </p>
            <asp:HiddenField ID="cmdOption" runat="server" ClientIDMode="Static"/>
        </div>

非常简单的标记。

好的,现在是困难的部分,jQuery UI 是一个 java 脚本例程,它是这样的:

    <script>
        var searchok = false
        function mysearch(btn) {
            if (searchok) {
                return true
            }
            var myDialog = $("#mysearchdiv");
            myDialog.dialog({
                title:"Search For Hotels",
                modal: true,
                width: "320px",
                resizable: false,
                appendTo: "form",
                autoOpen: true,
                buttons: {
                    Ok: function ()
                    {
                        searchok = true
                        btn.click()
                    },
                    Clear: function () {

                        searchok = true
                        $('#cmdOption').val('c')
                        btn.click()
                    },
                    Cancel: function () {
                        myDialog.dialog('close')
                    }
                }
            });
            return false
        }

    </script>

所以,它是一些代码,但是 jQuery.UI 是“抓住”div,并将其转换成一个漂亮的对话框。所以最后的结果是这样的:

现在,要么是在我开始输入后添加了 c# 标记,要么是我错过了它。

但是,C# 代码大同小异。第一页加载代码是这样的:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            GHotels.DataSource = MyRst("select * from tblHotels where id = 0");
            GHotels.DataBind();

            // load our search combo box
            cboCity.DataSource = MyRst("SELECT City from tblCity ORDER BY City");
            cboCity.DataBind();
            cboCity.Items.Insert(0,new ListItem("",""));
        }
    }

    public DataTable MyRst(string strSQL)
    {
        DataTable rstData = new DataTable();
        using (SqlCommand cmdSQL = new SqlCommand(strSQL,
            new SqlConnection(Properties.Settings.Default.TEST3)))
        {
            cmdSQL.Connection.Open();
            rstData.Load(cmdSQL.ExecuteReader());
        }
        return rstData;
    }

所以上面将加载网格(我们发送一个空白行,因为我们使用 header 进行搜索。

点击按钮?好吧,我们弹出一个 jquery 对话框。如果它 return 是真或假 - 确定服务器端按钮是否会触发。

所以,我们有这个:

                <asp:TemplateField HeaderStyle-Width="200px">
                    <HeaderTemplate>
                        <asp:LinkButton ID="cmdSearchHotel" 
                        runat="server" 
                        CssClass="btn-default btn-sm"
                        OnClientClick="return mysearch(this);"
                        OnClick="cmdSearchHotel_Click"
                        >Hotel 
                        <span aria-hidden="true" class="glyphicon glyphicon-search"></span>
                        </asp:LinkButton>
                    </HeaderTemplate>

                    <ItemTemplate>
                        <asp:Label ID="lblHotel" runat="server" Text='<%# Eval("HotelName") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>

请注意我们如何使用 jQuery 搜索例程 return true 或 false。

好的,现在可以很简单地将代码写入 filter/search 基于该弹出窗口的网格。

代码非常简单,我们“累积”添加每个搜索选项,或者如果搜索框中没有输入任何值,则简单地跳过选项。

而且,我们添加了那个隐藏字段,因为如您所见,我们现在可以向该对话框添加更多按钮,但不必创建新的代码服务器端 - 只需单击一下按钮即可处理所有选项对于那个对话框。

因此,此过滤的 C# 代码为:

    protected void cmdSearchHotel_Click(object sender, EventArgs e)
    {
        if (cmdOption.Value == "c")
        {
            // clear the search option
            cboCity.Text = "";
            txtSearchHotel.Text = "";
            chkActiveOnly.Checked = false;
            cmdOption.Value = "";
            GHotels.DataSource = MyRst("select * from tblHotels where id = 0");
            GHotels.DataBind();
            return;
        }

        // filter the grid
        string strWhere = "";
        using (SqlConnection con = new SqlConnection(Properties.Settings.Default.TEST3))
        using (SqlCommand cmdSQL = new SqlCommand("SELECT * FROM tblHotels",con))
        {
            if (cboCity.Text != "")
            {
                strWhere += "City = @City";
                cmdSQL.Parameters.Add("@City", SqlDbType.NVarChar).Value = cboCity.Text;
            }

            if (txtSearchHotel.Text != "")
            {
                if (strWhere != "")
                    strWhere += " AND ";
                strWhere += "HotelName like @Hotel + '%'";
                cmdSQL.Parameters.Add("@Hotel", SqlDbType.NVarChar).Value = txtSearchHotel.Text;
            }

            if (chkActiveOnly.Checked)
            {
                if (strWhere != "")
                    strWhere += " AND ";
                strWhere += "Active = 1";
            }

            if (strWhere != "")
                cmdSQL.CommandText += " WHERE " + strWhere;

            cmdSQL.CommandText += " ORDER BY HotelName";

            con.Open();
            GHotels.DataSource = cmdSQL.ExecuteReader();
            GHotels.DataBind();
        }

所以,总而言之:

绝对最少的代码。

并没有比典型的网格多多少标记。

我分享了一个很长一段时间以来很少有人使用过的超酷技巧。这就是如何让一个 jQuery.UI 对话框在我们不想的情况下不触发服务器端按钮。因此我们不需要 java 中的多个例程,也不需要 mutiple 例程服务器端。我们只需使用一个按钮调用对话框,它 return 为真或为假。但它仍然是 运行ning 异步的,因为所有和大多数 JavaScript 小部件应该是。 (不允许使用阻塞代码!!!)。