基本上,我想要一个按钮,将我的控件(即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);
}
答案 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);
}