2009-07-29 60 views
2

我在ASP.NET Web窗体上有一个向导控件。我设置的默认按钮上的ApplicationWizard PreRender事件的每一步在后台代码如下所示:在Ajaxified向导控件中设置默认按钮

Page.Form.DefaultButton = ApplicationWizard.FindControl("StepNavigationTemplateContainerID").FindControl("StepNextButton").UniqueID; 

这是可以正常使用,但是当我ajaxify向导控制它不工作。 “默认”按钮设置为初始加载窗体(StartNextButton)时指定的控件,但在其他步骤上不会更新为StepNextButton。我究竟做错了什么?

回答

0

默认按钮的定义是什么?如果它是一个按钮,当您处于文本表单字段(输入类型=文本)时按下Enter键,然后在每个浏览器中,它是表单中的第一个提交按钮或图像按钮(input type = submit | image)如果存在。

你可以做的是为所有控件添加一个客户端脚本,在[enter]上提交表单等规则适用于(如input type =“text”)。

服务器侧的样品(可以Form_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;}"); 

键代码== 13是一个回车键
键代码== 27是退出键

1

后一一天或两天拉我的头发我设法破解这...希望这可以帮助其他人像我一样沮丧:

任何人都发现这篇文章知道这里直观的答案,设置窗体的默认按钮到下一个butto你的向导n,什么都不做。因此,下一个合乎逻辑的步骤是通过代表用户单击按钮来设法解决问题。假设我从代码隐藏文件中附加以下处理程序,以我的文本框和myButtonId是按钮,我需要为我的默认的ID:

  function textKeyDown(e) { 
       if (e.keyCode == 13) { 
        var myBtn = $get(myButtonId); 
        myBtn.click(); 
       } 
      } 

你会觉得上面会工作得很好,但因为它事实证明,强制向导按钮点击正在创建一个非常鬼祟的冲突 - 页面上的第一个按钮也会点击,覆盖最初的按钮点击我强制通过脚本创建非常奇怪的结果。就我而言,我的母版页中的第一个按钮是一个表示Home的按钮,当用户点击它时,他们会回到主页。所以在我试图强制Wizard的Next按钮点击时,我最终会回到我的主页,看起来没有任何理由。附加到PageRequestManager.initializeRequest后,我可以看到我有两个单独的回发启动:1,我强制向导按钮单击,1为一个甚至没有在我的雷达 - 按钮的主页。因此,长话短说,如果我从后面的代码中更新窗体的默认按钮(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键,尽管我无法想象它在这种情况下会表现得太不同。如果每步有很多输入,则可能不需要在向导中的每个控件上捕捉Enter键。

所以,你有它 - 只需要12个小时的故障排除来完成应该花费大约10分钟的时间。

快乐编码。

+0

我有这个问题。我试图根据你的答案来解决,但不能让它工作。 JavaScript已添加好,但页面仍然响应主页按钮,而不是下一个按钮....?有任何想法吗? – 2012-02-13 11:25:07

+0

Hi @Mad Pierre - 您是否尝试过多种浏览器?我的答案可能会略微过时,因为Chrome浏览器已经决定“click()”不能被调用,而必须通过生成DOM2事件来模拟鼠标点击... – Brian 2012-02-15 12:10:13

1

感谢布莱恩,你的脚本帮助我使用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的并没有为我工作,只好将其更改为客户端ID)

0

我想我已经终于破解了这个! 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; 
    } 

我使用__doPostBack而不是点击太多,但这不是问题。

0

我不认为你在这里需要任何脚本。问题似乎是页面上有多个提交按钮。所以你必须告诉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 
相关问题