views:

729

answers:

2

I cureently have a set up like below

Public ClassA

property _classB as ClassB

End Class

Public ClassB

property _someProperty as someProperty 

End Class

what I want to do is to databind object A to a gridview with one of the columns being databound to ClassB._someProperty. When I try to databind it as Classb._someProperty I get a "Field or Property not found on Selected Datasource" error

I have tried to use the objectContainerDataSource and also directly binding to the gridview with no success.

Has anyone come across this in the past?

+2  A: 

Ordinary databinding doesn't generally allow for expressions. Under the hood the datagrid is using reflection (rather the executing code the way DataBinder.Eval does on an ASP.NET page) to find the property that you specify to bind to a column. To do what you want it would need to evaluate the binding as an expression, work out that you were looking for a parent -> child relation, and then reflect down to that level. AFAIK the inbuilt databinding on the grid is too dumb to know how to do this.

I've had the same issue recently, and my solution was to do a LINQ projection and bind that to the grid instead. Something like the following (in C# because I'm not comfortable with the LINQ syntax in VB):

IList<ClassA> listOfClassAObjects = GetMyListOfClassAObjectsFromSomewhere();
var projection = from ClassA a in listOfClassAObjects
                 select new { SomeProperty = a.SomeProperty, 
                              SomeOtherProperty = a.SomeOtherProperty,
                              SomePropertyFromB = a.ClassB.SomeProperty };
datagrid.DataSource = projection;
datagrid.DataBind();

You'll get back a list of anonymous types containing that projection, and you can bind the appropriate column to SomePropertyFromB.

For extra encapsulation (if you do this a lot) put the projection into an extension method so you can do something like

var data = GetMyListOfClassAObjectsFromSomewhere().ProjectionForDataGrid();
datagrid.DataSource = data;
datagrid.DataBind();
DotNetGuy
This uses LINQ which I believe is only available post .net 2.0. as I am restricted to .net 2.0 is there another way?
Dean
You'll need the C# 3.0 compiler to compile this, but you can run the resulting code on the 2.0 framework quite happily. The LINQ library (System.Linq) which is in the system.core assembly is indeed part of .NET Framework 3.5, but for the above code you don't need it.
DotNetGuy
A: 

I found the way to do this is to use a template field and eval (see below)

Set the datafield as property classB and then:

<asp:TemplateField HeaderText="_someProperty">
<ItemTemplate>       
                           <%#Eval("classB._someProperty")%>

</ItemTemplate>
</asp:TemplateField>
Dean