2011-09-06 16 views
3

首先,我在表中有3個文本框,一個DropDownList,一個CheckBox和2個LinkBut​​tons。 TextBoxes和DropDownList必須執行AutoPostBack,因爲在OnTextChanged調用的服務器端執行了一些計算。將回調設置爲回傳後的任何控件

我在這裏的問題是,任何控制(它需要一個回發)的內容更改,並嘗試將焦點移動到頁面上的任何其他控件(無論是選項卡或使用鼠標點擊任何其他控制)焦點不會移動到您點擊的下一個控件或控件。

我試過使用一種方法,它找到當前的控制和基於TabIndex,加1將焦點移動到下一個控件。這裏的問題是,它不允許在其他任何控件上設置焦點,而不是使用下一個TabIndex。爲了更好地解釋這裏是一個例子。

例如:我有TextBox1,TextBox2和TextBox3。我更改TextBox2中的內容,然後想要向後移動到TextBox1。當我點擊TextBox1時,焦點被設置爲TextBox3,因爲代碼正在使用TabIndex的順序。 **這裏的一個關鍵因素是TextBox1在服務器端代碼觸發之前獲得焦點,但之後失去焦點並將其設置在TextBox3上**

對我而言,似乎唯一可以實現的方法是添加客戶端上的一個函數,它在PostBack發生之前找到帶有焦點的Control,然後在服務器端代碼完成後重置該Control上的焦點。看起來我在服務器端做的任何事情都不會起作用,因爲當發生這種情況時焦點已經丟失。

我已經搜索和搜索,但一直沒有找到任何解決方案,這個特定的問題,我發現的一切涉及到設置焦點到下一個控制,而不是你想要有焦點的控制。任何幫助將不勝感激。先謝謝你。

下面是我用來移動到基於TabIndex下一個控制的代碼,但這不適用於我的情況。

protected void Page_Load(object sender, EventArgs e) 
    { 
     WebControl ctrl = GetPostBackControl() as WebControl; 
     if (ctrl != null && !SetNextFocus(Controls, ctrl.TabIndex + 1)) { ctrl.Focus(); } 
    } 

public Control GetPostBackControl() 
    { 
     Control control = null; 

     string ctrlname = Request.Params.Get("__EVENTTARGET"); 
     if (ctrlname != null && ctrlname != string.Empty) 
     { 
      control = FindControl(ctrlname); 
      control.Focus(); 
     } 
     else 
     { 
      foreach (string ctl in Request.Form) 
      { 
       Control c = FindControl(ctl); 
       if (c is Button) 
       { 
        control = c; 
        break; 
       } 
      } 
     } 
     return control; 
    } 

    private bool SetNextFocus(ControlCollection controls, int tabIndex) 
    { 
     foreach (Control control in controls) 
     { 
      if (control.HasControls()) 
      { 
       bool found = SetNextFocus(control.Controls, tabIndex); 
       if (found) { return true; } 
      } 

      WebControl webControl = control as WebControl; 
      if (webControl == null) { continue; } 
      if (webControl.TabIndex != tabIndex) { continue; } 

      webControl.Focus(); 
      return true; 
     } 

     return false; 
    } 

回答

0

謝謝你的幫助,這也讓我一點點接近。阻止它正常工作的唯一原因是我的頁面有一些變量正在從其他頁面繼承。當頁面加載時,覆蓋會導致頁面中斷,因爲它無法找到這些控件。我能夠在.aspx頁面上添加一個HiddenField並添加以下代碼在onload()函數來解決這個問題:

if (document.getElementById("HiddenField1").value != "") { 
    var contr = document.getElementById(document.getElementById"HiddenField1").value); 
    contr.focus(); 
    document.getElementById("HiddenField1").value = ""; 
} 

以及添加一個被稱爲在每個文本框的新功能:

function tabFocus(e) { 
    document.getElementById("HiddenField1").value = e.id; 
} 

我最終沒有在後面的代碼做任何改變。再次感謝您的幫助!

4

試着做這樣的事回發後保留焦點:

/// <summary> 
/// Overrides the OnLoad event moves the cursor to the appropriate control. 
/// </summary> 
/// <param name="e"></param> 
protected override void OnLoad(EventArgs e) 
{ 
    base.OnLoad(e); 

    int currentTabIndex = 1; 
    WebControl postBackCtrl = (WebControl)GetControlThatCausedPostBack(Page);  

    foreach (WebControl ctrl in Panel1.Controls.OfType<WebControl>()) 
    { 
     ctrl.TabIndex = (short)currentTabIndex; 
     if (postBackCtrl != null) 
     { 
      if (ctrl.TabIndex == postBackCtrl.TabIndex + 1) 
       ctrl.Focus(); 
     } 
     currentTabIndex++; 
    }           
} 


/// <summary> 
/// Retrieves the control that caused the postback. 
/// </summary> 
/// <param name="page"></param> 
/// <returns></returns> 
private Control GetControlThatCausedPostBack(Page page) 
{ 
    //initialize a control and set it to null 
    Control ctrl = null; 

    //get the event target name and find the control 
    string ctrlName = Page.Request.Params.Get("__EVENTTARGET"); 
    if (!String.IsNullOrEmpty(ctrlName)) 
     ctrl = page.FindControl(ctrlName); 

    //return the control to the calling method 
    return ctrl; 
} 
+0

你是什麼意思,它無法找到這些控件?哪些控件? –

+0

我創建了一個新的解決方案,重複了這個問題,並嘗試了你的代碼,但不幸的是,在我的情況下,它使頁面打破。我添加了下面的代碼來解決我遇到的問題。再次感謝你的幫助! – Brian