问题描述
||
我想从Codebehind显示一个jQuery UI对话框,并且需要在回发后刷新它。
该对话框是用于过滤和查找数据的控件。因此,用户从DropDownLists中选择并在TextBoxes中输入文本,单击“ Apply-Button \”,发生异步回发,数据将根据用户的选择进行过滤,结果将显示在GridView中。因此,我需要围绕GridView更新UpdatePanel。
异步回发在以下链接的帮助下起作用:
带ASP.NET按钮回发的jQuery UI对话框
http://blog.roonga.com.au/2009/07/using-jquery-ui-dialog-with-aspnet-and.html
(基本上是“ 0”解决方案)
问题:我无法使用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)
更新:我也注意到回发值有问题。所有TextBoxes(如果为空或不带逗号)。这表明控件根据以下内容多次渲染: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()
)。如果有人感兴趣,我可以添加更多代码。
解决方法
我认为这有事要做
对话框不在其中
UpdatePanel或类似的东西。
我也注意到了
回发值。所有文本框,如果
空的或没有附加逗号。
您确实在两个方面都正确。问题的症结在于脚本管理器“认为”应该更新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上张贴的最邪恶的代码,如果您使用它,蓬松的白色小猫会死亡,但是这种方法确实有效。
希望这可以帮助。
,这是我解决相同问题的方法。它将删除所有旧对话框,并将新更新的对话框添加回表单,以便回发工作。我将以下代码放在一个脚本块中,该脚本块通过后面的代码中的ScriptManager.RegisterStartupScript
添加到页面中。
$(\'#divMyDialogAdded\').remove();
$(\'#divMyDialog\').dialog({
autoOpen: false,modal: true
}).parent().appendTo(\'form:first\');
$(\'#divMyDialog\').attr(\'id\',\'divMyDialogAdded\');
,我不确定,但这可能是正确的,当我使用时它的工作形式是我
AjaxControlToolkit.ToolkitScriptManager.RegisterStartupScript
尝试这个 ?
ScriptManager.RegisterClientScriptBlock(Me.Page,GetType(Page),\"showChargeFilterDialog\",\"createChargeFilterDialog();$(\'#Dialog_ChargeFilter\').dialog(\'open\');\",True)
,我认为Jquery和脚本管理器/更新面板在生成和解析脚本时会使其冲突,因此您应该正确处理更新面板的触发器中的事件,以便在方法后面的代码中使用此事件:
UpdatePanel2.Update();
所以我有这个问题,可以通过下面的代码解决(这是我的示例代码):
<!--------- show for dialog --->
<div id=\"dialog\" style=\"direction: rtl;\">
<asp:ScriptManager ID=\"ScriptManager1\" runat=\"server\">
</asp:ScriptManager>
<asp:UpdatePanel ID=\"UpdatePanel2\" runat=\"server\" RenderMode=\"Block\" UpdateMode=\"Conditional\" EnableViewState=\"True\" ChildrenAsTriggers=\"True\">
<ContentTemplate>
<div>
<table>
<tr>
<td>
<asp:ListBox ID=\"lstSLA\" runat=\"server\" SelectionMode=\"Single\" Width=\"250px\" Height=\"350px\">
</asp:ListBox>
</td>
<td valign=\"middle\">
<asp:Button ID=\"BtnUpMove\" runat=\"server\" Text=\" top\" OnClick=\"BtnUpMove_Click\" />
<div>
<br />
</div>
<asp:Button ID=\"BtnDownMove\" runat=\"server\" Text=\"down\" OnClick=\"BtnDownMove_Click\" />
</td>
</tr>
<tr>
<td colspan=\"2\" align=\"center\">
<asp:Button ID=\"btnSavePeriority\" runat=\"server\" Text=\"Save\" OnClick=\"btnSavePeriority_Click\" />
</td>
<td>
</td>
</tr>
</table>
</div>
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID=\"btnSavePeriority\" />
<asp:AsyncPostBackTrigger ControlID=\"BtnUpMove\" EventName=\"Click\" />
<asp:AsyncPostBackTrigger ControlID=\"BtnDownMove\" EventName=\"Click\" />
</Triggers>
</asp:UpdatePanel>
</div>
并在C#代码中:
受保护的void BtnUpMove_Click(对象发送者,EventArgs e)
{
int SelectedIndex = lstSLA.SelectedIndex;
if (SelectedIndex == -1) // nothing selected
{
UpdatePanel2.Update();
return;
}
if (SelectedIndex == 0) // already at top of list
{
UpdatePanel2.Update();
return;
}
ListItem Temp;
Temp = lstSLA.SelectedItem;
lstSLA.Items.Remove(lstSLA.SelectedItem);
lstSLA.Items.Insert(SelectedIndex - 1,Temp);
UpdatePanel2.Update();
lstSLA.SelectedIndex = -1;
}
protected void BtnDownMove_Click(object sender,EventArgs e)
{
int SelectedIndex = lstSLA.SelectedIndex;
if (SelectedIndex == -1) // nothing selected
{
UpdatePanel2.Update();
return;
}
if (SelectedIndex == lstSLA.Items.Count - 1) // already at top of list
{
UpdatePanel2.Update();
return;
}
ListItem Temp;
Temp = lstSLA.SelectedItem;
lstSLA.Items.Remove(lstSLA.SelectedItem);
lstSLA.Items.Insert(SelectedIndex + 1,Temp);
UpdatePanel2.Update();
lstSLA.SelectedIndex = -1;
}
protected void btnSavePeriority_Click(object sender,EventArgs e)
{
if (lstSLA.Items.Count == 0) return;
try
{
var db = DatabaseHelper.GetITILDataAccess();
ServiceLevel srvlvl = new ServiceLevel();
int priority = 1;
foreach (ListItem ls in lstSLA.Items)
{
srvlvl = new ServiceLevel();
srvlvl = db.ServiceLevels.Single(p => p.ID == long.Parse(ls.Value));
srvlvl.priority = priority;
priority++;
ServiceLevelManagement.Update(srvlvl);
}
ShowMessage(ITILMessages.InsertComplete);
}
catch (Exception ex)
{ }
finally { }
}