如何将.aspx标记中创建的TemplateField添加到代码隐藏的GridView列中?

时间:2012-10-01 14:46:19

标签: asp.net gridview controls templatefield

基本上,我想要一个按钮,将我的控件(即TextBox,DropDownList)添加到我的GridView中。

这似乎已经足够简单了:

protected void btn_AddColumn_Click(object sender, EventArgs e)
{
    TemplateField MyTemplateField = new TemplateField();
    gv_SupplierPrices.Columns.Add(MyTemplateField);
}

说我想添加这个标记:

<asp:TemplateField>
    <ItemTemplate>
       <table style="width:100%;">
          <tr>
             <td><asp:TextBox ID="tbox_ItemPrice" runat="server"></asp:TextBox></td>
          </tr>
       </table>
     </ItemTemplate>
</asp:TemplateField>

这是问题所在。如何在我的.aspx页面上使用我在标记中创建的TemplateField并将其添加到代码隐藏的新列中?我不知道也不想在代码后面创建我的TemplateField,因为我无法创建复杂或花哨的标记。它们看起来就像是彼此相邻的控件。这很难看。

P.S。如果有人对我实际制作的东西感到好奇,我基本上将我的GridView变成了类似Excel的网格。新列表示供应商,每行表示供应商销售的项目。他们希望这样,因为在填写价格时更容易并排比较价格。


更新:我已经弄明白了。我可以简单地从代码隐藏中调用我的GridView列,代表我在标记中创建的TemplateField,然后添加它。

<asp:GridView ID="gv_SupplierTable" runat="server" AutoGenerateColumns="False" 
                        DataKeyNames="Id" DataSourceID="TestTable_DS">
                        <Columns>
                            <asp:BoundField DataField="Id" HeaderText="Id" InsertVisible="False" 
                                ReadOnly="True" SortExpression="Id" />
                            <asp:BoundField DataField="AccountType" HeaderText="AccountType" 
                                SortExpression="AccountType" />
                            <asp:TemplateField AccessibleHeaderText="MyTemplateFieldCreated in Markup">
                                <ItemTemplate>
                                    <table style="width:100%;">
                                        <tr>
                                            <td><asp:TextBox ID="tbox_ItemPrice" runat="server"></asp:TextBox></td>
                                        </tr>
                                    </table>
                                </ItemTemplate>
                            </asp:TemplateField>
                        </Columns>
                    </asp:GridView>

然后在codebehind中,我可以访问表示在标记中创建的TemplateField的列,并在按钮点击时再次添加它,如新副本:

    protected void btn_AddColumn_Click(object sender, EventArgs e)
    {
    DataControlField newColumn = this.gv_SupplierTable.Columns[2]; 
                                 //this column at index #2 from my GridView represents                  
                                 the TemplateField created in markup since the columns  
                                 at index #0 and index #1 are DataBound.
    gv_SupplierTable.Columns.Add(newColumn);
    }

3 个答案:

答案 0 :(得分:1)

您可以切换每列的可见性。

gv_SupplierPrices.Columns[10].Visible = true;

答案 1 :(得分:1)

在你的位置,我会考虑咬紧牙关并以编程方式调查创建模板化字段。这将是一件令人讨厌的事,但一旦你完成了,你就会完成。当然,您需要将它们抽象为辅助类或单独的控件。

答案 2 :(得分:0)

以下是有关向GridView动态添加列的几个示例:

protected void Page_Init(object sender, EventArgs e)
{
    btnAddColumn.Click += new EventHandler(btnAddColumn_Click);

    BoundField temp = new BoundField();
    temp.DataField = "Source";
    temp.HeaderText = "Source";
    temp.SortExpression = "Source";

    gv.Columns.Add(temp);
}

void btnAddColumn_Click(object sender, EventArgs e)
{
    TemplateField temp = new TemplateField();
    temp.HeaderText = txtNewColumn.Text;

    txtNewColumn.Text = string.Empty;

    gv.Columns.Add(temp);
}

ASPX:

<div>
    <asp:TextBox ID="txtNewColumn" runat="server" />
    <asp:Button ID="btnAddColumn" runat="server" Text="Add Column" />
</div>
<asp:GridView ID="gv"
    runat="server"
    AutoGenerateColumns="False"
    DataSourceID="dsExceptions">
    <Columns>
        <asp:BoundField DataField="Message" HeaderText="Message" />
    </Columns>
</asp:GridView>

<asp:ObjectDataSource ID="dsExceptions"
    runat="server" 
    SelectMethod="GetExceptions"
    TypeName="WebApplication.Data.MyDataContext" EnablePaging="True" 
    SelectCountMethod="GetExceptionCount" >
    <SelectParameters>
        <asp:Parameter Name="maximumRows" Type="Int32" />
        <asp:Parameter Name="startPageIndex" Type="Int32" />
        <asp:Parameter Name="startRowIndex" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

我的ObjectDataSource只是获取了我创建的Exceptions的集合,因此您可以忽略该部分代码。

所以我通过Page_Init处理程序中的代码添加了一列,并添加了一个列,其中标题文本设置为txtNewColumn中的文本。但有一件事是,如果刷新页面,它将丢失您使用页面上的按钮添加的列。您需要在按钮单击事件处理程序中添加一些代码来存储新列,因此它们在重新加载时始终位于GridView中。由于听起来这些列代表了供应商,因此您可能只想为某人添加表单以将供应商添加到您的系统中。供应商被保存在某个地方的数据库/数据存储区中,在Page_Init中,您可以从该数据存储区获取所有供应商并循环遍历它们,从而为供应商创建模板字段。它会是这样的:

// I am just creating a list here, you would pull the vendor names in from the 
// datastore here instead.
var vendors = new List<string> { "Vendor A", "Vendor B", "Vendor C" };
foreach (var vendor in vendors)
{
    TemplateField temp = new TemplateField();
    temp.HeaderText = vendor;
    gv.Columns.Add(temp);
}