2012-10-14 114 views
0

enter code here我有一些代碼,我繼承了正在使用的RowDataBound添加JavaScript到複選框一個gridview永遠設置的onclick的JavaScript複選框。這是爲了使行復選框由標題中的主複選框設置。所有的作品。問題在於性能。用戶不需要分頁,其中一些網格可以有數千行。如果我們不使用Attributes.Add()來連接javascript,則渲染速度很快。如果我使用的RowDataBound爲JavaScript注入,業績進入從瞬間到了區區600行近一分鐘。那是不對的。的GridView的RowDataBound正在行

所以我有兩個問題:

1)它是正常的RowDataBound採取永遠來處理這些JavaScript注入?

2)如果是這樣,你有什麼建議,以建立行復選框頭中具有主複選框工作更快的替代方案?

而且因爲我是新的論壇,我想在這裏感謝大家已經接受幫助。我已經潛伏了幾個星期了,你們的知識和意願都非常可觀。

UPDATE:

謝謝大家對你的幫助。下面是我落得這樣做:

首先,我不得不將一些變量在我的aspx捕捉clientID的一個母版頁環境:

<script language="javascript" type="text/javascript"> 
    //set the control id required by the external javascript 
    var ChangedAddressesGridViewID = '<%=ChangedAddressesGridView.ClientID%>'; 
</script> 

然後,我設置的onclick頁眉複選框名我的標題功能,並設置子選項框的onclick我的孩子點擊功能的名稱。我只提供了三個參數,單擊複選框本身的「this」,GridView的MasterPage友好名稱以及表示該列的數字。硬編碼的,我知道,但列不dynmamic,所以不會在這個時候一個問題:

<asp:GridView id="ChangedAddressesGridView" runat="server" AutoGenerateColumns="False" > 
    <Columns> 
     <asp:BoundField datafield="AddressId" headertext="ID" /> 
     <asp:BoundField datafield="Code" headertext="Code" /> 
     <asp:BoundField datafield="Facility" headertext="Facility" /> 
     <asp:BoundField datafield="Address" headertext="Address" /> 

     <asp:TemplateField headertext="Select"> 
      <HeaderTemplate> 
       <asp:Label id="LBLOverride" runat="server" text="Override" font-size="Smaller" font-names="Arial"></asp:Label><br /> 
       <asp:CheckBox id="chkBxHeader1" runat="server" onclick="HeaderClick(this,ChangedAddressesGridViewID,'4');"></asp:CheckBox> <br /> 
      </HeaderTemplate> 
      <ItemTemplate> 
       <asp:CheckBox id="chkBxSelect1" runat="server" onclick="ChildClick(this,ChangedAddressesGridViewID,'4');" ></asp:CheckBox> 
      </ItemTemplate> 
      <headerstyle horizontalalign="Center" /> 
      <itemstyle horizontalalign="Center" /> 
     </asp:TemplateField>  

     <asp:BoundField datafield="CAddress" headertext="Corrected Address" /> 

     <asp:TemplateField headertext="Select"> 
      <HeaderTemplate> 
       <asp:Label id="lblChange" runat="server" text="Change" font-size="Smaller" font-names="Arial"></asp:Label><br /> 
       <asp:CheckBox id="chkBxHeader2" runat="server" onclick="HeaderClick(this,ChangedAddressesGridViewID,'6');"></asp:CheckBox> 
      </HeaderTemplate> 
      <ItemTemplate> 
       <asp:CheckBox id="chkBxSelect2" runat="server" onclick="ChildClick(this,ChangedAddressesGridViewID,'6');"></asp:CheckBox> 
      </ItemTemplate> 
      <headerstyle horizontalalign="Center" /> 
      <itemstyle horizontalalign="Center" /> 
     </asp:TemplateField> 

    </Columns> 
</asp:GridView> 

這裏的,使得它的工作的JavaScript:

function GetHeaderCheckBox(grid, cellnum) { 
    cell = grid.rows[0].cells[cellnum]; 
    for (j = 0; j < cell.childNodes.length; j++) { 
     if (cell.childNodes[j].type == "checkbox") {return cell.childNodes[j]; } 
    } 
    return false; 
} 

function CheckBoxIsChecked(row, cellnum) { 
    cell = row.cells[cellnum]; 
    for (j = 0; j < cell.childNodes.length; j++) { 
     if (cell.childNodes[j].type == "checkbox") { 
      return cell.childNodes[j].checked; 
     } 
    } 
} 

function SetCheckBox(row, cellnum, checkedValue) { 
    cell = row.cells[cellnum]; 
    for (j = 0; j < cell.childNodes.length; j++) { 
     if (cell.childNodes[j].type == "checkbox") { 
      cell.childNodes[j].checked = checkedValue; 
     } 
    } 
} 

function HeaderClick(HeaderCheckBox, GridViewID, checkboxcolumn) { 

    var checkedValue; 
    var grid = document.getElementById(GridViewID); 
    var TotalChkBx = grid.rows.length; 

    if (HeaderCheckBox.checked == true) { checkedValue = true; } else { checkedValue = false; } 

    for (var n = 1; n < TotalChkBx; n++) { 
     SetCheckBox(grid.rows[n], checkboxcolumn, checkedValue); 
    }; 
} 

function ChildClick(RowCheckBox, GridViewID, checkboxcolumn) { 

    var grid = document.getElementById(GridViewID); 
    var HeaderCheckBox = GetHeaderCheckBox(grid, checkboxcolumn); 
    var TotalChkBx = grid.rows.length; 
    var TotalChkBxChecked = 0; 

    for (var n = 1; n < TotalChkBx; n++) { 
     if (CheckBoxIsChecked(grid.rows[n], checkboxcolumn)) { TotalChkBxChecked++; } 
    }; 

    if (TotalChkBxChecked == TotalChkBx - 1) { HeaderCheckBox.checked = true; } else { HeaderCheckBox.checked = false; } 
} 

有你有它。有一件事這個比大多數類似的例子不同的是,我希望通過列去,而不是僅僅通過「輸入」列表中旋轉。這是因爲我有兩個複選框列,我不確定如何使用「輸入」,我可以保持它們分離而不會變得非常混亂。所以,我發現了一個例子,幫助我瞭解如何在這裏做到這一點:

http://technico.qnownow.com/how-to-delete-multiple-rows-from-gridview-with-checkboxes/

而且,以消除更多不必要的參數,我有孩子的功能弄清楚自身的頭複選框。

無論如何,現在我有一個全選的頭/子複選框模式,我可以放在任何地方。以前的版本必須查找特定的複選框名稱,因此僅限於該列,這意味着您必須在需要的地方複製/粘貼功能。差異已悄悄進入,我的行爲不一致和錯誤。有了這個解決方案,到目前爲止,沒有任何錯誤,並且到處都有相同的確切行爲

而且沒有的RowDataBound。生活很好。

再次感謝大家。你們都幫助我思考了問題的各個方面。

+1

你的主複選框只是檢查/取消選中所有'GridView'複選框? – Jupaol

+0

不僅如此。它還會檢查任何已檢查的行。我沒有設計邏輯,但它看起來像原來的設計師想要檢查主複選框,如果任何單行被點擊。我不確定這是否有用,特別是考慮到性能成本。好點子!也許我應該對設計提出質疑。 –

回答

0

如果我的理解是正確的,你添加JavaScript只是一個碩士複選框選中/取消GridView

內的所有複選框這是我的假設,因爲你沒有提供拒絕代碼交互你也不回答我的問題上述....

那麼,如果是這樣,你可以使用在客戶端jQuery來達到同樣的效果的情況下:

例子:

<script> 
    $(function() { 
     var $grid = $("table[id$=myCustomGridView]"); 
     var $rows = $("> tbody > tr:not(:has(table, th))", $grid); 
     var $master = $("input:checkbox[id$=masterCheck]"); 
     var $gridChecks = $("input:checkbox", $rows); 

     $master.change(function (e) { 
      e.preventDefault(); 

      $gridChecks.prop("checked", $master.is(":checked")); 
     }); 

     $gridChecks.change(function (e) { 
      e.preventDefault(); 

      var masterValue = true; 

      for (var i = 0; i < $gridChecks.length; i++) { 
       var $x = $gridChecks.eq(i); 

       if (!$x.is(":checked")) { 
        masterValue = false; 
        break; 
       } 
      } 

      $master.prop("checked", masterValue); 
     }); 
    }); 
</script> 
<asp:CheckBox Text="Check/Uncheck all" runat="server" ID="masterCheck" /> 
<asp:GridView runat="server" ID="myCustomGridView"> 
    <Columns> 
     <asp:TemplateField> 
      <ItemTemplate> 
       <asp:CheckBox runat="server" ID="myCheckBox" Text='<%# Eval("job_desc") %>' /> 
      </ItemTemplate> 
     </asp:TemplateField> 
    </Columns> 
</asp:GridView> 

This is a live sample

+0

這看起來不錯。我之前並沒有使用過JQuery,但這將是一個很好的藉口。我今天不在工作,所以明天我會回來給你結果。再次感謝。 –

+0

我試過這個,它沒有工作,但只是因爲我無法讓jquery設置。這可能很簡單。但無論如何我都會在不同的地方結束。我決定在rowdatabound減速期間看看任務管理器,而這正是吃掉所有循環的ide。我在沒有調試器的情況下運行它,它是瞬時的。很高興我不需要改變代碼。我仍然感激你的想法,現在決定讓jquery工作。 –

+0

嗯,爲了得到它的工作只需添加NUget包,引用它的代碼,這就是它 – Jupaol

0

你可以在不使用javascript的情況下從後端做同樣的事情。使用標題複選框的CheckedChanged功能來執行此操作。代碼應該看起來像這樣 -

protected void chkAll_CheckedChanged(object sender, EventArgs e) 
{ 
    CheckBox chk = (CheckBox)GridView1.HeaderRow.FindControl("chkAll"); 
    if (chk.Checked) 
    { 
     for (int i = 0; i < GridView1.Rows.Count; i++) 
     { 
      CheckBox chkrow = (CheckBox)GridView1.Rows[i].FindControl("CheckBox1"); 
      chkrow.Checked = true; 
     } 

    } 
    else 
    { 
     for (int i = 0; i < GridView1.Rows.Count; i++) 
     { 
      CheckBox chkrow = (CheckBox)GridView1.Rows[i].FindControl("CheckBox1"); 
      chkrow.Checked = false; 
     } 
    } 

} 

讓我知道這是如何執行的。

+0

謝謝,我會試試看。我今天不在工作,所以明天我會回覆你,讓你知道。 –

+0

正如我在其他地方提到的那樣,我發現調試器本身導致巨大的性能下降,所以我沒有立即需要更改原始rowdatabound邏輯。但是謝謝你的努力。 –

相關問題