tags:

views:

1828

answers:

7

I have created an IEnumerable list of racing drivers using LINQ from a string array as such below:

string[] driverNames = {
                              "Lewis Hamilton", 
                              "Heikki Kovalainen",
                              "Felipe Massa",
                              "Kimi Raikkonen",
                              "Robert Kubica",
                              "Nick Heidfeld",
                              "Fernando Alonso",
                              "Nelson Piquet Jr",
                              "Jarno Trulli",
                              "Timo Glock",
                              "Sebastien Bourdais",
                              "Sebastien Buemi",
                              "Mark Webber",
                              "Sebastian Vettel",
                              "Nico Rosberg",
                              "Kazuki Nakajima",
                              "Adrian Sutil",
                              "Giancarlo Fisichella",
                              "Jenson Button",
                              "Rubens Barrichello"
                          };

IEnumerable<string> result = from driver in driverNames
                             orderby driver
                             select driver;

I am just keeping it simple for now.

I then bind it to a ASP.NET GridView like so below:

GV_CurrentF1Drivers.DataSource = result;
GV_CurrentF1Drivers.DataBind();

This works fine. Now I want to take the same output (result) and bind it to a repeater but no matter what I try I can not get the repeater to work and I think I am missing some key understanding of LINQ and how it works with ASP.NET.

Below is the full aspx page to show where I have got to so far. Please can somebody (gently if possible) guide me back on to the path?

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Example1.aspx.cs" Inherits="Example1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div style="float: left;">
        <asp:GridView ID="GV_CurrentF1Drivers" runat="server" />
    </div>
    <div style="float: left;">
        <asp:Repeater ID="R_CurrentF1Drivers" runat="server">
            <ItemTemplate>
                <%# Eval("driver") %></ItemTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>

I use the following code to bind the result to the Repeater:

R_CurrentF1Drivers.DataSource = result;
R_CurrentF1Drivers.DataBind();

I get the following error when I try to run the page with the Repeater in:

Exception Details: System.Web.HttpException: DataBinding: 'System.String' does not contain a property with the name 'driver'.

+5  A: 

You're getting back an enumerable of strings with no name. If you want to use the property name driver you can make an anonymous type and say:

var result = from driver in driverNames
             orderby driver
             select new { Driver = driver };

then do the databinding.

I believe you can also Eval(".") to evaluate the object itself and not a property. Also as multiple people have said below you can use <%# Container.DataItem %>.

Orion Adrian
var = from driver in driverNames ? where is the variable name ?var foo= from driver in driverNames , edit it guy ;)
Adinochestva
Sorry when I try that code I get "Error 1 Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<AnonymousType#1>' to 'System.Collections.Generic.IEnumerable<string>'. An explicit conversion exists (are you missing a cast?)"
Ian Roke
Gotta use a different name than the lower case driver I guess.
Orion Adrian
Also there's something about using anonymous types in databinding. I'm having trouble remembering it, but I actually wrote a library for getting around it dynamically at runtime. It has to do with postbacks and them not having the same class going out as coming in. But that's only really an issue if you're editing the datasource.
Orion Adrian
If you change your code to the above, you'll also have to change your ASP.net page to bind to Eval("Driver")
Orion Adrian
Thanks mate I have accepted this answer as the most complete. Can you tell me why I was getting an error when I was using IEnumerable<string> result instead of var result? It was to do with a cast. If I copy the error would you be able to help me with how to get it working?
Ian Roke
Because the databinding is looking for properties on the string object, not the value of the string. When you bind to something using Eval("Driver"), then it's going to look at the Driver property on each object. If you want just the item itself you can use Container.DataItem which represents the object in question. What you did was mix the two. You referenced it by a property, but bound it to objects that didn't have that property.
Orion Adrian
A: 

Because a string does not have a property called "driver" and you're using a list of strings this won't work. Try replacing the Eval statement with Container.DataItem

Jeroen Landheer
A: 

try

<%# Container.DataItem.ToString() %>

The eval is looking for a property named driver but you have the actuall driver name as a string. It'd be like calling "drivername".DriverName. The enumeration of your collection is working with the actual items. If you actually had a collection like IList drivers, then that would work.

Joshua Belden
+3  A: 

Change <%# Eval("driver") %> to

<%# Container.DataItem %>
Mehrdad Afshari
+1 This works well as an alternative solution too. Thanks for your help.
Ian Roke
A: 

are you sure there is no type ? as the code looks fine.

you can also use select new { Driver = driver, DriverAge = driverage, etc..}

then in your ASPX page you use this following

<ItemTemplate>
<div class="Driver"><%# Eval("Driver") %></div>
<div class="DriverAge"><%# Eval("DriverAge ") %></div>   
</ItemTemplate>

hope this helps.

A: 

or simply <%# Eval("result.Driver") %>

ruhrpott
A: 

I realize this is an old question but I wanted to point out that a string array already is IEnumerable<string> and you could just bind the array directly to the repeater using Mehrdad's answer:

<%# Container.DataItem %>
Jamie Ide