I've fiddled further and found that GridView does allow much more formating than I thought. Within a cell , you can format a complete subtable (multiple rows/columns). Try this in GuestBook: replace the <Columns> part of EditGuestbook.Ascx with:
<Columns>
<asp:CommandField ShowEditButton="True" ShowDeleteButton="True" ButtonType = "Image"
EditImageUrl = "EditChange.gif" CancelImageUrl="EditCancel.gif" DeleteImageUrl="EditDelete.gif" UpdateImageUrl="EditOk.gif" EditText="Modifier" CancelText="Annuler" DeleteText = "Supprimer"
UpdateText ="Valider" />
<asp:BoundField DataField="ID" HeaderText="ID" Visible="False" />
<asp:BoundField DataField="ModuleID" HeaderText="ModuleID" Visible="False" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Message" HeaderText="Message" SortExpression="Message" />
<asp:BoundField DataField="Email" HeaderText="Email" />
<asp:BoundField ApplyformatInEditMode="True" DataField="DateEntered" DataformatString="{0:d}"
HeaderText="Date" HtmlEncode="False" SortExpression="DateEntered" />
<asp:TemplateField>
<ItemTemplate>
<table>
<tr><td><asp:Label ID="lblMessage0" Text='<%# Bind("Name") %>' runat="server"></asp:Label></td>
<td><asp:Label ID="lblMessage1" Text='<%# Bind("Message") %>' runat="server"></asp:Label></td></tr>
<tr><td><asp:Label ID="Label1" Text='<%# Bind("ModuleID") %>' runat="server"></asp:Label></td>
<td><asp:Label ID="Label2" Text='<%# Bind("Email") %>' runat="server"></asp:Label></td></tr>
</table>
</ItemTemplate>
</asp:TemplateField>
</Columns>