向 ASP.NET Gridview 添加动态列 [英] Adding dynamic columns to an ASP.NET Gridview

查看:22
本文介绍了向 ASP.NET Gridview 添加动态列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在向 GridView 动态添加列时遇到问题.我需要根据 DropDownList 中的值更改布局——即包含的列.当用户更改此列表中的选择时,我需要删除除第一列之外的所有列,并根据选择动态添加其他列.

I'm having a problem dynamically adding columns to a GridView. I need to change the layout -- i.e. the included columns -- based on the value in a DropDownList. When the user changes the selection in this list, I need to remove all but the first column and dynamically add additional columns based on the selection.

我的标记中只定义了一个列——第 0 列,一个模板列,我在其中声明了一个 Select 链接和另一个特定于应用程序的 LinkBut​​ton.该列需要始终存在.进行 ListBoxSelection 后,我删除除第一列之外的所有列,然后重新添加所需的列(在此示例中,我已将其简化为始终添加标题"列).下面是部分代码:

I have only one column defined in my markup -- column 0, a template column, in which I declare a Select link and another application specific LinkButton. That column needs to always be there. When the ListBoxSelection is made, I remove all but the first column and then re-add the desired columns (in this sample, I've simplified it to always add a "Title" column). Here is a portion of the code:

RemoveVariableColumnsFromGrid();
BoundField b = new BoundField();
b.DataField = "Title";
this.gvPrimaryListView.Columns.Add(b);
this.gvPrimaryListView.DataBind();


private void RemoveVariableColumnsFromGrid() {
    int ColCount = this.gvPrimaryListView.Columns.Count;
    //Leave column 0 -- our select and view template column
    while (ColCount > 1) {
        this.gvPrimaryListView.Columns.RemoveAt(ColCount - 1);
        --ColCount;
    }
}

第一次运行这段代码时,我看到了静态列和动态添加的标题"列.但是,下次进行选择时,第一列将生成为空(其中没有任何内容).我看到了标题栏,我看到了它左边的第一栏——但是里面没有生成任何东西.在调试器中,我可以看到 gvPrimaryListView 确实仍然有两列,第一列(索引 0)确实是一个模板列.事实上,该列甚至保留了它在下面的标记中设置为 165px 的宽度(用于调试目的).

The first time this code runs through, I see both the static column and the dynamically added "Title" column. However, the next time a selection is made, the first column is generated empty (nothing in it). I see the title column, and I see the first column to its left -- but there's nothing generated within it. In the debugger, I can see that gvPrimaryListView does indeed still have two columns and the first one (index 0) is indeed a template column. In fact, the column even retains it's width which is set as 165px in the markup below (for debugging purposes).

有什么想法吗?

<asp:GridView ID="gvPrimaryListView" runat="server" Width="100%" AutoGenerateColumns="false"
    DataKeyNames="Document_ID" EnableViewState="true" DataSourceID="odsPrimaryDataSource"
    AllowPaging="true" AllowSorting="true" PageSize="10" OnPageIndexChanging="activeListView_PageIndexChanging"
    AutoGenerateSelectButton="False" OnSelectedIndexChanged="activeListView_SelectedIndexChanged"
    Visible="true" OnRowDataBound="CtlDocList_RowDataBound" Font-Size="8pt" Font-Names="Helvetica">
    <Columns>
        <asp:TemplateField ShowHeader="false">
            <ItemTemplate>
                <asp:LinkButton EnableTheming="false" ID="CtlSelectDocRowBtn" runat="server" Text="Select"
                    CommandName="Select" CssClass="gridbutton" OnClick="RowSelectBtn_Click" />
                <asp:ImageButton EnableTheming="false" ID="DocViewBtn" runat="server" ImageUrl="../../images/ViewDoc3.png"
                    CssClass="gridbutton" CommandName="Select" OnClick="DocViewBtn_Click" />
            </ItemTemplate>
            <ItemStyle Width="165px" />
        </asp:TemplateField>
    </Columns>
    <EmptyDataTemplate>
        <asp:Label ID="Label6" runat="server" Text="No rows found." SkinID="LabelHeader"></asp:Label>
    </EmptyDataTemplate>
</asp:GridView>

<小时>

只是一些额外的信息.


Just some additional information.

这与它是第一列的事实无关,而是与它是一个 TemplateField 的事实有关.如果我在左侧(在标记中)放置一个普通列并将 TemplateField 列向右移动,则第一列呈现良好,并且(现在是第二个)TemplateField 列消失.

It has nothing to do with the fact that it is the first column but everything to do with the fact that it is a TemplateField. If I put a normal column to the left (in the markup) and shift the TemplateField column to the right, the first column renders fine, and the (now second) TemplateField column disappears.

另一件奇怪的事情——问题不会发生在第一次回发——或第二次——但它从第三次回发开始,然后继续进行后续的回发.我被难住了.

Another strange thing -- the problem doesn't happen the first postback -- OR THE SECOND -- but it starts on the third postback and then continues for subsequent postbacks. I'm stumped.

推荐答案

我最近解决了网格视图中动态列的类似问题,也许这会有所帮助.

I recently conquered silmilar issues with dynamic columns in gridviews, perhaps this will help.

首先关闭视图状态
其次,在 oninit 事件中触发的函数中以编程方式添加列
最后,我使用以下帮助程序类在 RowDataBound 事件开始时使复选框实例化.是的,其中一些是硬编码的.

First turn the viewstate off
Second add the columns programatically in a function fired in the oninit event
Lastly I used the following helper class to cause the checkboxes to instantiate when the RowDataBound event kicked off. Yes some of it is hard coded.

哎呀这是所有的代码.有它:) 保修,等等等等...

Heck here is all the code. Have at it :) Warrenty as is, blah blah blah...

最后,因为我刚刚弄湿了 DotNet,任何提示都将不胜感激 [IE 不要扯我太多 :)].是的,在某处从网上借用"了初始代码,抱歉,我不记得了:(

Finally since I am just getting my feet wet DotNet any tips would be appreciated [IE don't rip me too much :) ]. And yes 'borrowed' the initial code from the web somewhere, sorry I cant remember off the top of my head :(

-- 在受保护的覆盖 void OnInit 中关闭此功能

-- Fire this off in protected override void OnInit

    private void GridViewProject_AddColumns()
    {
        DataSet dsDataSet = new DataSet();
        TemplateField templateField = null;

        try
        {
            StoredProcedure sp = new StoredProcedure("ExpenseReportItemType_GetList", "INTRANETWEBDB", Context.User.Identity.Name);
            dsDataSet = sp.GetDataSet();

            if (sp.RC != 0 && sp.RC != 3000)
            {
                labelMessage.Text = sp.ErrorMessage;
            }

            int iIndex = 0;
            int iCount = dsDataSet.Tables[0].Rows.Count;
            string strCategoryID = "";
            string strCategoryName = "";
            iStaticColumnCount = GridViewProject.Columns.Count;

            // Insert all columns immediatly to the left of the LAST column
            while (iIndex < iCount)
            {
                strCategoryName = dsDataSet.Tables[0].Rows[iIndex]["CategoryName"].ToString();
                strCategoryID = dsDataSet.Tables[0].Rows[iIndex]["CategoryID"].ToString();

                templateField = new TemplateField();
                templateField.HeaderTemplate = new GridViewTemplateExternal(DataControlRowType.Header, strCategoryName, strCategoryID);
                templateField.ItemTemplate = new GridViewTemplateExternal(DataControlRowType.DataRow, strCategoryName, strCategoryID);
                templateField.FooterTemplate = new GridViewTemplateExternal(DataControlRowType.Footer, strCategoryName, strCategoryID);

                // Have to decriment iStaticColumnCount to insert dynamic columns BEFORE the edit row
                GridViewProject.Columns.Insert((iIndex + (iStaticColumnCount-1)), templateField);
                iIndex++;
            }
            iFinalColumnCount = GridViewProject.Columns.Count;
            iERPEditColumnIndex = (iFinalColumnCount - 1); // iIndex is zero based, Count is not
        }
        catch (Exception exception)
        {
            labelMessage.Text = exception.Message;
        }
    }

-- 助手类

public class GridViewTemplateExternal : System.Web.UI.ITemplate
{
    #region Fields
    public DataControlRowType DataRowType;
    private string strCategoryID;
    private string strColumnName;
    #endregion

    #region Constructor
    public GridViewTemplateExternal(DataControlRowType type, string ColumnName, string CategoryID)
    {
        DataRowType = type; // Header, DataRow,
        strColumnName = ColumnName; // Header name
        strCategoryID = CategoryID;
    }
    #endregion

    #region Methods
    public void InstantiateIn(System.Web.UI.Control container)
    {
        switch (DataRowType)
        {
            case DataControlRowType.Header:
                // build the header for this column
                Label labelHeader = new Label();
                labelHeader.Text = "<b>" + strColumnName + "</b>";
                // All CheckBoxes "Look Up" to the header row for this information
                labelHeader.Attributes["ERICategoryID"] = strCategoryID;
                labelHeader.Style["writing-mode"] = "tb-rl";
                labelHeader.Style["filter"] = "flipv fliph";
                container.Controls.Add(labelHeader);
                break;
            case DataControlRowType.DataRow:
                CheckBox checkboxAllowedRow = new CheckBox();
                checkboxAllowedRow.Enabled = false;
                checkboxAllowedRow.DataBinding += new EventHandler(this.CheckBox_DataBinding);
                container.Controls.Add(checkboxAllowedRow);
                break;
            case DataControlRowType.Footer:
                // No data handling for the footer addition row
                CheckBox checkboxAllowedFooter = new CheckBox();
                container.Controls.Add(checkboxAllowedFooter);
                break;
            default:
                break;
        }
    }
    public void CheckBox_DataBinding(Object sender, EventArgs e)
    {
        CheckBox checkboxAllowed = (CheckBox)sender;// get the control that raised this event
        GridViewRow row = (GridViewRow)checkboxAllowed.NamingContainer;// get the containing row
        string RawValue = DataBinder.Eval(row.DataItem, strColumnName).ToString();
        if (RawValue.ToUpper() == "TRUE")
        {
            checkboxAllowed.Checked = true;
        }
        else
        {
            checkboxAllowed.Checked = false;
        }
    }
    #endregion
}

这篇关于向 ASP.NET Gridview 添加动态列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆