Как скрыть столбцы в ASP.NET GridView с автоматически сгенерированными столбцами?
GridView1.Columns.Count всегда равен нулю даже SqlDataSource1.DataBind();
Но с сеткой все в порядке
я могу сделать
for (int i = 0; i < GridView1.HeaderRow.Cells.Count;i++)
Я переименовываю заголовки запроса здесь, но
GridView1.Columns[i].Visible = false;
Я не могу использовать его, потому что GridView1.Columns.Count равен 0.
Так как я могу их скрыть?
11 ответов
Попробуйте положить e.Row.Cells[0].Visible = false;
внутри RowCreated
событие вашей сетки.
protected void bla_RowCreated(object sender, GridViewRowEventArgs e)
{
e.Row.Cells[0].Visible = false; // hides the first column
}
Таким образом, он автоматически скрывает весь столбец.
У вас нет доступа к сгенерированным столбцам через grid.Columns[i]
в вашей сетке DataBound
событие.
Коллекция Columns заполняется только тогда, когда AutoGenerate Columns = false, и вы вручную генерируете столбцы.
Хороший обходной путь для этого - динамическое заполнение коллекции Columns до установки свойства DataSource и вызова DataBind().
У меня есть функция, которая вручную добавляет столбцы на основе содержимого таблицы данных, которую я хочу отобразить. После того, как я это сделал (а затем установил DataSource и вызвал DataBind(), я могу использовать коллекцию Columns, и значение Count является правильным, и я могу включать и выключать видимость столбца, как я изначально хотел.
static void AddColumnsToGridView(GridView gv, DataTable table)
{
foreach (DataColumn column in table.Columns)
{
BoundField field = new BoundField();
field.DataField = column.ColumnName;
field.HeaderText = column.ColumnName;
gv.Columns.Add(field);
}
}
Примечание. Это решение работает только в том случае, если GridView
столбцы известны заранее.
Похоже, вы используете GridView
с AutoGenerateColumns=true
, который является значением по умолчанию. Я рекомендую настройку AutoGenerateColumns=false
и добавление столбцов вручную:
<asp:GridView runat="server" ID="MyGridView"
AutoGenerateColumns="false" DataSourceID="MySqlDataSource">
<Columns>
<asp:BoundField DataField="Column1" />
<asp:BoundField DataField="Column2" />
<asp:BoundField DataField="Column3" />
</Columns>
</asp:GridView>
И только включить BoundField
для каждого поля, которое вы хотите отобразить. Это даст вам максимальную гибкость с точки зрения отображения данных.
У меня возникла та же проблема - нужно, чтобы AutogenerateColumns моего элемента управления GridView были 'true' из-за его привязки к источнику данных SQL, и поэтому мне нужно было скрыть некоторые столбцы, которые не должны отображаться в элементе управления GridView.
Чтобы сделать это, добавьте некоторый код в событие _RowDataBound вашего GridView, например, следующее (предположим, что идентификатор вашего GridView равен = 'MyGridView'):
protected void MyGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Cells[<index_of_cell>].Visible = false;
}
}
Это отлично сработает;-)
В rowdatabound
метод для 2-го столбца
GridView gv = (sender as GridView);
gv.HeaderRow.Cells[2].Visible = false;
e.Row.Cells[2].Visible = false;
Вы должны выполнить GridView1.Columns[i].Visible = false;
после того, как сетка была привязана к данным.
Попробуйте это, чтобы скрыть столбцы в ASP.NET GridView с автоматически сгенерированными столбцами, и RowDataBound/RowCreated тоже работают.
Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Or _
e.Row.RowType = DataControlRowType.Header Then // apply to datarow and header
e.Row.Cells(e.Row.Cells.Count - 1).Visible = False // last column
e.Row.Cells(0).Visible = False // first column
End If
End Sub
Protected Sub GridView1_RowCreated(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowCreated
If e.Row.RowType = DataControlRowType.DataRow Or _
e.Row.RowType = DataControlRowType.Header Then
e.Row.Cells(e.Row.Cells.Count - 1).Visible = False
e.Row.Cells(0).Visible = False
End If
End Sub
@nCdy: index_of_cell следует заменить целым числом, соответствующим порядковому номеру ячейки, которую вы хотите скрыть в коллекции.Cells.
Например, предположим, что ваш GridView представляет следующие столбцы:
КОНТАКТНОЕ ИМЯ | КОНТАКТНЫЙ НОМЕР | CUSTOMERID | АДРЕСНАЯ ЛИНИЯ 1 | ПОСТ-КОД
И вы хотите, чтобы столбец CUSTOMERID не отображался. Поскольку индексы коллекций основаны на 0, индекс вашего столбца CUSTOMERID равен..........? Это верно, 2!! Отлично. Теперь... угадайте, что вы должны положить туда, чтобы заменить ' index_of_cell '??
Я нашел ответ Стива Хибберта очень полезным. Проблема, которую описывал OP, - это проблема AutoGeneratedColumns в GridView.
В этом случае вы можете указать, какие столбцы будут "видимыми", а какие будут скрыты при привязке таблицы данных в коде.
Например: Gridview находится на странице следующим образом.
<asp:GridView ID="gv" runat="server" AutoGenerateColumns="False" >
</asp:GridView>
И затем в коде за функцию PopulateGridView вызывается во время события загрузки страницы.
protected void PopulateGridView()
{
DataTable dt = GetDataSource();
gv.DataSource = dt;
foreach (DataColumn col in dt.Columns)
{
BoundField field = new BoundField();
field.DataField = col.ColumnName;
field.HeaderText = col.ColumnName;
if (col.ColumnName.EndsWith("ID"))
{
field.Visible = false;
}
gv.Columns.Add(field);
}
gv.DataBind();
}
Выше GridView AutoGenerateColumns имеет значение False, а кодовая область используется для создания связанных полей. Одним из них является получение источника данных как источника данных через собственный процесс, который я здесь обозначил GetDataSource(). Затем один перебирает коллекцию столбцов данных. Если имя столбца соответствует заданным критериям, вы можете соответствующим образом установить видимое свойство связанного поля. Затем вы привязываете данные к виду сетки. Это очень похоже на AutoGenerateColumns="True", но у вас есть критерии для столбцов. Этот подход наиболее полезен, когда критерии скрытия и скрытия основаны на имени столбца.
Выполните итерацию по строкам GridView и сделайте ячейки целевых столбцов невидимыми. В этом примере я хочу, чтобы столбцы 4-6 были видны как есть, поэтому мы пропускаем их:
foreach (GridViewRow row in yourGridView.Rows)
{
for (int i = 0; i < rows.Cells.Count; i++)
{
switch (i)
{
case 4:
case 5:
case 6:
continue;
}
row.Cells[i].Visible = false;
};
};
Затем вам нужно будет удалить заголовки столбцов отдельно (имейте в виду, что удаление ячеек заголовков изменяет длину GridView после каждого удаления):
grdReportRole.HeaderRow.Cells.RemoveAt(0);
Как говорили другие, событие RowDataBound или RowCreated должно работать, но если вы хотите избежать объявления событий и поместить весь код чуть ниже вызова функции DataBind, вы можете сделать следующее:
GridView1.DataBind()
If GridView1.Rows.Count > 0 Then
GridView1.HeaderRow.Cells(0).Visible = False
For i As Integer = 0 To GridView1.Rows.Count - 1
GridView1.Rows(i).Cells(0).Visible = False
Next
End If
Аналогичен принятому ответу, но позволяет использовать ColumnNames и привязывается к RowDataBound().
Dictionary<string, int> _headerIndiciesForAbcGridView = null;
protected void abcGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (_headerIndiciesForAbcGridView == null) // builds once per http request
{
int index = 0;
_headerIndiciesForAbcGridView = ((Table)((GridView)sender).Controls[0]).Rows[0].Cells
.Cast<TableCell>()
.ToDictionary(c => c.Text, c => index++);
}
e.Row.Cells[_headerIndiciesForAbcGridView["theColumnName"]].Visible = false;
}
Не уверен, что это работает с RowCreated().