GridView中的动态ItemTemplate,带有动态下拉列表列

时间:2017-01-20 20:28:32

标签: c# asp.net gridview drop-down-menu

我正在尝试在asp.net gridview中创建动态列,在这些动态列中,我需要插入一个动态下拉列表。最终结果应如下所示:

enter image description here

注意此网格的右上角有HSE1,HSE2等。这些列将改变上面示例中的含义我可能有一个额外的HSE8,HSE9等。基本上这些列是动态的。为了做到这一点,我做了以下,这是我的gridview的asp.net标记:

 <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>

为了填充这个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帖子以获取更多信息:How to add TemplateField to a gridview in the code behind?

基本上,界面如下所示:

 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值变为空)。

2 个答案:

答案 0 :(得分:1)

我认为你应该动态创建整个网格,看下面的代码

                    string tempnum = "txtbox";
                    TemplateField temp1 = new TemplateField();
                    temp1.HeaderStyle.Width = Unit.Pixel(101);
                    temp1.HeaderStyle.CssClass = "headerwidth";
                    temp1.HeaderText = "txt";
                    temp1.ItemTemplate = new CreateTextBox(tempnum);
                    GridView1.Columns.Add(temp1);

答案 1 :(得分:1)

它适用于我在Page_Load中创建动态TemplateFields并在protected void Page_Init(object sender, EventArgs e) { //create a loop for the dynamic fields for (int i = 1; i < 6; i++) { //create a new template field TemplateField field = new TemplateField(); field.HeaderText = "HSE " + i; //create the new itemtemplate field.ItemTemplate = new GridViewTemplate(DataControlRowType.DataRow, "HSE_" + i); //add the field to the grid GridView1.Columns.Add(field); } } protected void Page_Load(object sender, EventArgs e) { //normal use of IsPostBack if (!IsPostBack) { //bind the gridview data GridView1.DataSource = LoadFromDataBase(); GridView1.DataBind(); } } protected void Button1_Click(object sender, EventArgs e) { Button1.Text = "PostBack is done!"; } public class GridViewTemplate : ITemplate { private DataControlRowType templateType; private string columnName; public GridViewTemplate(DataControlRowType type, string colname) { templateType = type; columnName = colname; } public void InstantiateIn(System.Web.UI.Control container) { switch (templateType) { case DataControlRowType.DataRow: DropDownList list = new DropDownList(); list.DataSource = LoadFromDataBase(); list.DataTextField = "myText"; list.DataValueField = "myValue"; list.DataBind(); container.Controls.Add(list); break; default: break; } } } 中执行GridView DataBindind的示例。我已经测试了它,如果有PostBack,则没有添加额外的列,所有DropDownLists仍然存在所有数据,并且如果它们在PostBack之前被更改,则它们的SelectedValues会正确显示。

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false"></asp:GridView>
<br />
<br />
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />

ASPX使示例完整

  UILongPressGestureRecognizer *leftLongPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(decreaseNum:)];

  UILongPressGestureRecognizer *rightLongPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(increaseNum:)];

  [leftView addGestureRecognizer:leftLongPress];
  [rightView addGestureRecognizer:rightLongPress];