【问题标题】:How to fill an asp:DropDown client side?如何填写 asp:DropDown 客户端?
【发布时间】:2012-06-28 20:34:05
【问题描述】:

我有一个带有两个<asp:DropDown> 控件的网页:

当用户选择一个国家时,我想填写州列表。


尝试 #1 - OnSelectedIndexChanged

第一件事很简单:在第一个下拉列表的OnSelectedIndexChanged 期间,填写第二个框:

//be sure to set AutoPostBack of cbCountry to true in the properties window

protected void cbCountry_SelectedIndexChanged(object sender, EventArgs e)
{
   cbState.Items.Clear();
   FetchStatesForCountryIntoStateDropDown(cbState, cbCountry.SelectedValue);
   if (cbState.Items.Count > 0)
      cbState.SelectedIndex = 0;
}    

效果很好,只是它触发了页面刷新。发送帖子时用户被打断,页面被重新加载。并且页面不再是他们离开的地方,他们不再坐在下拉列表中。


尝试 #2 - 老式的 kludgey UpdatePanels

@Seglo calls UpdatePanels an old-fashioned kludge。但是因为我找不到更好的东西 - 让我们试试吧!将内容包装在更新面板中,让它发挥作用:

问题在于,当UpdatePanel 更新时,它会删除这两个控件并用新控件替换它们。这意味着用户在第一个下拉菜单中失去了焦点。人们建议horrible kludges using javascript to try to save and restore the focus。但我宁愿做正确的事。


尝试 #3 - 仅 UpdatePanel 您需要更新的内容

我不需要更新 Country 下拉列表(也不需要标签)。我只需要更新State下拉列表;那么为什么不将 only 包装在 <asp:UpdatePanel> 中。其实this is the answer suggested on StackOverflow

这行得通。 Country 下拉菜单不会失去焦点。 OnSelectedIndexChanged 事件触发,State 下拉列表填充...

...我第一次更改国家/地区下拉菜单。

如果我更改国家/地区 再次,它会引发异常:

回发或回调参数无效。

updatepanel 不知何故弄乱了 WebForms 控件;使回发数据无效。这是有道理的,因为弄乱了 WebForms 控件会使回发数据无效。


尝试 #4 - 尝试自己使用 javascript 伪造回发

它不会给你带来任何好处;但是people have tried triggering a postback manually through javascript:

$('#userControl1').on('focusout', function() {
     __doPostback('UpdatePanel2UniqueId', '');
});

除非不知道cbCountryUpdatePanel1ClientID,否则脚本不会运行;也不知道能不能解决我的问题


尝试 #5 - 使用 PageMethods 获取状态列表。

现在我只是链接其他人的随机建议。我需要大约 4 个小时来尝试实施任何建议。这意味着我已经失去了一天半的时间来尝试填充组合框。

我不能为我在谷歌上找到的每一个随机建议浪费一天的时间;我需要一个实际的答案。所以我把他们包括在内只是为了向脾气暴躁的人展示研究工作(好像研究工作很重要)。

一些people have suggested calling ASP.net PageMethods, and update the cbState in client javascript

function GetStates(country)
{
    PageMethods.GetTeam(teamCode, CountryCallback);
}

function CountryCallback(result)
{
    var teamName = $get('TeamName');
    var seed = $get('Seed');
    var rpi = $get('RPI');
    var scoutingReport = $get('ScoutingReport');
    teamName.innerText = result.TeamName;
    seed.innerText = result.Seed;
    rpi.innerText = result.RPI;
    scoutingReport.innerText = result.ScoutingReport;
}

onchange="GetTeam(this.options[this.selectedIndex].value);"

这里的问题与尝试#2 相同。视图状态将是错误的,因为我已经搞砸了 ASP.net 背后的表单。


似乎存在一个根本问题,即 ASP.net 和 viewstate 从根本上与客户端 DOM 更新不兼容。任何修改页面客户端的尝试都会使整个 ASP.net Web 表单编程模型无效。

【问题讨论】:

  • 你已经成功了,ViewState 几乎普遍会阻止你做很多这样的事情。这就是我们从基于 ViewState 的模型转变为几乎纯 MVC 模型的原因。我建议使用 PageMethods TWICE,一次进行更新,然后再次提交表单。然后在第二个 PageMethod 成功时重定向。 (这会很快发生,你会感到惊讶)=== 另一种方法是使用 UpdatePanel 并等待。 === 公平地说,有一些方法可以让你所要求的工作,但当你还不熟悉时,它们比第二个 PageMethod 花费的时间要长很多。
  • 同意。在与 UpdatePanel 斗争并实施了尴尬的解决方法之后,我终于完全摆脱了它们并使用 WebMethods/jQuery 来变魔术。
  • @Dimitri 当您这样做时,修改页面客户端不会导致Invalid postback or callback argument. 错误吗?
  • 您可以使用页面方法创建一个下拉列表。将其渲染为字符串并使用 jquery 将 html 输出插入到页面中。

标签: asp.net ajax


【解决方案1】:

使用 AJAX 控制工具包...它有一个 CascadingDropDown 非常完美! :)

http://www.asp.net/ajaxLibrary/AjaxControlToolkitSampleSite/CascadingDropDown/CascadingDropDown.aspx

【讨论】:

    【解决方案2】:

    使用 javascript 更新 DropDownList 控件不会改变视图状态,这意味着在每个帖子中所做的更改都将被覆盖。

    我已经对隐藏字段中列表的内容进行了类似的序列化,然后在服务器代码中对每个帖子进行反序列化

    这是一个显示类似内容的完整工作示例的答案(检查接受的答案)。

    ASP.NET jQuery double listbox edit and save

    编辑 1

    顺便说一句,为了摆脱:

    回发或回调参数无效。

    您可以禁用视图状态验证,但不建议这样做,只有在您可以信任大部分时间在您的用户中的 Intranet 中时,您才应该这样做

    <%@ Page EnableEventValidation="false"
    

    【讨论】:

      【解决方案3】:

      我有一个窍门,它奏效了。它在状态下拉列表的同一更新窗格中使用隐藏按钮。

      <script type="text/javascript">
          function ddlCountry_changed() {
              document.getElementById('<%= btnLoad.ClientID %>').click();
          }
      </script>
      
      Country:
      <asp:DropDownList ID="ddlCountry" runat="server" onchange="ddlCountry_changed();">
          <asp:ListItem Text="Vietnam" Value="1"></asp:ListItem>
          <asp:ListItem Text="United State" Value="2"></asp:ListItem>
      </asp:DropDownList>
      
      <asp:UpdatePanel ID="updatePanel" runat="server">
          <ContentTemplate>
              <asp:Button ID="btnLoad" style="display: none" runat="server" OnClick="btnLoad_OnClick" />
              State:
              <asp:DropDownList ID="ddlState" runat="server">
              </asp:DropDownList>
          </ContentTemplate>
      </asp:UpdatePanel>
      

      后面的代码:

          protected void btnLoad_OnClick(object sender, EventArgs e)
          {
              ddlState.Items.Clear();
      
              if (ddlCountry.SelectedValue == "2")
              {
                  ddlState.Items.Add(new ListItem() { Text = "California", Value = "1" });
              }
              else
              {
                  ddlState.Items.Add(new ListItem() { Text = "Saigon", Value = "2" });
              }
          }
      

      【讨论】:

        【解决方案4】:

        与Attempt#1相关的解决页面位置问题你可以尝试在aspx页眉中使用这个

        <%@ Page MaintainScrollPositionOnPostback="true" %>
        

        并在cbCountry_SelectedIndexChanged 方法中注册一个javascript 来设置状态组合框的焦点。

        【讨论】:

          【解决方案5】:

          进入下拉列表的设置

          设置 AutoPostBack=True ,

          【讨论】:

          • 在尝试 #1 中,OP 提到他已经在这样做了。
          猜你喜欢
          • 1970-01-01
          • 2018-10-12
          • 1970-01-01
          • 2014-09-06
          • 1970-01-01
          • 2015-07-25
          • 2013-04-22
          • 2012-10-17
          • 2014-09-16
          相关资源
          最近更新 更多