title: Populate GridView with object data
body: <p>Wondering the best way to populate a GridView with my object data.</p>
  
  <p>I have to show a product list from an complex object <code>Sale</code>, whose structure is something like this:</p>
  
  <pre><code>class Sale {
      int id;
      List&lt;SaleItem&gt; saleItems;
  }
  
  class SaleItem {
      int id;
      int quantity;
      Product product;
  
      BillingAddress billingAddress;
      ShippingAddress shippingAddress;
  }
  
  class Product {
      int id;
      string name;
      List&lt;BuyingConfiguration&gt; buyingConfigurations;
  }
  
  class BuyingConfiguration {
      string name; // like size, color, material
      string value;
  }
  </code></pre>
  
  <p>and my grid should look like this:</p>
  
  <pre><code>Sale Items
  +---------+---+------------+------------+----------------+
  | Name    | # | B. Address | S. Address | Configurations |
  +---------+---+------------+------------+----------------+
  | Ferrari | 2 | --         | --         | Color: red     |
  |         |   |            |            | Engine: Xyz    |
  +---------+---+------------+------------+----------------+
  | Jax     | 1 | --         | --         | Color: blue    |
  |         |   |            |            | Engine: Abc    |
  +---------+---+------------+------------+----------------+
  </code></pre>
  
  <p>Should I implement an ObjectDataSource for my <code>Sale</code> object? Is there any better solution?</p>
  
  <hr>
  
  <p>EDIT 2: Let me try to make myself clear: the problem is not how to the display configurations. 
  My problem is that the <code>Sale</code> object is returned to my code from the persistence layer, thats the why I dont want the GridView to access Database directly. Instead, it needs to load all its data from my <code>Sale</code> object, how to achieve that?</p>
  
  <hr>
  
  <p>EDIT:</p>
  
  <p>The Grid markup as requested:</p>
  
  <pre><code>&lt;asp:GridView runat="server" ID="GridProdutos" OnRowDataBound="GridProdutos_OnRowDataBound"
      AutoGenerateColumns="False"&gt;
      &lt;Columns&gt;
          &lt;asp:BoundField HeaderText="Name" /&gt;
          &lt;asp:BoundField HeaderText="#" /&gt;
          &lt;asp:BoundField HeaderText="B. Address" /&gt;
          &lt;asp:BoundField HeaderText="S. Address" /&gt;
          &lt;asp:BoundField HeaderText="Configurations" /&gt;
      &lt;/Columns&gt;
  &lt;/asp:GridView&gt;
  </code></pre>
  
  <hr>
  
  <p>Ugly solution so far, using OnRowDataBound (I want to avoid that!):</p>
  
  <pre><code>protected void GridProdutos_OnRowDataBound(object sender, GridViewRowEventArgs e) {
      if (e.Row.DataItem == null)
          return;
  
      SaleItem item = (SaleItem )e.Row.DataItem;
  
      e.Row.Cells[0].Text = item.product.name;
      e.Row.Cells[1].Text = item.quantity.ToString();
  
      StringBuilder sbConfigurations = new StringBuilder();
  
      foreach (BuyingConfiguration configurationItem in item.product.buyingConfigurations) {
          sbConfigurations.AppendFormat("{0}: {1}&lt;br /&gt;", configurationItem.name, configurationItem.value);
      }
      e.Row.Cells[4].Text = sbConfigurations .ToString();
  }
  </code></pre>