您将获得:位于ASP.NET DataGrid内的UI控件(例如TextBox)的引用。
您的任务:找到DataGrid列的标题。
我找到了以下解决方案,但我并不特别喜欢它,因为(a)它很复杂,(b)它(ab)使用有关DataGrid的HTML表示的知识:
从UI控件(ctl
)开始,遍历Parent
属性,直到到达TableCell(tc
)及其父DataGridItem(dgi
)
在DataGrid的index
属性(Cells
)中获取TableCell的索引(dgi.Cells.Cast<TableCell>().ToList().IndexOf(tc)
)。
进一步向上遍历Parent
属性,直到到达DataGrid(grid
),然后使用以下索引访问标题文本:grid.Columns(index).HeaderText
。
我确信这个问题有一个更优雅的解决方案。它是什么?
答案 0 :(得分:1)
DataGrid
或GridView
?一般来说,你的TextBox
和标题之间没有任何关系,所以没有真正优雅的方式。
这是我提出的最好的,但我怀疑它比你的方法更优雅:
GridView
:
protected void TextBox_TextChanged(object sender, EventArgs e)
{
TextBox txt = (TextBox)sender;
GridViewRow row = (GridViewRow)txt.NamingContainer;
GridView grid = (GridView)row.NamingContainer;
DataControlField column = grid.Columns.Cast<DataControlField>()
.Select((c, Index) => new { Column = c, Index })
.Where(x => row.Cells[x.Index].GetControlsRecursively().Contains(txt))
.Select(x => x.Column)
.FirstOrDefault();
if (column != null)
{
string headerText = column.HeaderText;
}
}
DataGrid
:
protected void TextBox_TextChanged(object sender, EventArgs e)
{
TextBox txt = (TextBox)sender;
DataGridItem item = (DataGridItem)txt.NamingContainer;
DataGrid grid = (DataGrid)item.NamingContainer;
DataControlField column = grid.Columns.Cast<DataControlField>()
.Select((c, Index) => new { Column = c, Index })
.Where(x => item.Cells[x.Index].GetControlsRecursively().Contains(txt))
.Select(x => x.Column)
.FirstOrDefault();
if (column != null)
{
string headerText = column.HeaderText;
}
}
我正在使用此扩展方法以递归方式查找控件:
public static IEnumerable<Control> GetControlsRecursively(this Control parent)
{
foreach (Control c in parent.Controls)
{
yield return c;
if (c.HasControls())
{
foreach (Control control in c.GetControlsRecursively())
{
yield return control;
}
}
}
}
此方法使用gridView.Columns
集合作为源,因为您要查找查找列。它需要通过TextBox
/ GridViewRow
找到DataGridItem
,并在此项/行的每个单元格中进行递归搜索。如果找到对TextBox
的引用,则会找到标题。
请注意,您无法使用item.Cells[x.Index].FindControl(txt.ID)
,因为FindControl
首次尝试查找NamingContainer
/ GridViewRow
控件的DataGridItem
,因此它没有帮助搜索细胞。