我想知道在GridView没有数据时,最好且最简单的方法是如何显示表格底部以进行数据输入?
将您的数据源设置为GridView所绑定的对象类型,其中一个对象填充了空值,然后隐藏该DataRow。
编辑:因为您使用的是datatable...
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();
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
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项目的优点。
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;
}
另外一点,如果您想有条件地显示网格的标题和页脚或显示空数据文本/模板,则可以在隐藏上述代码中的行之后检查您的条件,并在必要时删除该行。然后,代码将类似于以下内容:
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
理想情况下,只有在表中还没有记录时才显示虚拟行。因此,请将SelectCommand设置为以下内容:
SELECT [ID], FirstName, LastName, Email FROM Customers union SELECT 0 [ID], '' FirstName, '' LastName, '' Email where 0 in (SELECT COUNT(1) from Customers)
这样,如果计数> 0,则不会返回虚拟行。
请注意,虚拟行中没有FROM子句。