Asp.net 在Ajaxified向导控件中设置默认按钮
我的ASP.NET web窗体上有一个向导控件。我将在代码隐藏中的ApplicationWizard PreRender事件的每个步骤上设置默认按钮,如下所示:Asp.net 在Ajaxified向导控件中设置默认按钮,asp.net,asp.net-ajax,wizard,Asp.net,Asp.net Ajax,Wizard,我的ASP.NET web窗体上有一个向导控件。我将在代码隐藏中的ApplicationWizard PreRender事件的每个步骤上设置默认按钮,如下所示: Page.Form.DefaultButton = ApplicationWizard.FindControl("StepNavigationTemplateContainerID").FindControl("StepNextButton").UniqueID; 这是完美的工作,但当我ajaxify向导控件它不工作。默认按钮设置为初
Page.Form.DefaultButton = ApplicationWizard.FindControl("StepNavigationTemplateContainerID").FindControl("StepNextButton").UniqueID;
这是完美的工作,但当我ajaxify向导控件它不工作。默认按钮设置为初始加载表单时指定的控件(StartNext按钮),但在其他步骤上不更新为StepNextButton。我做错了什么?试试。默认按钮的定义是什么?如果它是一个按钮,当您在文本表单字段(输入类型=文本)中并按enter键时,应该调用它,那么在每个浏览器中,它都是表单中的第一个提交或图像按钮(输入类型=提交|图像)(如果存在) 您可以做的是向所有控件添加一个客户端脚本,如[enter]上的submit form(提交表单)规则适用于这些控件(如输入type=“text”) 服务器端示例(可以在表单_Init中使用)只是为了一个想法:
SomeTextBox.Attributes.Add("onkeydown",
"if((event.keyCode&&event.keyCode==13)){" +
Page.ClientScript.GetPostBackEventReference(StepNextButton, "") +
";return false;}" +
"if((event.keyCode&&event.keyCode==27)){" +
Page.ClientScript.GetPostBackEventReference(CancelButton, "") +
";return false;}");
keyCode==13是一个回车键keyCode==27是一把逃生钥匙在拔了一两天头发后,我设法破解了这个。。。希望这能帮助像我一样沮丧的人: 任何找到这篇文章的人都知道,这里直观的答案是,将表单的默认按钮设置为向导的下一个按钮,但没有任何作用。因此,下一个合乎逻辑的步骤是尝试通过代表用户单击按钮来解决问题。假设我已将下面的处理程序从codebehind中附加到我的文本框,并且myButtonId是我默认需要的按钮id:
function textKeyDown(e) {
if (e.keyCode == 13) {
var myBtn = $get(myButtonId);
myBtn.click();
}
}
您可能会认为上面的方法可以很好地工作,但事实证明,强制向导按钮单击会产生非常微妙的冲突-页面上的第一个按钮也会单击,覆盖我通过脚本强制的初始按钮单击,并产生非常奇怪的结果。在我的例子中,母版页中的第一个按钮是一个显示“主页”的按钮,当用户单击它时,他们返回主页。因此,在我试图强制向导的“下一步”按钮单击时,我会回到我的主页,看起来根本没有理由。在连接到PageRequestManager.initializeRequest后,我可以看到我有两个单独的回发开始:一个用于强制向导按钮单击,一个用于当时甚至不在我的雷达上的按钮-主页按钮
因此,长话短说,如果我从代码隐藏中更新表单的默认按钮(Page.form.DefaultButton),然后从代码隐藏中发出此脚本,并从我的文本框中引用它,所有工作都很正常:
public static void ExampleAssignDefaultButton(WizardStepBase activeWizardStep, TextBox myTextBox, IButtonControl myButton)
{
// create the format string for the script
string javaScript = @"function defaultButton(src, evt){{
if(evt.keyCode == 13){{
var btn = $get('{0}');
setTimeout(new function() {{ btn.click(); }}, 5);
}}
}}";
// format it ...
javaScript = String.Format(javaScript, ((WebControl)myButton).ClientID);
// register it...
ScriptManager.RegisterClientScriptBlock(activeWizardStep, activeWizardStep.GetType(), "defaultButton", javaScript, true);
// assign it to my textbox
myTextBox.Attributes.Add("onkeydown", "defaultButton(this, event);");
// also update the form's default button:
myTextBox.Page.Form.DefaultButton = ((WebControl)myButton).UniqueID;
}
值得注意的是,我总是从活动向导步骤的OnPreRender事件调用上述方法。还值得注意的是,因为我的向导中每个步骤只有一个文本框,所以我只需将此行为分配给单个控件。我还没有尝试过在整个页面中捕捉回车键,尽管我无法想象在这种情况下它的行为会有太大的不同。如果每个步骤都有大量输入,则可能不需要捕捉向导中每个控件上的Enter键
所以,你有它-只有12个小时的故障排除来做一些事情,应该已经花了大约10分钟
快乐编码
B谢谢Brian,在使用RadAjax、多用户控件和多种类型的面板时,您的脚本帮助我建立了自己的脚本。通过从控件而不是脚本中传递按钮ID,可以简化defaultButton 第页:
function defaultButton(btnid, src, evt) {
if (evt.keyCode == 13) {
var btn = $get(btnid);
setTimeout(new function () { btn.click(); }, 5);
}
}
代码:
Private Sub WizardStep_PreRender(sender As Object, e As System.EventArgs) Handles wsUserPass.PreRender, wsCompanyCode.PreRender, wsSetPassword.PreRender
Dim button As WebControl = Nothing
Dim activeWizardStep As WizardStepBase = CType(sender, WizardStepBase)
Select Case activeWizardStep.StepType
Case WizardStepType.Step
button = activeWizardStep.FindControl("StepNavigationTemplateContainerID").FindControl("StepNextButton")
Case WizardStepType.Start
button = activeWizardStep.FindControl("StartNavigationTemplateContainerID").FindControl("StartNextButton")
Case WizardStepType.Finish
button = activeWizardStep.FindControl("FinishNavigationTemplateContainerID").FindControl("FinishButton")
End Select
If button Is Nothing Then Return
Dim ctrls = FindControls(Of RadTextBox)(activeWizardStep)
For Each ctrl In ctrls
ctrl.Attributes.Add("onkeydown", String.Format("defaultButton('{0}', this, event);", button.ClientID))
Next
pnlMain.DefaultButton = button.UniqueID
End Sub
Public Shared Function FindControls(Of T)(ctrl As Control) As List(Of T)
Dim controls As New List(Of T)
If ctrl.Controls.Count > 0 Then
For Each subctrl In ctrl.Controls
If [Type].ReferenceEquals(GetType(T), subctrl.GetType()) Then
controls.Add(subctrl)
Else
controls.AddRange(FindControls(Of T)(subctrl))
End If
Next
End If
Return controls
End Function
(注意,UniqueID对我不起作用,必须将其更改为ClientID)我想我终于破解了这个问题!javascript中的(调试)警报消息使其工作的事实为我指明了正确的方向 我必须向javascript添加几行代码才能使其正常工作,因此我的方法如下所示:
private void SetDefaultButtonScript(WizardStepBase activeWizardStep, IButtonControl myButton)
{
string clientID = ((WebControl)myButton).ClientID;
string uniqueID = ((WebControl)myButton).UniqueID;
// create the format string for the script
string javaScript = @"function defaultButton(btnid, evt) {{
if (evt.keyCode == 13) {{
__doPostBack('{0}', '');
var btn = $get('{1}');
btn.focus();
return;
}}
}}
";
javaScript = String.Format(javaScript, uniqueID, clientID);
// register it...
ScriptManager.RegisterClientScriptBlock(activeWizardStep, activeWizardStep.GetType(), "defaultButton", javaScript, true);
foreach (Control c in activeWizardStep.Controls)
{
if (c is TextBox)
{
((TextBox)c).Attributes.Add("onkeydown", "defaultButton(this, event);");
}
//TODO child controls of controls to find all text boxes, any other controls etc
}
Page.Form.DefaultButton = uniqueID;
}
我使用的是uu doPostBack而不是单击,但这不是问题所在。我认为这里不需要任何脚本。问题似乎是页面上有多个提交按钮。因此,您必须告诉asp.net您希望使用哪一个作为“默认”提交。您必须在页面生命周期的正确时间告诉它。我不确定它是否是最优的,但在PreRender事件中这样做似乎是可行的。仅添加以下代码的基本ajaxified向导似乎使用了正确的按钮:
Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
MyBase.OnPreRender(e)
Select Case LoginWizard.ActiveStep.StepType
Case WizardStepType.Start
Page.Form.DefaultButton = LoginWizard.FindControl("StartNavigationTemplateContainerID").FindControl("NextStart").UniqueID
Case WizardStepType.Step
Page.Form.DefaultButton = LoginWizard.FindControl("StepNavigationTemplateContainerID").FindControl("NextStep").UniqueID
Case WizardStepType.Finish
Page.Form.DefaultButton = LoginWizard.FindControl("FinishNavigationTemplateContainerID").FindControl("LastStep").UniqueID
End Select
End Sub
我有这个问题。我正试图根据你的答案来解决问题,但就是无法让它发挥作用。javascript添加正常,但页面仍然响应主页按钮而不是下一步按钮。。。。?有什么想法吗?嗨@Mad Pierre-你试过多种浏览器吗?对于像Chrome这样的浏览器来说,我的答案可能有点过时了,因为它们决定“click()”不能被调用,相反,您必须通过生成DOM2事件来模拟鼠标点击……还没有。我先试试IE(9)。你看到我上面的其他评论了吗:如果我添加了一个警报,脚本会工作吗?Hi@Madperre-可能在.click()调用之前禁用你的主页按钮?我必须查看你的代码才能知道到底发生了什么,但肯定有什么东西触发了点击你的另一个按钮,禁用该按钮将阻止点击被允许触发-编辑-刚刚看到你解决了问题-很高兴你解决了它:)也许禁用将帮助其他人阅读此线程,所以我将此保留在机智…这是一个奇怪的!基于您的c#代码,只有在javascript函数末尾出现警报时,默认按钮才起作用!例如,如果我放置函数defaultButton(btnid,src,evt){if(evt.keyCode==13){var btn=$get(btnid);setTimeout(新函数(){btn.click();},5);alert('test');}它可以工作!但是,删除警报(“测试”)会导致我的默认主页按钮单击“赢”。有人有什么想法吗?到目前为止,我已经浪费了几天时间。。。。。