Показать нижний колонтитул gridview на пустой сетке?
Просто хотел узнать, каков наилучший и самый простой способ показать нижний колонтитул gridview для ввода данных, даже если вид grid пуст?
6 ответов
Задайте в качестве источника данных тип объекта, который вы привязываете к 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 вашего запроса, затем объедините всю полную статистику в
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, но оно также имеет то преимущество, что не требует динамического изменения набора данных (как в первый пример) и не требующий большого количества кода или необходимости развертывания пользовательских библиотек управления для вашего веб-проекта.
Вы можете создать "пустую" строку и сделать ее невидимой:
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
Обратите внимание, что здесь мы удаляем как строку DataItem (необходимо, потому что на постбеках представление сетки может перерисовывать себя без повторной привязки данных), так и саму строку GridView (необходимо, потому что к этому моменту строка уже находится в Childtable сетки, которую мы не не хочу)
Наконец, если скрытая фиктивная запись вызывает другие проблемы в вашем сеточном представлении, когда у него есть другие данные (например, некорректное разбиение на страницы), вы можете использовать аналогичный код для удаления фиктивной строки, когда в сеточном представлении больше строк.
В идеале вы хотите показывать фиктивную строку только в том случае, если в таблице еще нет записей. Так что установите ваш SelectCommand что-то вроде этого:
SELECT [ID], FirstName, LastName, электронная почта от объединения клиентов SELECT 0 [ID], '' FirstName, '' LastName, '' Email, где 0 in (SELECT COUNT(1) от клиентов)
Таким образом, если число> 0, фиктивная строка не возвращается.
Обратите внимание, что в фиктивной строке нет предложения FROM.