Hi,
I´m trying to create a custom GridView with additional functionality but I do have problem with PostBack which are "simulated" by "Button2". On every PostBack (after a first DataBinding) the content of one DataRow gets erased until the GridView is fully empty. It has something to do with AddCustomControls() within the PreRender event. But I don´t know how to fix this issue. Does anybody have an idea? Any help would be greatly appreciated.
Maybe the following picture describes the behavior better than my words:
http://i.stack.imgur.com/r1W7T.png[
^]
With DataBind() in the OnLoad event and AddCustomControls in the OnDataBound event it worked pretty well. The table stayed exactly the same between PostBacks. But I couldn´t use this "solution" (which is also not very elegant) anymore when I tried to implement the editing of the grid. Logically the edited values within the TextBoxes were overriden by the DataBind() in OnLoad.
Somehow it has to do with "headerTable.Rows.AddAt(1, controlRow);". If I do "headerTable.Rows.Add(controlRow);" which adds the row at the end everything works finde. So the content AFTER this kind of header row get cleared...
Web.config
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<pages>
<controls>
<add tagPrefix="asp" assembly="WebApplication11" namespace="WebApplication11"/>
</controls>
</pages>
</system.web>
</configuration>
Default.aspx
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:mightygridview
ID="mightyGridView"
runat="server"
AllowSorting="true"
AllowHiding="true"
AutoGenerateEditButton="false"
OnRowUpdating="mightyGridView_RowUpdating">
</asp:mightygridview>
<br />
<asp:Button ID="Button1" runat="server" Text="Button - Binding" onclick="Button1_Click" />
<asp:Button ID="Button2" runat="server" Text="Button - Nothing" />
</div>
</form>
</body>
</html>
Default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
DataTable tbl = new DataTable();
DataRow row;
tbl.Columns.Add("Spalte A");
tbl.Columns.Add("Spalte B");
tbl.Columns.Add("Spalte C");
row = tbl.NewRow();
row[0] = "Spalte A, Zeile 1";
row[1] = "Spalte B, Zeile 1";
row[2] = "Spalte C, Zeile 1";
tbl.Rows.Add(row);
row = tbl.NewRow();
row[0] = "Spalte A, Zeile 2";
row[1] = "Spalte B, Zeile 2";
row[2] = "Spalte C, Zeile 2";
tbl.Rows.Add(row);
row = tbl.NewRow();
row[0] = "Spalte A, Zeile 3";
row[1] = "Spalte B, Zeile 3";
row[2] = "Spalte C, Zeile 3";
tbl.Rows.Add(row);
mightyGridView.DataSource = tbl;
mightyGridView.DataBind();
}
public class MightyGridView : GridView
{
public MightyGridView()
{
_images = new Dictionary<_imageTypes, string>();
_images.Add(_imageTypes.SortAsc, "data:;base64,...");
_images.Add(_imageTypes.SortAscActive, "data:;base64,...");
_images.Add(_imageTypes.SortDesc, "data:;base64,...");
_images.Add(_imageTypes.SortDescActive, "data:;base64,...");
_images.Add(_imageTypes.HideColumn, "data:;base64,...");
_images.Add(_imageTypes.ShowAllColumns, "data:;base64,...");
}
private enum _imageTypes { SortAsc, SortAscActive, SortDesc, SortDescActive, HideColumn, ShowAllColumns }
private readonly Dictionary<_imageTypes, string> _images;
public new bool AllowSorting { get; set; }
public bool AllowHiding { get; set; }
public override object DataSource
{
get
{
return Page.Session[this.ID + ".DataSource"];
}
set
{
Page.Session[this.ID + ".DataSource"] = value;
base.DataSource = value;
}
}
private void AddCustomControlsRow()
{
if (DataSource != null)
{
if (AllowSorting || AllowHiding)
{
DataTable dataTable = GetDataTableFromDataSource();
if (dataTable.Columns.Count > 0 && dataTable.Rows.Count > 0)
{
if (this.HeaderRow != null && this.HeaderRow.Parent != null)
{
string sortExpression = dataTable.DefaultView.Sort.Replace(" ASC", "").Replace(" DESC", "");
SortDirection sortDirection = dataTable.DefaultView.Sort.EndsWith(" ASC") ? SortDirection.Ascending : SortDirection.Descending;
Table headerTable = (Table)this.HeaderRow.Parent;
GridViewRow controlRow = new GridViewRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal);
TableCell controlCell;
ImageButton imageButton;
foreach (TableCell cell in this.HeaderRow.Cells)
{
if (!(cell.Text.Replace(" ", "").Trim().Length > 0))
{
controlCell = new TableCell();
cell.Attributes.Add("style", "border-bottom: 0");
controlCell.Attributes.Add("style", "border-top: 0; text-align: center");
controlRow.Cells.Add(controlCell);
}
else
{
controlCell = new TableCell();
cell.Attributes.Add("style", "border-bottom: 0");
controlCell.Attributes.Add("style", "border-top: 0; text-align: center");
if (AllowSorting)
{
imageButton = new ImageButton();
imageButton.Attributes.Add("data-column-name", cell.Text);
imageButton.Click += new ImageClickEventHandler(SortColumnAscButton_Click);
if (sortExpression == cell.Text && sortDirection == SortDirection.Ascending)
imageButton.ImageUrl = _images[_imageTypes.SortAscActive];
else
imageButton.ImageUrl = _images[_imageTypes.SortAsc];
controlCell.Controls.Add(imageButton);
imageButton = new ImageButton();
imageButton.Attributes.Add("data-column-name", cell.Text);
imageButton.Click += new ImageClickEventHandler(SortColumnDescButton_Click);
if (sortExpression == cell.Text && sortDirection == SortDirection.Descending)
imageButton.ImageUrl = _images[_imageTypes.SortDescActive];
else
imageButton.ImageUrl = _images[_imageTypes.SortDesc];
controlCell.Controls.Add(imageButton);
controlRow.Cells.Add(controlCell);
}
if (AllowHiding)
{
imageButton = new ImageButton();
imageButton.Attributes.Add("data-column-name", cell.Text);
imageButton.Click += new ImageClickEventHandler(HideColumnButton_Click);
imageButton.ImageUrl = _images[_imageTypes.HideColumn];
controlCell.Controls.Add(imageButton);
controlRow.Cells.Add(controlCell);
}
}
}
headerTable.Rows.AddAt(1, controlRow);
}
}
}
}
}
public static DataTable GetDataTableFromIEnumerable(IEnumerable enumerable)
{
DataTable dataTable = new DataTable();
DataRow row;
PropertyInfo[] propertyInfos;
foreach (object obj in enumerable)
{
propertyInfos = obj.GetType().GetProperties();
if (dataTable.Columns.Count == 0)
foreach (PropertyInfo pi in propertyInfos)
dataTable.Columns.Add(pi.Name, pi.PropertyType);
row = dataTable.NewRow();
foreach (PropertyInfo pi in propertyInfos)
{
object value = pi.GetValue(obj, null);
row[pi.Name] = value;
}
dataTable.Rows.Add(row);
}
return dataTable;
}
private DataTable GetDataTableFromDataSource()
{
DataTable dataTable;
if (DataSource is DataTable)
dataTable = (DataTable)DataSource;
else if (DataSource is IEnumerable)
dataTable = GetDataTableFromIEnumerable((IEnumerable)DataSource);
else
throw new NotSupportedException("Typ wird nicht unterstützt.");
return dataTable;
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}
protected override void OnDataBinding(EventArgs e)
{
base.OnDataBinding(e);
}
protected override void OnDataBound(EventArgs e)
{
base.OnDataBound(e);
}
protected override void OnPreRender(EventArgs e)
{
AddCustomControlsRow();
base.OnPreRender(e);
}
protected override void OnUnload(EventArgs e)
{
base.OnUnload(e);
}
protected void SortColumnAscButton_Click(object sender, ImageClickEventArgs e)
{
DataTable dataTable = GetDataTableFromDataSource();
dataTable.DefaultView.Sort = ((ImageButton)sender).Attributes["data-column-name"] + " ASC";
DataSource = dataTable;
DataBind();
}
protected void SortColumnDescButton_Click(object sender, ImageClickEventArgs e)
{
DataTable dataTable = GetDataTableFromDataSource();
dataTable.DefaultView.Sort = ((ImageButton)sender).Attributes["data-column-name"] + " DESC";
DataSource = dataTable;
DataBind();
}
protected void HideColumnButton_Click(object sender, ImageClickEventArgs e)
{
DataTable dataTable = GetDataTableFromDataSource();
dataTable.Columns.Remove(((ImageButton)sender).Attributes["data-column-name"]);
DataSource = dataTable;
DataBind();
}