Как получить значение ячейки по имени столбца, а не по индексу в GridView в asp.net
У меня есть gridview
в asp.net и теперь я хочу значение ячейки по имени столбца, но не по индексу ячейки.
Как было бы возможно получить значение ячейки по имени столбца ячейки
13 ответов
GridView
не действует как имена столбцов, так как это datasource
свойство знать эти вещи.
Если вам все еще нужно знать индекс по имени столбца, то вы можете создать вспомогательный метод, который будет делать это как gridview
Заголовок обычно содержит эту информацию.
int GetColumnIndexByName(GridViewRow row, string columnName)
{
int columnIndex = 0;
foreach (DataControlFieldCell cell in row.Cells)
{
if (cell.ContainingField is BoundField)
if (((BoundField)cell.ContainingField).DataField.Equals(columnName))
break;
columnIndex++; // keep adding 1 while we don't have the correct name
}
return columnIndex;
}
помните, что код выше будет использовать BoundField
... тогда используйте это как:
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
int index = GetColumnIndexByName(e.Row, "myDataField");
string columnValue = e.Row.Cells[index].Text;
}
}
Я настоятельно рекомендую вам использовать TemplateField
чтобы иметь свои собственные элементы управления, тогда проще получить такие элементы управления, как:
<asp:GridView ID="gv" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblName" runat="server" Text='<%# Eval("Name") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
а затем использовать
string columnValue = ((Label)e.Row.FindControl("lblName")).Text;
Хотя это и долгое время, но этот относительно небольшой фрагмент кода кажется простым для чтения и получения:
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
int index;
string cellContent;
foreach (TableCell tc in ((GridView)sender).HeaderRow.Cells)
{
if( tc.Text.Equals("yourColumnName") )
{
index = ((GridView)sender).HeaderRow.Cells.GetCellIndex(tc);
cellContent = ((GridView)sender).SelectedRow.Cells[index].Text;
break;
}
}
}
Вы можете использовать DataRowView, чтобы получить индекс столбца.
void OnRequestsGridRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var data = e.Row.DataItem as DataRowView;
// replace request name with a link
if (data.DataView.Table.Columns["Request Name"] != null)
{
// get the request name
string title = data["Request Name"].ToString();
// get the column index
int idx = data.Row.Table.Columns["Request Name"].Ordinal;
// ...
e.Row.Cells[idx].Controls.Clear();
e.Row.Cells[idx].Controls.Add(link);
}
}
}
Ячейки заголовка строки иногда не будут работать. Это просто вернет столбец Index. Это поможет во многих отношениях. Я знаю, что это не тот ответ, который он запрашивает. Но это поможет многим людям.
public static int GetColumnIndexByName(GridView gridView, string columnName)
{
for (int i = 0; i < gridView.Columns.Count ; i++)
{
if (gridView.Columns[i].HeaderText.ToUpper() == columnName.ToUpper() )
{
return i;
}
}
return -1;
}
Основано на чем-то, найденном в Code Project
Как только таблица данных объявлена на основе источника данных сетки, ищите индекс столбца по имени столбца из коллекции столбцов. На этом этапе используйте индекс по мере необходимости для получения информации или форматирования ячейки.
protected void gridMyGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataTable dt = (DataTable)((GridView)sender).DataSource;
int colIndex = dt.Columns["MyColumnName"].Ordinal;
e.Row.Cells[colIndex].BackColor = Color.FromName("#ffeb9c");
}
}
Для любителей лямбды
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var boundFields = e.Row.Cells.Cast<DataControlFieldCell>()
.Select(cell => cell.ContainingField).Cast<BoundField>().ToList();
int idx = boundFields.IndexOf(
boundFields.FirstOrDefault(f => f.DataField == "ColName"));
e.Row.Cells[idx].Text = modification;
}
}
Небольшая ошибка с indexcolumn в ответе Александра: нам нужно позаботиться о столбце "not found":
int GetColumnIndexByName(GridViewRow row, string columnName)
{
int columnIndex = 0;
int foundIndex=-1;
foreach (DataControlFieldCell cell in row.Cells)
{
if (cell.ContainingField is BoundField)
{
if (((BoundField)cell.ContainingField).DataField.Equals(columnName))
{
foundIndex=columnIndex;
break;
}
}
columnIndex++; // keep adding 1 while we don't have the correct name
}
return foundIndex;
}
а также
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
int index = GetColumnIndexByName(e.Row, "myDataField");
if( index>0)
{
string columnValue = e.Row.Cells[index].Text;
}
}
}
Мы можем сделать это в одной строке кода. Не нужно ничего перебирать или вызывать другие методы.
protected void GridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string cellValue = e.Row.Cells[e.Row.Cells.GetCellIndex(e.Row.Cells.Cast<DataControlFieldCell>().FirstOrDefault(cell => cell.ContainingField.HeaderText == "columnName"))].Text;
}
}
protected void gvResults_PreRender(object sender, EventArgs e)
{
var gridView = (GridView)sender;
gridView.GetColumnByName("YourDataBoundDataField").Visible = true;
}
Расширение:
public static DataControlField GetColumnByName(this GridView gridView, string columnName)
{
int columnIndex = -1;
for (int i = 0; i < gridView.Columns.Count; i++)
{
if (gridView.Columns[i].HeaderText.Trim().Equals(columnName, StringComparison.OrdinalIgnoreCase))
{
columnIndex = i;
break;
}
}
if (columnIndex == -1)
{
throw new ArgumentOutOfRangeException("GridViewRow does not have the column with name: " + columnName);
}
return gridView.Columns[columnIndex];
}
Основная причина, по которой это будет сложно, заключается в том, что ячейки gridview не имеют доступных имен ячеек (тьфу).
Чтобы обойти этот недостаток, вы можете создать метод расширения (мой находится в VB.NET, но у @Dmitriyh, похоже, есть аналогичное решение на C#).
Чтобы обойти это, убедитесь, что HeaderText ячеек gridview имеет то же значение, что и имена ячеек, и получите значения через это имя HeaderText.
Вот методы расширения, которые вам понадобятся для строк и целых чисел в фрагменте кода VB.NET, который я сделал
Public Shared Function GetStringByCellName(pGridViewRow As GridViewRow, pCellName As String) As String
For Each myCell As DataControlFieldCell In pGridViewRow.Cells
If myCell.ContainingField.ToString() = pCellName Then
Return myCell.Text
End If
Next
Return Nothing
End Function
И разница для целых чисел в синтаксическом анализе/приведении
Public Shared Function GetIntegerByCellName(pGridViewRow As GridViewRow, pCellName As String) As Integer
For Each myCell As DataControlFieldCell In pGridViewRow.Cells
If myCell.ContainingField.ToString() = pCellName Then
Return Integer.Parse(myCell.Text)
End If
Next
Return Nothing
End Function
И вызов функций выглядел бы так, если бы он был в классе.
Dim columnNamesStringValue As String = ExtensionMethodsClassName.GetStringByCellName(pGridViewRow, "stringOfColumnName")
Dim columnNamesIntegerValue As Integer = ExtensionMethodsClassName.GetIntegerByCellName(pGridViewRow, "stringOfColumnName")
имейте в виду, что вы не всегда можете получить значение, а вместо этого можете получить
Прежде чем вы (возможно, попытаетесь поместить значение в свою базу данных), сначала убедитесь, что это не ничто, проверив, что это не ничто. Однако, если вы хотите вставить в базу данных, может быть лучше вернутьSystem.DBNull
вместо Nothing из предоставленных мной методов расширения. (НЕ ПРОВЕРЯЙТЕ И НЕ ВСТАВЛЯЙТЕ ДРУГИЕ НУЛИ илиNothing
КАКDBNull
'С. РАЗЛИЧНЫЕ ВИДЫNULL
'ПЕСОКNOTHINGS
НЕ РАВНЫ)
If (columnNamesStringValue IsNot Nothing)
//get the value of a gridview
public string getUpdatingGridviewValue(GridView gridviewEntry, string fieldEntry)
{//start getGridviewValue
//scan gridview for cell value
string result = Convert.ToString(functionsOther.getCurrentTime());
for(int i = 0; i < gridviewEntry.HeaderRow.Cells.Count; i++)
{//start i for
if(gridviewEntry.HeaderRow.Cells[i].Text == fieldEntry)
{//start check field match
result = gridviewEntry.Rows[rowUpdateIndex].Cells[i].Text;
break;
}//end check field match
}//end i for
//return
return result;
}//end getGridviewValue
Можно использовать имя поля данных, если не заголовок, так легко, что решило проблему для меня. Для ASP.NET и VB:
например, для строки:
Dim Encoding = e.Row.DataItem("Кодировка").ToString().Trim()
например, для целого числа:
Dim MsgParts = Convert.ToInt32(e.Row.DataItem("CalculatedMessageParts").ToString ())
protected void CheckedRecords(object sender, EventArgs e)
{
string email = string.Empty;
foreach (GridViewRow gridrows in GridView1.Rows)
{
CheckBox chkbox = (CheckBox)gridrows.FindControl("ChkRecords");
if (chkbox != null & chkbox.Checked)
{
int columnIndex = 0;
foreach (DataControlFieldCell cell in gridrows.Cells)
{
if (cell.ContainingField is BoundField)
if (((BoundField)cell.ContainingField).DataField.Equals("UserEmail"))
break;
columnIndex++;
}
email += gridrows.Cells[columnIndex].Text + ',';
}
}
Label1.Text = "email:" + email;
}