2009-01-10 7 views
2

J'ai étendu le contrôle GridView standard dans ASP.NET. Fondamentalement, c'est exactement la même chose, mais la pagination et le tri sont effectués à l'aide de rappels.GridView avec pager TopAndBottom

J'ai réussi à créer mon propre PagerTemplate, mais cela ne fonctionne que lorsque PagerSettings.Position est défini sur Haut. Je veux avoir le téléavertisseur en haut et en bas.

Je reçois une exception HttpException disant: La table doit contenir des sections de ligne dans l'ordre de l'en-tête, du corps, puis du pied de page.

Quelqu'un sait ce que cela pourrait être?

J'ai déjà essayé d'appeler la méthode MakeAccessible(), mais cela n'aide pas.

code:

private int _IdColumnIndex = -1; 

public override object DataSource 
{ 
    get 
    { 
    return HttpContext.Current.Session[this.ClientID + "_DataSource"]; 
    } 
    set 
    { 
    if (!value.GetType().Equals(typeof(DataView))) 
     throw new ArgumentException("Only System.Data.DataView is accepted as a DataSource for DataGridView!"); 

    HttpContext.Current.Session[this.ClientID + "_DataSource"] = value; 
    } 
} 

/// <summary> 
/// Sets the default settings. 
/// </summary> 
private void SetDefaultSettings() 
{ 
    base.AllowPaging = true; 
    base.AllowSorting = true; 
    base.ShowHeader = true; 
    base.ShowFooter = true; 
    base.PagerTemplate = new GridPagerTemplate(PAGER_ID, this); 
    base.PagerSettings.Position = PagerPosition.TopAndBottom; 
    base.PageSize = 10; 

    AddSelectionCheckbox(); 
} 

//private void MakeAccessible() 
//{ 
// if (this.Rows.Count > 0) 
// { 
// //This replaces <td> with <th> and adds the scope attribute 
// this.UseAccessibleHeader = true; 

// //This will add the <thead> and <tbody> elements 
// this.HeaderRow.TableSection = TableRowSection.TableHeader; 

// //This adds the <tfoot> element. Remove if you don't have a footer row 
// this.FooterRow.TableSection = TableRowSection.TableFooter; 
// } 
//} 

private void AddSelectionCheckbox() 
{ 
    TemplateField tf = new TemplateField(); 
    tf.HeaderText = ""; 
    tf.ItemTemplate = new CheckboxTemplate(ROW_CHECKBOX_ID); 

    base.Columns.Add(tf); 
} 

protected override void OnInit(EventArgs e) 
{ 
    SetDefaultSettings(); 

    base.DataBound += new EventHandler(DataGridView_DataBound); 
    base.RowDataBound += new GridViewRowEventHandler(DataGridView_RowDataBound); 

    base.OnInit(e); 
} 

protected override void OnPreRender(EventArgs e) 
{ 
    base.OnPreRender(e); 
    //this.PaintRows(); 
    //this.FormatCells(); 

    // Get JavaScript for this DataGridView, and include it on the page. 
    string scriptUrl = Page.ClientScript.GetWebResourceUrl(this.GetType(), "Yakinix.UI.Controls.DataGridView.js"); 
    Page.ClientScript.RegisterClientScriptInclude("DataGridView", scriptUrl); 

    string js = "function DGV_MakeCallback(argument)" + 
       "{" + 
        "__theFormPostData = '';" + 
        "__theFormPostCollection = new Array();" + 
        "WebForm_InitCallback();" + 
        GetCallbackEventReference("DGV_Callback") + 
       ";}"; 

    Page.ClientScript.RegisterClientScriptBlock(typeof(DataGridView), typeof(DataGridView).FullName + "DGV_MakeCallback", js, true); 

    if (this.HeaderRow != null) 
    this.HeaderRow.TableSection = TableRowSection.TableHeader; 
} 

private string GetCallbackEventReference(string func) 
{ 
    string callbackEventReference = Page.ClientScript.GetCallbackEventReference(this, "argument", func, "'" + ClientID + "'", false); 

    return callbackEventReference; 
} 

public override void RenderBeginTag(HtmlTextWriter writer) 
{ 
    writer.RenderBeginTag(HtmlTextWriterTag.Div); // <div> 
    base.RenderBeginTag(writer); 
} 

public override void RenderEndTag(HtmlTextWriter writer) 
{ 
    base.RenderEndTag(writer); 
    writer.RenderEndTag(); // </div> 
} 

/// <summary> 
/// Renders the gridview control and strips whitespace. It also 
/// applies the right formatting. 
/// </summary> 
public string RenderHtml() 
{ 
    using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture)) 
    { 
    //this.PaintRows(); 
    //this.FormatCells(); 

    if (this.HeaderRow != null) 
     this.HeaderRow.TableSection = TableRowSection.TableHeader; 

    this.UseAccessibleHeader = true; 
    this.RenderControl(new HtmlTextWriter(sw)); 
    string html = sw.ToString(); 

    return html; 
    } 
} 

// TODO: Style all rows for the column matching current SortExpression. 
protected void DataGridView_RowDataBound(object sender, GridViewRowEventArgs e) 
{ 
    //DataGridView gridView = (DataGridView)sender; 

    //if (gridView.SortExpression.Length > 0) 
    //{ 
    // int cellIndex = -1; 

    // // find the column index for the corresponding sort expression 
    // foreach (DataControlField field in gridView.Columns) 
    // { 
    // if (field.SortExpression == gridView.SortExpression) 
    // { 
    //  cellIndex = gridView.Columns.IndexOf(field); 
    //  break; 
    // } 
    // } 

    // if (cellIndex > -1) 
    // { 
    // if (e.Row.RowType == DataControlRowType.Header) 
    // { 
    //  // this is a header row, 
    //  // set the sort style 
    //  e.Row.Cells[cellIndex].CssClass += (gridView.SortDirection == SortDirection.Ascending ? " sortascheader" : " sortdescheader"); 
    // } 
    // else if (e.Row.RowType == DataControlRowType.DataRow) 
    // { 
    //  // this is a data row 
    //  e.Row.Cells[cellIndex].CssClass += (e.Row.RowIndex % 2 == 0 ? " sortaltrow" : "sortrow"); 
    // } 
    // } 
    //} 

    RenderDetailsRow(e); 
} 

/// <summary> 
/// Renders the details row, which is hidden when rendered. Clicking a details link, displays the row and more detailed data is shown, and is editable. 
/// </summary> 
/// <param name="e">The <see cref="System.Web.UI.WebControls.GridViewRowEventArgs"/> instance containing the event data.</param> 
private void RenderDetailsRow(GridViewRowEventArgs e) 
{ 
    // Only add a details row to DataRows 
    if (false && e.Row.RowType == DataControlRowType.DataRow) 
    { 
    Table table = e.Row.Parent as Table; 

    if (table != null) 
    { 
     GridViewRow row = new GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal); 
     row.Style[HtmlTextWriterStyle.Display] = "none"; 

     TableCell rowCell = new TableCell(); 
     rowCell.ColumnSpan = this.Columns.Count; 
     rowCell.Height = new Unit(100); 

     row.Cells.Add(rowCell); 
     table.Rows.Add(row); 

     HtmlAnchor htmlAhref = new HtmlAnchor(); 
     htmlAhref.HRef = "javascript:void(0);"; 
     htmlAhref.Attributes.Add("onclick", "ToggleElement('" + row.ClientID + "');"); 
     htmlAhref.InnerText = "Test"; 

     e.Row.Cells[e.Row.Cells.Count - 1].Controls.Add(htmlAhref); 
    } 
    } 
} 

protected void DataGridView_DataBound(object sender, EventArgs e) 
{ 
    FillPagerDetails(base.TopPagerRow); 
    FillPagerDetails(base.BottomPagerRow); 
} 

private void FillPagerDetails(GridViewRow pagerRow) 
{ 
    if (pagerRow != null) 
    { 
    // Retrieve the DropDownList and Label controls from the row. 
    DropDownList pageList = pagerRow.Cells[0].FindControl(PAGER_ID) as DropDownList; 

    if (pageList != null) 
    { 
     pageList.Attributes.Add("onchange", "DataGridViewPage(this.value, '" + ClientID + "');"); 

     // Add the number of pages to the ListBox 
     for (int i = 0; i < base.PageCount; i++) 
     { 
     int pageNumber = i + 1; 

     // Create a ListItem that represents a page 
     ListItem item = new ListItem(String.Format("{0}", pageNumber), i.ToString()); 

     // If the page is already selected, make sure the 
     // ListBox select the selected page 
     if (i == base.PageIndex) 
      item.Selected = true; 

     // Add the ListItem object to the Items collection of the DropDownList. 
     pageList.Items.Add(item); 
     } 
    } 
    } 
} 

protected override void InitializeRow(GridViewRow row, DataControlField[] fields) 
{ 
    base.InitializeRow(row, fields); 

    if (row.RowType == DataControlRowType.Header) 
    { 
    for (int i = 0; i < row.Cells.Count; i++) 
    { 
     row.Cells[i].Controls.Clear(); 

     if (row.Cells[i].Text.Equals("CHKCOL", StringComparison.Ordinal)) 
     { 
     CheckBox chkSelectAll = new CheckBox(); 
     chkSelectAll.ID = "chkSelectAllRows"; 
     row.Cells[i].Controls.Add(chkSelectAll); 
     } 
     else 
     { 
     row.Cells[i].Text = String.Format(CultureInfo.InvariantCulture, "<a href=\"javaScript:DataGridViewSort('{0}', '{2}');void(0)\" title=\"{1}\">{1}</a>", fields[i].SortExpression, fields[i].HeaderText, this.ClientID); 
     } 
    } 
    //if (ViewState["SortExpression"] != null) 
    //{ 
    // int index; 
    // index = 0;// GetHeaderCellIndex(ViewState["SortExpression"].ToString()); 
    // if (index != -1) 
    // { 
    // //Literal literal; 
    // //if ((SortDirection)ViewState["SortDirection"] == SortDirection.Ascending) 
    // //{ 
    // // if (string.IsNullOrEmpty(SortAscendingImageUrl)) 
    // // { 
    // // literal = new Literal(); 
    // // literal.Text = "&#8593;"; 
    // // row.Cells[index].Controls.Add(literal); 
    // // } 
    // // else 
    // // { 
    // // sortImage.ImageUrl = SortAscendingImageUrl; 
    // // row.Cells[index].Controls.Add(sortImage); 
    // // } 
    // //} 
    // //else 
    // //{ 
    // // if (string.IsNullOrEmpty(SortDescendingImageUrl)) 
    // // { 
    // // literal = new Literal(); 
    // // literal.Text = "&#8595;"; 
    // // row.Cells[index].Controls.Add(literal); 
    // // } 
    // // else 
    // // { 
    // // sortImage.ImageUrl = SortDescendingImageUrl; 
    // // row.Cells[index].Controls.Add(sortImage); 
    // // } 
    // //} 
    // } 
    //} 
    } 
    else if (row.RowType == DataControlRowType.DataRow) 
    { 
    for (int i = 0; i < row.Cells.Count; i++) 
    { 
     if (fields[i].HeaderText.Equals("id", StringComparison.InvariantCultureIgnoreCase)) 
     { 
     _IdColumnIndex = i; 
     break; 
     } 
    } 
    } 
} 

protected override void OnRowCreated(GridViewRowEventArgs e) 
{ 
    base.OnRowCreated(e); 

    if (e.Row.RowType == DataControlRowType.Header) 
    { 
    //HtmlImage img = new HtmlImage(); 
    //img.ID = "lbCheckAll"; 
    //img.Src = "/img/btn_slct_all.gif"; 
    //img.Alt = "Select all"; 
    //img.Attributes.Add("onclick", "SelectAllRows('" + this.ClientID + "',true);return false;"); 
    //e.Row.Cells[0].Controls.Add(img); 
    } 
    else if (e.Row.RowType == DataControlRowType.DataRow) 
    { 
    //AddCheckbox(e); 
    } 
    else if (e.Row.RowType == DataControlRowType.Footer) 
    { 
    //e.Row.Cells[0].Text = "sdsds"; 
    } 
} 

protected override void OnRowDataBound(GridViewRowEventArgs e) 
{ 
    base.OnRowDataBound(e); 

    if (e.Row.RowType == DataControlRowType.DataRow) 
    { 
    //AddCheckbox(e); 

    if (_IdColumnIndex != -1) 
     e.Row.Cells[_IdColumnIndex].Text = "<a href=\"Details.aspx?id=" + e.Row.Cells[_IdColumnIndex].Text + "\">Edit</a>"; 
    } 
} 

public override void Sort(string sortExpression, SortDirection sortDirection) 
{ 
    DataView dv = this.DataSource as DataView; 

    if (dv != null) 
    { 
    dv.Sort = sortExpression + " " + (sortDirection == SortDirection.Ascending ? "ASC" : "DESC"); 
    } 
} 

#region ICallbackEventHandler Members 

private string callbackArg = String.Empty; 

string ICallbackEventHandler.GetCallbackResult() 
{ 
    // Save state with PageStatePersister and place it to Page.ClientState 
    System.Reflection.MethodInfo mi = typeof(Page).GetMethod("SaveAllState", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); 
    mi.Invoke(this.Page, null); 

    // Get serialized viewstate from Page's ClientState 
    System.Reflection.PropertyInfo stateProp = typeof(Page).GetProperty("ClientState", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); 
    string state = stateProp.GetValue(this.Page, null).ToString(); 

    return callbackArg + "¤#¤" + state; 
} 

void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument) 
{ 
    try 
    { 
    // Load XML from client 
    XmlDocument doc = new XmlDocument(); 
    doc.LoadXml(eventArgument.Replace("&", "&amp;")); 
    string pagerId = String.Empty; 

    if (doc.DocumentElement.Name == "callback") 
    { 
     string gridId = doc.DocumentElement["arguments"]["gridId"].InnerText; 

     switch (doc.DocumentElement["action"].InnerText) 
     { 
     case "sort": 
      string sortExpression = doc.DocumentElement["arguments"]["sortExpression"].InnerText; 
      Sort(sortExpression.Split(' ')[0].Trim(), sortExpression.Split(' ')[1].Trim().Equals("ASC") ? SortDirection.Ascending : SortDirection.Descending); 
      break; 

     case "page": 
      string pageIndex = doc.DocumentElement["arguments"]["pageIndex"].InnerText; 
      this.PageIndex = Convert.ToInt32(pageIndex); 
      pagerId = base.BottomPagerRow.Cells[0].FindControl(PAGER_ID).ClientID; 
      break; 

     case "search": 
      break; 
     } 

     this.DataBind(); 
     callbackArg = String.Format("{0}¤|¤{1}¤|¤{2}", gridId, this.RenderHtml(), pagerId); 
    } 

    doc = null; 
    } 
    catch (Exception ex) 
    { 
    callbackArg = String.Format(AJAX_ERROR_FORMAT, ex.Message + "\n\n" + ex.StackTrace); 
    } 
    finally 
    { 
    if (callbackArg.Equals(string.Empty)) 
    { 
     callbackArg = String.Format(AJAX_ERROR_FORMAT, "An AJAX Error occurred!"); 
    } 
    } 
} 

#endregion 

Répondre

0

Donner un coup d'œil sur, vous voulez vous assurer que vos en-tête et pied de page téléavertisseurs sont correctement définis à TableRowSection.TableHeader ou TableRowSection.TableFooter.

Vous essayez peut-être de dessiner votre pager Bottom comme un thead et non un pied bot.

L'erreur que je crois est jeté par la WebControls.Table

8

C'est ce qui fonctionne pour moi .. les PagerRows doivent être réglés sur leurs sections appropriées.

J'ai obtenu cette astuce de http://www.codeproject.com/Members/iguigova?msg=3153516 (recherche MakeAccessible)

protected override void OnPreRender(EventArgs e) 
{ 
    base.OnPreRender(e); 

    if (Rows.Count > 0) 
    { 
     UseAccessibleHeader = true; 
     HeaderRow.TableSection = TableRowSection.TableHeader; 
     FooterRow.TableSection = TableRowSection.TableFooter; 
    } 

    if (TopPagerRow != null) 
    { 
     TopPagerRow.TableSection = TableRowSection.TableHeader; 
    } 
    if (BottomPagerRow != null) 
    { 
     BottomPagerRow.TableSection = TableRowSection.TableFooter; 
    } 
} 
+1

Cela a fonctionné pour moi. Je recevais le même message d'erreur "La table doit contenir des sections de ligne dans l'ordre de l'en-tête, du corps, puis du pied de page." Lors de la définition de PagerSettings.Position = "TopAndBottom". Cela l'a réparé. – cjuk

+0

Si je pouvais je voudrais upvote ceci plusieurs fois! Life Saver. J'ai eu la même erreur que cjuk et cela non seulement a effacé l'erreur, mais a permis aux données jQuery de fonctionner. Cela semble également être la réponse définitive à http://stackoverflow.com/questions/15756074/exception-while-binding-jquery-datatable-to-gridview, si vous souhaitez y répondre également. – RJB

+0

Après 6 heures de recherche j'ai eu la réponse parfaite. Cette solution est une saveur de vie. +1 de moi Dave – Debaprasad