如何在不重新加载页面的情况下刷新下拉列表?

9

我在页面中有两个下拉列表:

<asp:DropDownList AutoPostBack="True" OnSelectedIndexChanged="ddlMain_SelectedIndexChanged" ClientIDMode="Static" ID="ddlMain" name="searchPhys" style="width: 365px;" class="default" runat="server" AppendDataBoundItems="true">
    <asp:ListItem Text="BY PHYSICIAN" Value="0" Selected="True" />
    <asp:ListItem Text="BY LOCATION" Value="1" />
    <asp:ListItem Text="BY SPECIALTY" Value="2" />
</asp:DropDownList>

<br /><br />

<asp:DropDownList ClientIDMode="Static" ID="ddlDrillDown" name="searchPhys" style="width: 365px;" class="default" runat="server" AppendDataBoundItems="true">
</asp:DropDownList>

我处理下拉列表更改的代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Xml.Linq;
using System.Configuration;
using System.Windows.Forms;
using System.Data;

public partial class physicians : System.Web.UI.Page
{

    protected void Page_Load(object sender, EventArgs e) {

    if (!Page.IsPostBack) {
        PopulatePhysician();
    }
    //PopulateSpecialty();
    //PopulateLocation();

    }

    public void PopulatePhysician() {
        SqlCommand cmd = new SqlCommand("getPhysicians", new SqlConnection(ConfigurationManager.AppSettings["ConnString"]));
        //cmd.CommandType = Data.CommandType.StoredProcedure
        cmd.Connection.Open();

        SqlDataReader ddlValues = default(SqlDataReader);
        ddlValues = cmd.ExecuteReader();

        //if (!IsPostBack) {
            ddlDrillDown.Items.Clear();
            ddlDrillDown.DataSource = ddlValues;
            ddlDrillDown.DataValueField = "content_id";
            ddlDrillDown.DataTextField = "content_title";
            ddlDrillDown.DataBind();
            //set the default value for the drop down
            ListItem Item = new ListItem();
            Item.Text = "Select a Physician's Name";
            Item.Value = "0";
            //Item.Selected = True
            ddlDrillDown.Items.Insert(0, Item);
        //}
    cmd.Connection.Close();
    cmd.Connection.Dispose();
    }

    public void PopulateSpecialty() {
        SqlCommand cmd = new SqlCommand("getSpecialties", new SqlConnection(ConfigurationManager.AppSettings["ConnString"]));
        cmd.Connection.Open();

        SqlDataReader ddlValues = default(SqlDataReader);
        ddlValues = cmd.ExecuteReader();

        //if (!IsPostBack) {
            ddlDrillDown.Items.Clear();
            ddlDrillDown.DataSource = ddlValues;
            ddlDrillDown.DataValueField = "content_id";
            ddlDrillDown.DataTextField = "content_title";
            ddlDrillDown.DataBind();
            //set the default value for the drop down
            ListItem Item = new ListItem();
            Item.Text = "Select a Specialty";
            Item.Value = "0";
            ddlDrillDown.Items.Insert(0, Item);
        //}
        cmd.Connection.Close();
        cmd.Connection.Dispose();
    }

    public void PopulateLocation() {
        SqlCommand cmd = new SqlCommand("getLocations", new SqlConnection(ConfigurationManager.AppSettings["ConnString"]));
        cmd.Connection.Open();

        SqlDataReader ddlValues = default(SqlDataReader);
        ddlValues = cmd.ExecuteReader();

        //if (!IsPostBack) {
            ddlDrillDown.Items.Clear();
            ddlDrillDown.DataSource = ddlValues;
            ddlDrillDown.DataValueField = "content_id";
            ddlDrillDown.DataTextField = "content_title";
            ddlDrillDown.DataBind();

            //set the default value for the drop down
            ListItem Item = new ListItem();
            Item.Text = "Select a Location";
            Item.Value = "0";
            ddlDrillDown.Items.Insert(0, Item);
        //}
        cmd.Connection.Close();
        cmd.Connection.Dispose();
    }

    public void ddlMain_SelectedIndexChanged(object sender, System.EventArgs e) {
        switch(ddlMain.SelectedIndex) {
            case 0:
                PopulatePhysician();
                break;
            case 1:
                PopulateLocation();
                break;
            case 2:
                PopulateSpecialty();
                break;
        }
    }
}

我需要添加的功能是,当用户从“ddlMain”下拉列表中选择一个选项时,根据该选项刷新“ddlDrillDown”下拉列表而无需重新加载页面。
我该如何实现?
更新:
<asp:ScriptManager ID="ScriptManager" 
                               runat="server" />
            <asp:UpdatePanel ID="UpdatePanel1" 
                             UpdateMode="Conditional"
                             runat="server">
                <ContentTemplate>
                    <asp:DropDownList AutoPostBack="True" OnSelectedIndexChanged="ddlMain_SelectedIndexChanged" ClientIDMode="Static" ID="ddlMain" style="width: 365px;" class="default" runat="server" AppendDataBoundItems="true">
                        <asp:ListItem Text="BY PHYSICIAN" Value="0" Selected="True" />
                        <asp:ListItem Text="BY LOCATION" Value="1" />
                        <asp:ListItem Text="BY SPECIALTY" Value="2" />
                    </asp:DropDownList>
                    <br /><br />
                    <asp:DropDownList ClientIDMode="Static" ID="ddlDrillDown" style="width: 365px;" class="default" runat="server" AppendDataBoundItems="true">
                    </asp:DropDownList>
                    </ContentTemplate>
            </asp:UpdatePanel>

我需要刷新listview的数据,而不需要刷新整个页面。更多细节请查看我的问题:https://stackoverflow.com/questions/47180999/listview-databind-causes-lost-of-formview-data/47181885?noredirect=1#comment81313556_47181885 - fatiDev
6个回答

8
使用 AJAX。将两个下拉列表控件放置在 UpdatePanel 中,并在页面的开头添加一个 ScriptManager(如果尚未存在)。

ScriptManager可以放在任何地方,还是必须出现在FORM标记之后?我已经更新了我的问题,并请告诉我是否正确。 - SearchForKnowledge
ScriptManager必须出现在需要它的任何控件之前。(https://dev59.com/omYr5IYBdhLWcg3wssKP)......为了更安全起见,建议将添加ScriptManager作为团队中的首个控件的惯例 :) - Manish Dalal
你不需要做任何其他事情。尝试在IE中加载您的页面,看看是否有任何“Sys”JavaScript错误(在状态栏中)。 - Manish Dalal
不知道为什么会发生这种情况。我刚刚创建了一个示例页面,它按预期工作......你能以某种方式分享你的页面吗? - Manish Dalal
除非页面刷新,否则下拉菜单将失去其样式。我正在使用DropKick CSS来为我的选择框添加样式... - SearchForKnowledge
显示剩余7条评论

5
如果是这种情况,Ajax方法应该能解决您的问题。由于您对Ajax还比较陌生,我将详细介绍一些细节。
  1. 同一个页面中只能有一个ScriptManager。 (如果您使用的是主页面,请添加到主页面,不需要在嵌套内容页面中再添加)
  2. 添加UpdatePanel并将您的控件添加到UpdatePanel的ContentTemplate中。
  3. 将AutoPostBack="True"添加到您的主下拉列表。
  4. 通过双击主下拉列表添加SelectedIndexChanged事件。
  5. 在主下拉列表的SelectedIndexChanged事件中,通过添加ddlDrillDown.Items.Clear()方法清除ddlDrillDown项,并根据主下拉列表的值重新绑定所需的数据。

2

建议您使用 UpdatePanel。请不要使用 ClientIDMode="Static",除非您真的非常需要。

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>

        <asp:DropDownList AutoPostBack="True" OnSelectedIndexChanged="ddlMain_SelectedIndexChanged" ID="ddlMain" runat="server">
            <asp:ListItem Text="BY PHYSICIAN" Value="0" Selected="True" />
            <asp:ListItem Text="BY LOCATION" Value="1" />
            <asp:ListItem Text="BY SPECIALTY" Value="2" />
        </asp:DropDownList>

        <asp:DropDownList ID="ddlDrillDown" name="searchPhys" runat="server">
        </asp:DropDownList>

    </ContentTemplate>
</asp:UpdatePanel>

现在,UpdatePanel的问题在于它不会刷新页面,但会重新加载DOM。因此,使用jQuery进行的任何更改都将丢失。这就是为什么您会失去DropKick CSS的原因。 您需要再次触发$("#ID").dropkick(。为此,您可以使用PageRequestManager。

<script type="text/javascript">
    $(document).ready(function () {
        TriggerDropkick();
    });

    var prm = Sys.WebForms.PageRequestManager.getInstance();

    prm.add_endRequest(function () {
        TriggerDropkick();
    });

    function TriggerDropkick() {
        $("#<%= ddlMain.ClientID %>, #<%= ddlDrillDown.ClientID %>").dropkick({
            mobile: true
        });
    }
</script>

建议使用服务来获取DropDownList的值。这是可能的,但由于这是WebForms,您需要禁用一些验证,以防止“Invalid postback or callback argument”异常。

2

您可以使用Ajax来实现此目标。

创建asmx服务或WebApi控制器,返回项目列表。在更改时调用它并呈现它。


我是新手,不确定如何完成它。我根据@Manish Dalal的说法更新了我的问题,但它没有起作用 :/ - SearchForKnowledge
我不使用ScriptManager。我使用jQuery来调用Web服务并渲染元素。 - GraDea
你能提供一份我所拥有的样本吗? - SearchForKnowledge

1

你可以使用另一种方法,即 Asp.Net [Webmethod] 属性。

在服务器端代码中创建一个带有 [Webmethod] 属性的方法。 在前端,使用 window.PageMethods.(你的方法名称) 调用服务器调用。


0

我使用了依赖下拉列表方法。如何实现?

  1. 将DropDownList1_SelectedIndexChanged的内容放入一个子程序中

例如:

Sub Drop1()
YOURCOD
End Sub
  1. DropDownList1_SelectedIndexChanged 中调用 Drop1()
  2. DropDownList2_SelectedIndexChanged (Drop2()) 创建相同的操作

现在在 DropDownList1_SelectedIndexChanged 中调用 Drop1Drop2。 就这样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接