2

I have an EntityDataSource I've mapped to the entity Resident which includes two navigation properties (Building1, Room1). I've set my GridView to use this EntityDataSource and set the EntityDataSource Include property to Building1, Room1 so it includes these navigation properties and have added these columns to the GridView. When I run the application instead of displaying the associated navigation property it shows this: webHousingAdmin.Building How can I get it to display the actual value? Code looks like this for GridView:

        <asp:TemplateField>
            <ItemTemplate>
                <asp:Label ID="lbl1" runat="server" Text='<%# Bind("Building1") %>' />
            </ItemTemplate>
        </asp:TemplateField>

I've gotten it to display the actual value by using the following code:

            <asp:TemplateField HeaderText="Building">
            <ItemTemplate>
                <asp:Label ID="lblBuilding" Text='<%# Bind("Building1.building_name") %>' runat="server" />
            </ItemTemplate>
        </asp:TemplateField>

But is there a simpler way to do this? This only displays the text, doesn't let me edit it...if I can do it as a boundfield that would be ideal.

Dave Mackey
  • 4,306
  • 21
  • 78
  • 136
  • 1
    It looks like you were trying to bind the property Building1, Room1, etc. directly to a column in the GridView. Since these are classes and not simple scalar properties `.ToString()` is called which returns only the class name (if you didn't overwrite it). But that's only a guess, you need to show the code to get well-founded answers. – Slauma Apr 04 '11 at 14:51

2 Answers2

2

To get something meaningful in your label you can either bind a scalar property of your Building class to the Label ...

<asp:Label ID="lbl1" runat="server" Text='<%# Bind("Building1.Name") %>' />

... or you can overwrite ToString() of the class ...

public class Building
{
    public string Name { get; set; }
    public string AnotherText { get; set; }

    public override string ToString()
    {
        return string.Concat(Name, ", ", AnotherText); // or whatever you like
    }
}

If you bind a property to the grid which is a class the binding engine will call ToString() - and this returns only the full class name (namespace dot class name) if you don't override ToString. This explains why you only see webHousingAdmin.Building in your example.

Edit

Not really related to this question: But you might encounter problems if you try to bind navigation properties with Bind (and not only Eval) for bidirectional communication between datasource and grid. Probably it won't work. See this related question and answer:

Columns of two related database tables in one ASP.NET GridView with EntityDataSource

Community
  • 1
  • 1
Slauma
  • 175,098
  • 59
  • 401
  • 420
0

This was asked years ago but I found looking for the same anwer. This is what worked for me. In the ASPX this is the complete GridView following the stated model:

<asp:EntityDataSource ID="dsResidents" runat="server"
        ConnectionString="name=connString"
        DefaultContainerName="dbContext"
        EntitySetName="Residents"
        Include="Building"
        EnableUpdate="true" />

    <asp:GridView ID="ResidentGrid" runat="server"
        DataSourceID="dsResidents"
        OnRowUpdating="ResidentsGrid_RowUpdating"
        AutoGenerateColumns="False">
        <Columns>
            <asp:CommandField ShowEditButton="True" />
            <asp:TemplateField Visible="false">
                <ItemTemplate>
                    <asp:Label ID="lblID"
                        Text='<%# Eval("residentId") %>'
                        runat="server" />
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Name">
                <ItemTemplate>
                    <asp:Label ID="lblName"
                        Text='<%# Eval("residentName") %>'
                        runat="server" />
                </ItemTemplate>
            <asp:TemplateField HeaderText="CountryCode">
                <ItemTemplate>
                    <asp:Label ID="lblCountryCode"
                        Text='<%# Eval("Building.number") %>'
                        runat="server" />
                </ItemTemplate>
                <EditItemTemplate>
                    <asp:EntityDataSource ID="dsBuildings" runat="server"
                        ConnectionString="name=connString"
                        DefaultContainerName="dbContext"
                        EntitySetName="Buildings" />

                    <asp:DropDownList ID="ddlBuilding"
                        DataSourceID="dsBuildings"
                        DataTextField="number"
                        DataValueField="id"
                        SelectedValue='<%# Eval("id") %>' <!-- I am not sure about this line -->
                        runat="server" />
                </EditItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

Note that if you create the Entity Model with the wizard, by default, the ConnectionString name is the same that the DefaultContainerName. In the backing class add the event handler for updating the grid row (OnRowUpdating):

protected void ResidentsGrid_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
    // This is for retrieving the entity object for the resident selected
    Label idLabel = (Label)ResidentsGrid.Rows[e.RowIndex].Cells[1].FindControl("lblID");
    int residentId = int.Parse(idLabel.Text);

    // And this is for the building selected in the dropdown
    DropDownList ddl = (DropDownList)ResidentsGrid.Rows[e.RowIndex].Cells[4].FindControl("ddlBuilding");
    // I would like to say that the cell index is the column position but as I know it isn't

    using (dbContext ctx = new dbContext())
    {
        Resident resident = ctx.Residents
            .Where(res => res.residentId == residentId).First();

        Building selectedBuilding = ctx.Buildings
            .Where(bld => bld.id == ddl.SelectedItem.Value).First();

        resident.Building = selectedBuilding;

        ctx.SaveChanges();
    }
}
sillo01
  • 604
  • 6
  • 13