【发布时间】:2011-03-27 03:21:11
【问题描述】:
只是想知道即使在 gridview 为空的情况下,为数据输入显示 gridview 页脚的最佳和最简单的方法是什么?
【问题讨论】:
只是想知道即使在 gridview 为空的情况下,为数据输入显示 gridview 页脚的最佳和最简单的方法是什么?
【问题讨论】:
将数据源设置为要绑定到 GridView 的对象类型,其中一个对象填充空值,然后隐藏该 DataRow。
编辑:因为您使用的是数据表...
DataTable dt = new DataTable();
// Define all of the columns you are binding in your GridView
dt.Columns.Add("AColumnName");
...
...
DataRow dr = dt.NewRow();
dt.Rows.Add(dr);
myGridView.DataSource = dt;
myGridView.DataBind();
【讨论】:
更优雅.. 扩展 GridView 并添加 ShowFooterWhenEmpty 属性,这样您就不必到处实现自定义代码。
Imports System.Web.UI.WebControls
Imports System.ComponentModel
Namespace UI.WebControls
Public Class GridViewExtended
Inherits GridView
Private _footerRow As GridViewRow
<DefaultValue(False), Category("Appearance"), Description("Include the footer when the table is empty")> _
Property ShowFooterWhenEmpty As Boolean
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(False)> _
Public Overrides ReadOnly Property FooterRow As GridViewRow
Get
If (Me._footerRow Is Nothing) Then
Me.EnsureChildControls()
End If
Return Me._footerRow
End Get
End Property
Protected Overrides Function CreateChildControls(ByVal dataSource As System.Collections.IEnumerable, ByVal dataBinding As Boolean) As Integer
Dim returnVal As Integer = MyBase.CreateChildControls(dataSource, dataBinding)
If returnVal = 0 AndAlso Me.ShowFooterWhenEmpty Then
Dim table As Table = Me.Controls.OfType(Of Table)().First
Me._footerRow = Me.CreateRow(-1, -1, DataControlRowType.Footer, DataControlRowState.Normal, dataBinding, Nothing, Me.Columns.Cast(Of DataControlField).ToArray, table.Rows, Nothing)
If Not Me.ShowFooter Then
_footerRow.Visible = False
End If
End If
Return returnVal
End Function
Private Overloads Function CreateRow(ByVal rowIndex As Integer, ByVal dataSourceIndex As Integer, ByVal rowType As DataControlRowType, ByVal rowState As DataControlRowState, ByVal dataBind As Boolean, ByVal dataItem As Object, ByVal fields As DataControlField(), ByVal rows As TableRowCollection, ByVal pagedDataSource As PagedDataSource) As GridViewRow
Dim row As GridViewRow = Me.CreateRow(rowIndex, dataSourceIndex, rowType, rowState)
Dim e As New GridViewRowEventArgs(row)
If (rowType <> DataControlRowType.Pager) Then
Me.InitializeRow(row, fields)
Else
Me.InitializePager(row, fields.Length, pagedDataSource)
End If
If dataBind Then
row.DataItem = dataItem
End If
Me.OnRowCreated(e)
rows.Add(row)
If dataBind Then
row.DataBind()
Me.OnRowDataBound(e)
row.DataItem = Nothing
End If
Return row
End Function
End Class
End Namespace
【讨论】:
另一种解决方案是始终在数据源中添加一个虚拟行,用特定值“标记”该行,然后在 RowDataBound 上隐藏该行。
更准确地说,将列“, 0 AS dummyRow”添加到查询的 SELECT 子句的末尾,然后将完整的语句 UNION ALL 添加到
SELECT NULL AS column1, NULL AS column2,...,NULL AS columnN, 1 AS dummyRow
一旦您有了查询(所有这些都可以在您的 SQLDataSource 或您的 DAL 对象中完成,您的网格代码将如下所示:
Protected Sub MyGridView_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles MyGridView.RowDataBound
If (e.Row.RowType = DataControlRowType.DataRow) AndAlso (Not e.Row.DataItem Is Nothing) AndAlso (CInt(e.Row.DataItem("dummyRow")) = 1) Then
e.Row.Visible = False
End If
End Sub
这个解决方案有一些明显的开销,因为这个检查将对结果的每一行进行,更不用说你必须改变你的 SELECT 查询,但它还有一个优点是不需要动态改变数据集(与第一个示例一样)并且不需要太多代码或不必为您的 Web 项目部署自定义控件库。
【讨论】:
作为旁注,如果您想有条件地显示网格的页眉和页脚或显示空数据文本/模板,在您使用我上面发布的代码隐藏行后,您可以检查您的情况,如有必要删除行。然后代码将如下所示:
Protected Sub MyGridView_RowDataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles MyGridView.RowDataBound
If (e.Row.RowType = DataControlRowType.DataRow) AndAlso (Not e.Row.DataItem Is Nothing) AndAlso (CInt(e.Row.DataItem("dummyRow")) = 1) Then
e.Row.Visible = False
If (ConditionToShowEmptyDataTemplate) Then
CType(e.Row.DataItem, System.Data.DataRowView).Delete()
CType(e.Row.Parent, System.Web.UI.WebControls.Table).Rows.Remove(e.Row)
End If
End Sub
请注意,这里我们删除了 DataItem 行(这是必要的,因为在回发时,gridview 可能会在没有重新数据绑定的情况下重绘自身)和 GridView Row 本身(必要的,因为此时该行已经在网格的 Childtable 中,这我们不想要)。
最后,如果隐藏的虚拟记录在您的 gridview 有其他数据时导致其他问题(例如,错误的分页),您可以使用类似的代码在 gridview 有更多行时删除您的虚拟行。
【讨论】:
您可以创建一个“空”行并使其不可见:
if (list != null && list.Any())
{
gridView.DataSource = list;
gridView.DataBind();
}
else
{
MyCustomClass item = new MyCustomClass(){Id = 0, Name = "(No Data Rows)", Active = false};
List<MyCustomClass> l = new List<MyCustomClass>();
l.Add(item);
gridView.DataSource = l;
gridView.DataBind();
gridView.Rows[0].Visible = false;
}
【讨论】:
理想情况下,如果表中还没有记录,您只想显示虚拟行。因此,将您的 SelectCommand 设置为如下所示:
选择 [ID]、名字、姓氏、来自客户的电子邮件 联盟 SELECT 0 [ID], '' FirstName, '' LastName, '' Email where 0 in (SELECT COUNT(1) from Customers)
这样如果计数 > 0,则不返回虚拟行。
请注意,虚拟行中没有 FROM 子句。
【讨论】: