我想从Codebehind显示一个jQuery UI对话框,并且需要在回发后刷新它。
该对话框是用于过滤和查找数据的控件。因此,用户从DropDownLists中选择并在TextBoxes中输入文本,单击“Apply-Button”,发生异步回发,根据用户的选择对数据进行过滤,结果将显示在GridView中。因此,我需要围绕GridView更新UpdatePanel。
异步回发在以下链接的帮助下起作用:
(基本上是
dlg.parent().appendTo(jQuery("form:first"));
-Solution)问题:我既无法使用UpdateMode =“Always”也无法通过UpdatePanel.Update()从代码隐藏中手动更新UpdatePanel。我认为这与Dialog不在UpdatePanel内或其他类似原因有关。希望有人可以帮助我。
一些来源:
function createChargeFilterDialog() {
//setup dialog
$('#Dialog_ChargeFilter').dialog({
modal: true,
resizable: false,
autoOpen: false,
draggable: true,
hide: "Drop",
width: 850,
height: 600,
position: "center",
title: "Charge-Filter",
buttons: {
"Close": function () {
$(this).dialog("close");
}
},
open: function (type, data) {
$(this).parent().appendTo(jQuery("form:first"))
},
close: function (type, data) {
}
});
}
当通过以下方式单击BtnShowDialog(在jQuery-Dialog之外)时,它会从代码隐藏中调用
AjaxControlToolkit.ToolkitScriptManager.RegisterStartupScript _
(Me.Page, GetType(Page), "showChargeFilterDialog", "createChargeFilterDialog();$('#Dialog_ChargeFilter').dialog('open');", True)
更新:我也注意到回发值中存在问题。所有文本框(如果为空或不带逗号)。这表明控件根据以下条件多次渲染:http://www.componentart.com/community/forums/t/60999.aspx
我确定这两个问题都相关。整个对话框及其所有控件将在每次异步回发中重新创建,因此所有控件名称在DOM中存在多次(导致出现ViewState逗号附加问题)。这些控件仅在FireBug/IE Deveoper工具栏中可见,而在HTML-Source中不可见,因此我认为jQuery会导致这些问题。我如何处置对话框的或如何阻止对话框的重新创建(检查是否已存在)?这是因为对话框位于UpdatePanel内,还是因为对话框(通过Javascript)已移至UpdatePanel之外?
在异步回发之前销毁对话框并不能解决问题,因为对话框将完全消失:
<asp:Button ID="BtnApplyFilter" OnClientClick="$('#Dialog_ChargeFilter').dialog('destroy');" ... />
非常感谢您的帮助。
解决方案:我最后使用了AjaxControlToolkit中的ModalPopupExtender。在发生一些小问题之后,它的工作方式就像异步回发一样具有吸引力(如果您希望弹出窗口保持可见,请不要忘记在每个代码隐藏函数中调用
MPE.Show()
)。如果有人感兴趣,我可以添加更多代码。 最佳答案
您确实在两个方面都是正确的。问题的症结在于,脚本管理器“认为”它应该更新jQuery实际上已移动到页面上其他位置的元素,从而导致该元素的多个副本以及您提到的问题。
我已经使用嵌套的UpdatePanels看到了此问题,但在其他情况下也可能发生。
这是一个变通办法是困惑的问题。
选项1-更改jQuery UI的源代码。快速的运气我一点运气都没有。除了重新编写整个插件之外,如果不重新排列DOM的顺序,我很难找到让对话框正常工作的方法。另外,使用该路由,现在您“拥有”了源代码,因为您已对其进行了修改。
选项2-在页面部分呈现时调整DOM,以删除重复的元素。您可以输出一些其他脚本来清理虚假的重复元素。我不喜欢这种方法,因为它允许DOM在脚本运行之前处于无效状态。
选项3-手动覆盖UpdatePanel的呈现。代码看起来像这样:
private bool _hasDomPresence
{
get
{
return ViewState["__hasDomPresence"] == null ? false : (bool)ViewState["__hasDomPresence"];
}
set
{
ViewState["__hasDomPresence"] = value;
}
}
protected override void OnLoad( EventArgs e )
{
if( !ScriptManager.GetCurrent( this.Page ).IsInAsyncPostBack )
{
// a full postback means we no longer have a DOM presence
_hasDomPresence = false;
}
base.OnLoad( e );
}
protected virtual void ShowDetailDialog()
{
// code to show the offending dialog
// we are showing it, so note the fact that it now has a DOM presence
_hasDomPresence = true;
}
protected override void Render( HtmlTextWriter writer )
{
foreach( Control c in this.Controls )
{
//
// find the offending control's parent container prior to it being rendered
// In my scenario, the parent control is just a server-side DIV
if( c == this.DetailDialog )
{
//
// here, I am checking whether or not the panel actually needs to be
// rendered. If not, I set it to invisible, thus keeping a new DOM
// element from being created.
if( !this.DetailUpdatePanel.IsInPartialRendering && _hasDomPresence )
{
this.DetailUpdatePanel.Visible = false;
}
}
}
base.Render( writer );
}
由于页面的客户端和服务器版本不匹配(或者至少ASP.Net无法确定它们是否匹配),这也会使事件验证困惑。我可以找到的唯一方法是关闭事件验证。
使用适当的安全模型,事件验证不是100%必需的,但我不喜欢被迫将其关闭。
总而言之,这是我在SO上发布的最邪恶的代码,如果您使用它,蓬松的白色小猫会死亡,但是这种方法确实有效。
希望这可以帮助。