如何填写as​​p:DropDown客户端?

时间:2012-06-28 20:34:06

标签: asp.net ajax

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

enter image description here

当用户选择国家/地区时,我想填写状态列表。


尝试#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。但是因为我找不到更好的东西 - 让我们试一试!将内容包装在更新面板中,然后让它成为魔术:

enter image description here

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


尝试#3 - 只有UpdatePanel需要更新的内容

我不需要更新 国家/地区下拉列表(也不需要标签)。我只需要来更新下拉列表;那么为什么不在<asp:UpdatePanel>中仅包含 。事实上this is the answer suggested on StackOverflow

enter image description here

这很有效。 国家/地区下拉列表不会失去焦点。触发OnSelectedIndexChanged事件,状态下拉列表填充...

......我第一次更改国家/地区下拉列表。

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

  

无效的回发或回调参数。

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


尝试#4 - 尝试使用javascript

伪造回发

它没有获得任何东西;但是people have tried triggering a postback manually through javascript

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

除了不知道ClientIDcbCountry的{​​{1}}之外,该脚本不会运行;我甚至不知道它是否能解决我的问题


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

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

我无法承受在谷歌上找到的每一个随机建议都失去一天;我需要实际的答案。所以我只是让他们向脾气暴躁的人们展示研究工作(好像研究工作很重要)。

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

PageMethods

此处的问题与尝试#2相同。视图状态是错误的,因为我已经破坏了ASP.net背后的形式。


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

5 个答案:

答案 0 :(得分:1)

使用AJAX Control Toolkit ......它有一个CascadingDropDown,这将是完美的! :)

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

答案 1 :(得分:0)

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

我做过类似的事情,将隐藏字段中列表的内容序列化为JSON,然后在服务器代码中对每个帖子进行反序列化

这是一个答案,显示了一个完整的工作示例,以显示类似的东西(检查接受的答案)。

ASP.NET jQuery double listbox edit and save

编辑1

BTW为了摆脱:

  

无效的回发或回调参数。

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

<%@ Page EnableEventValidation="false"

答案 2 :(得分:0)

我有一个技巧,它的工作原理。它使用状态下拉列表中同一更新窗格中的隐藏按钮。

<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" });
        }
    }

答案 3 :(得分:0)

与尝试#1相关以解决页面位置问题,您可以尝试在aspx页面标题中使用它

<%@ Page MaintainScrollPositionOnPostback="true" %>

并在cbCountry_SelectedIndexChanged方法中注册javascript,以便将焦点设置在状态组合框中。

答案 4 :(得分:-2)

转到dropdownList的设置

设置AutoPostBack = True,