我正在尝试在asp.net网格视图中创建动态列,并在这些动态列中插入动态下拉列表。最终结果应该类似于此:
请注意网格的右上方,其中有HSE1、HSE2等。这些列的含义将发生变化,在上面的示例中,我可能会有额外的HSE8、HSE9等。基本上,这些列是动态的。为了实现这一点,我已经完成了以下操作,这是我的网格视图的asp.net标记:
为了填充这个网格视图(绑定它),我使用以下方法:
![enter image description here](https://istack.dev59.com/PShdu.webp)
<asp:GridView ID="gvMain" runat="server"
AutoGenerateColumns="False"
Width="100%" DataKeyNames="AreaLevelCostCenterFunctionID" OnPreRender="gvMain_PreRender" >
<Columns>
<asp:TemplateField HeaderText="JobTitle" >
<ItemTemplate>
<asp:HyperLink CssClass="loaderLink" ID="hlAreaLevel" runat="server" NavigateUrl='<%# "/Views/Training/AreaLevel/Details.aspx?AreaLevelID=" +
Eval("AreaLevelCostCenter.AreaLevelID") %>' Text='<%# Eval( "AreaLevelCostCenter.AreaLevel.AreaLevel1" )%>' ToolTip="Area Level">
</asp:HyperLink>
</ItemTemplate>
<ItemStyle HorizontalAlign="Left"></ItemStyle>
<HeaderStyle HorizontalAlign="Left"></HeaderStyle>
</asp:TemplateField>
<!--HERE'S WHERE I ADD MY DYNAMIC COLUMNS -->
</Columns>
<PagerSettings Position="TopAndBottom" />
</asp:GridView>
为了填充这个网格视图(绑定它),我使用以下方法:
private void SetGvMainGridData(IEnumerable<AreaLevel> newNameList)
{
if (newNameList != null)
{
BuildGridAdditionalColumns();
gvMain.DataSource = newNameList;
gvMain.DataBind();
upData.Update();
}
}
我的问题是,每当我分页数据或者回传筛选数据时,列数都会重复。这导致每次都会重新创建相同的列。因此,我编写了一些代码来解决这个问题,但我认为它看起来不太好。参数newNameList
是HSE 1、HSE 2等课程的列表。下面是BuildGridAdditionalColumns
的作用:
private void BuildGridAdditionalColumns()
{
using (var db = DataCenterAccess.NewConnection())
{
var tManager = new TrainingManager(db, CurrentUser);
//get the courses, THE HSE 1, HSE 2, etc...
var preDefinedCourses = tManager.GetTrainingPredefinedCourses();
if (preDefinedCourses != null && preDefinedCourses.Any())
{
foreach (var course in preDefinedCourses)
{
// Declare the template field
TemplateField bfield = new TemplateField();
//Initalize the DataField value.
bfield.ItemTemplate = new GridViewTemplate(ListItemType.Item, course.TrainingPredefinedCourse1);
//Initialize the HeaderText field value.
bfield.HeaderText = course.TrainingPredefinedCourse1;
//Add the newly created bound field to the GridView.
gvMain.Columns.Add(bfield);
}
}
}
}
请注意,我是如何执行 bfield.ItemTemplate = new GridViewTemplate(ListItemType.Item, course.TrainingPredefinedCourse1);
的。我必须创建一个接口来支持它,详细信息请参见此stackoverflow帖子:在代码后台中如何向GridView添加TemplateField?
基本上,这个接口看起来像这样:
public class GridViewTemplate : ITemplate
{
//A variable to hold the type of ListItemType.
readonly ListItemType _templateType;
//A variable to hold the column name.
readonly string _columnName;
//Constructor where we define the template type and column name.
public GridViewTemplate(ListItemType type, string colname)
{
//Stores the template type.
_templateType = type;
//Stores the column name.
_columnName = colname;
}
void ITemplate.InstantiateIn(Control container)
{
if (_templateType == ListItemType.Item)
{
//Creates a new drop down list control.
DropDownList ddl = new DropDownList {ID = _columnName};
ddl.Attributes.Add("class","chosen-select");
ddl.Width = 70;
//get the data to populate ddl
var tList = Utilities.GetCourseKeys().ToList();
var selectedValues = (from t in tList select new ListItem( t.KeyValue, t.TrainingPredefinedCourseKeyID.ToString())).ToList();
//add empty option to items and bind
selectedValues.Insert(0, new ListItem());
ddl.DataSource = selectedValues;
ddl.DataBind();
// ddl.DataBinding += new EventHandler(tb1_DataBinding); //Attaches the data binding event.
container.Controls.Add(ddl); //Adds the newly created ddl to the container.
}
}
}
当我提交或刷新这些数据时,基本上会遇到两个问题。一个问题是列会重复出现。另一个问题是数据绑定停止工作(即x、y值变为空)。