【发布时间】: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', '');
});
除非不知道cbCountry和UpdatePanel1的ClientID,否则脚本不会运行;也不知道能不能解决我的问题
尝试 #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 输出插入到页面中。