A D
A D

Reputation: 307

Change dynamically the field bound to a TextBox into an ASP.Net GridView

I have a gridview that I populate with List<>. GridView's columns are TextBoxes (as TemplateField). The list might contain objects from 2 different custom classes whose fields to display are not exactly the same.

For class1, I need to display in GridView:

class1.Name

class1.field1

For class2, I need to display in GridView:

class2.Name

class2.field2

So I can setup the gridview into the aspx so that it displays the class1 items:

        <asp:GridView ID="DG_Table" runat="server" style="z-index: 1;
                    autogeneratecolumns="False" 
            onrowcommand="DG_Table_RowCommand"  
            <Columns>


 <asp:TemplateField HeaderText="Name" >
 <ItemTemplate>
 <asp:TextBox ID="Name" runat="server" Text='<%# Bind("Name") %>'></asp:TextBox>
 </ItemTemplate>

 <asp:TemplateField HeaderText="field1" >
 <ItemTemplate>
 <asp:TextBox ID="field1" runat="server" Text='<%# Bind("field1") %>'></asp:TextBox>
 </ItemTemplate>

 </Columns>
 </asp:GridView>

Displaying a List<Class1> into the DataGrid works fine. Now, if I want to display items of class2 into the datagrid, I will do something like:

DG_Table.DataSource = new List<Class2>;
DG_Table.DataBind();

This will obviously cause this kind of error : An exception of type 'System.Web.HttpException' occurred in System.Web.dll but was not handled in user code

Additional information: DataBinding: 'Class2' does not contain a property with the name 'Field1'.

So I suppose that, before binding to the List, I need to convert my second column into the code behind. What would be the equivalent of

Text='<%# Bind("field1") %>'

into the code behind?

I expected something like this :

((TextBox)DG_Table.Columns[2]).Text = "";

But this conversion is not allowed.

Thx in advance.

Upvotes: 1

Views: 1727

Answers (2)

Mahesh
Mahesh

Reputation: 8892

You can try using the anonymous type to bind the data just before the binding the data convert them to the anonymous types and then bind them.

Change your grid view as,

<asp:GridView ID="DG_Table" runat="server" style="z-index: 1;autogeneratecolumns="False" onrowcommand="DG_Table_RowCommand">  
   <Columns>
     <asp:TemplateField HeaderText="Name" >
      <ItemTemplate>
         <asp:TextBox ID="Name" runat="server" Text='<%# Eval("Name") %>'></asp:TextBox>
      </ItemTemplate>
   <asp:TemplateField HeaderText="field1" >
      <ItemTemplate>
        <asp:TextBox ID="field1" runat="server" Text='<%# Eval("FieldValue") %>'></asp:TextBox>
     </ItemTemplate>
 </Columns>
 </asp:GridView>

For binding your first class,

gridView1.DataSource = class1List.Select(x=> new{Name = x.Name,FieldValue = x.Field1});
gridview1.DataBind();

When binding the second class list

gridView1.DataSource = class2List.Select(x=> new{Name = x.Name,FieldValue = x.Field1});
gridview1.DataBind();

Upvotes: 1

Med.Amine.Touil
Med.Amine.Touil

Reputation: 1235

Your problem is in the second TextBox it Binds or Evals "field1" which is not a property in Class2.

You can do as same as it was mentioned in the @code of code answer or just Change the Create a Model class for the View to bind it

Class GvItemModel 
{
   public string Name {get; set;}
   public string Field{get; set;}
}

And past it always as dataSource

var dataSource = new List<CvItemModel>();
... //Load class1 or Class2 it depends on your choice

Then

DG_Table.DataSource = dataSource ;
DG_Table.DataBind();

Change your second TextBox dataSource.

<asp:TemplateField HeaderText="field1" >
 <ItemTemplate>
 <asp:TextBox ID="field1" runat="server" Text='<%# Bind("Field") %>'></asp:TextBox>
 </ItemTemplate>

Upvotes: 0

Related Questions