9

<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 将 UpdatePanels 称为老式的杂物。但是因为我找不到更好的东西 - 让我们试试吧!将这些东西包装在更新面板中,让它发挥作用:

在此处输入图像描述

这样做的问题是,当UpdatePanel更新时,它会删除两个控件并用新控件替换它们。这意味着用户在第一个下拉菜单中失去了焦点。人们建议使用 javascript 尝试保存和恢复焦点的可怕 kludges。但我宁愿正确地做事。


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

我不需要更新国家下拉列表(也不需要标签)。我只需要更新状态下拉列表;那么为什么不只将它包装一个<asp:UpdatePanel>. 事实上,这是 StackOverflow 上建议的答案

在此处输入图像描述

那行得通。国家下拉菜单不会失去焦点。事件OnSelectedIndexChanged触发,状态下拉列表填充...

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

如果我再次更改Country ,则会引发异常:

无效的回发或回调参数。

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


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

它不会给你带来任何好处;但人们已经尝试通过 javascript 手动触发回发

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

除非不知道and ClientID,否则脚本不会运行;我也不知道它是否能解决我的问题cbCountryUpdatePanel1


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

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

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

有人建议调用 ASP.net PageMethods,并更新cbState客户端 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 表单编程模型无效。

4

5 回答 5

1

使用 AJAX 控制工具包......它有一个 CascadingDropDown ,这将是完美的!:)

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

于 2013-04-12T15:59:10.430 回答
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" });
        }
    }
于 2013-01-03T17:28:36.873 回答
0

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

<%@ Page MaintainScrollPositionOnPostback="true" %>

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

于 2013-04-12T13:57:16.903 回答
0

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

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

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

ASP.NET jQuery 双列表框编辑和保存

编辑 1

顺便说一句,为了摆脱:

无效的回发或回调参数。

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

<%@ Page EnableEventValidation="false"
于 2012-06-28T20:52:16.203 回答
-2

进入下拉列表的设置

设置 AutoPostBack=True ,

于 2012-12-14T14:24:22.857 回答