我正在尝试创建一个具有附加功能的自定义 GridView,但我确实遇到了由“Button2”“模拟”的 PostBack 问题。在每个 PostBack(在第一个 DataBinding 之后),一个 DataRow 的内容被删除,直到 GridView 完全为空。它与 PreRender 事件中的 AddCustomControls() 有关。但我不知道如何解决这个问题。有人有想法吗?任何帮助将不胜感激。
也许下图比我的话更好地描述了这种行为。
使用 OnLoad 事件中的 DataBind() 和 OnDataBound 事件中的 AddCustomControls,它工作得很好。表在 PostBacks 之间保持完全相同。但是当我尝试实现网格的编辑时,我不能再使用这个“解决方案”(这也不是很优雅)。从逻辑上讲,TextBoxes 中的编辑值被 OnLoad 中的 DataBind() 覆盖。
不知何故,它与“headerTable.Rows.AddAt(1, controlRow);”有关。如果我执行“headerTable.Rows.Add(controlRow);” 它在最后添加了行,一切正常。所以这种标题行之后的内容被清除了......
网页配置
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<pages>
<controls>
<add tagPrefix="asp" assembly="WebApplication11" namespace="WebApplication11"/>
</controls>
</pages>
</system.web>
</configuration>
默认.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>
默认.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();
}
MightyGridView.cs
public class MightyGridView : GridView
{
public MightyGridView()
{
_images = new Dictionary<_imageTypes, string>();
_images.Add(_imageTypes.SortAsc, "data:;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAJCAYAAADpeqZqAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOwwAADsMBx2+oZAAAAAd0SU1FB9oGEAstLlCBjxcAAABWSURBVBjTY/z45TsDqYCFkYF0wMTAyMiADW/ese8/LjkmbCZt3r73PzKNYRMjAwMDMkZXuHn73v/oalBs2oTDZHRxJph2XBpQNELVMn759pOM0CMDAADRtiJL6bIYOQAAAABJRU5ErkJggg==");
_images.Add(_imageTypes.SortAscActive, "data:;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAJCAYAAADpeqZqAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9oHDgckDaeYtVQAAAA1SURBVBjTY/z//z8DqYCJgQyAU5NK2Yb/JGmCacClkYmQDdg0MhHjJHRxJmL8gC7PSLcgBwAAMRqcsjcZIwAAAABJRU5ErkJggg==");
_images.Add(_imageTypes.SortDesc, "data:;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAJCAYAAADpeqZqAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOwwAADsMBx2+oZAAAAAd0SU1FB9oGEAstDmvvr98AAABhSURBVBjTY/zy7ScDqYCJgQzA8p/hPwMDAwPDpm17/xNS7OflzAix6T8DA8N/BgY/T4gATg2ezowwtUwYErg0IPsJqhmOfdEU+Ho6M6KrwRoQMI2+OGxm/PTlOzmhRzoAADvsH5oZ616EAAAAAElFTkSuQmCC");
_images.Add(_imageTypes.SortDescActive, "data:;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAJCAYAAADpeqZqAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9oHDgckFi39fLgAAABBSURBVBjTY/z//z8DqYCJgQzAAmOolG0gaOWdrgBGFJtgAoQ0YDgPl0Z0cSZCCrAa9P//f6xYuXT9f1xyjHQLcgCoNDp3uWsOTwAAAABJRU5ErkJggg==");
_images.Add(_imageTypes.HideColumn, "data:;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAJCAYAAADpeqZqAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9oGEAsyFSzQaK0AAADHSURBVBjThZAxCoNQDIbTnsAbCM4eQfAC4uYstCdwFOd2dXNwFZzcxQtI3+bkrIKz4AW+Ln2l7WtpIJB8yf9DIoAAsq4rVVWx77topnMcR6ZpQvdHecS2bXJTSrIsYxgGNE/TFKWU2LZ90MxwvVwvBEFAXdd4nodSis8dQwTI6XTGsiz6vufb3ABd1+G6Lnme4/v+f9E8zziOQ1mWAFIUxbP+KYqiyHCP49gQPb8nIrIsi4Rh+IokSRJp25Y3+OrQNM3XGz7zDsbcHXO0jDwtAAAAAElFTkSuQmCC");
_images.Add(_imageTypes.ShowAllColumns, "data:;base64,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");
}
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)
{
// Sicherstellen, dass es nicht die Spalte mit den Bearbeiten-Buttons ist, welche keine Überschrift enthält.
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)
{
// Weg der funktionierte, jedoch mit Editing Probleme macht: OnLoad: DataBind() / OnDataBound: AddCustomControls.
// Das DataBinding überschrieb die geänderten Werte wieder.
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)
{
// todo: Improve. Backup zum resetten, etc.
DataTable dataTable = GetDataTableFromDataSource();
dataTable.Columns.Remove(((ImageButton)sender).Attributes["data-column-name"]);
DataSource = dataTable;
DataBind();
}