Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I find three ways to solve (some) of your problems using C# and a way to extend some of these approaches using Visual Studio tools.</p> <h2>Anonymous types</h2> <p>ASP.NET can data bind to <a href="http://msdn.microsoft.com/en-us/library/bb397696.aspx" rel="nofollow">anonymous types</a>:</p> <pre><code>DataGrid.DataSource = GetAllUsers(). .AsQueryable() .Select(u =&gt; new { User = u, FullName = GetFullName(u) }); DataGrid.DataBind() </code></pre> <p>The anonymous type can still give easy access to the original type (in this example through the <code>User</code> property). This will make data binding <em>relatively</em> easy (using <code>&lt;asp:TemplateField&gt;</code>), and you have moved the complex logic to a separate method that operates on a <code>User</code> object. </p> <pre><code>&lt;%# Eval("User.FirstName") %&gt; &lt;%# Eval("User.LastName") %&gt; &lt;%# Eval("FullName") %&gt; </code></pre> <p>The data binding syntax should be placed inside the <code>ItemTemplate</code> of the <code>&lt;asp:TemplateField&gt;</code>, but I have omitted that code for brevity. Of course the last property can also be displayed using the <code>&lt;asp:BoundField&gt;</code>:</p> <pre><code>&lt;asp:BoundField DataField="FullName" /&gt; </code></pre> <p>Notice that you don't have to map <strong>each</strong> property of the original type in the anonymous type, you can just map one property to the original object. The (only?) drawback is that you can no longer use <code>&lt;asp:BoundField&gt;</code> for those properties but you must use <code>&lt;asp:TemplateField&gt;</code>. </p> <h2>Extension methods</h2> <p>To complement this approach, you could use <a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" rel="nofollow">extension methods</a> to 'attach' methods to a class even when you don't have access to the class' source:</p> <pre><code>public static class UserExtensions { public static string GetFullName(this User user) { return user.FirstName + " " + user.LastName; } } </code></pre> <p>For data binding we must use <code>&lt;asp:TemplateField&gt;</code>:</p> <pre><code>&lt;%# Eval("User.FirstName") %&gt; &lt;%# Eval("User.LastName") %&gt; &lt;%# (Container.DataItem as User).GetFullName() %&gt; </code></pre> <h2>Partial classes</h2> <p>Another option, available since C# 2.0, is to write a <a href="http://msdn.microsoft.com/en-us/library/wa80x488%28v=VS.100%29.aspx" rel="nofollow">partial class</a>, but only if the original class is also declared partial and is declared in your project (part of the same module). This approach is useful if the <code>User</code> class is generated with a tool, for instance if you use some kind of automatic database mapper tool in your project.</p> <pre><code>public partial class User { public string FullName { get { return this.FirstName + " " + this.LastName; } } } </code></pre> <p>For data binding we are now back to using '':</p> <pre><code>&lt;asp:BoundField DataField="FirstName" /&gt; &lt;asp:BoundField DataField="LastName" /&gt; &lt;asp:BoundField DataField="FullName" /&gt; </code></pre> <p>These are all possibilities of the C# compiler and the .NET runtime, so they fall in the category of techniques instead of frameworks. Of course, basic inheritance could also be used, but it may not be applicable in your situation?</p> <h2>T4 Text Templates</h2> <p>If you have very specific needs about how the data bound class should look like but can't use any of the approaches above, you can always look into <a href="http://msdn.microsoft.com/en-us/library/bb126445.aspx" rel="nofollow">T4 templates</a> in Visual Studio. (They work in ASP.NET Web Application projects but not in ASP.NET Web Site projects.) </p> <ul> <li><a href="http://www.olegsych.com/?s=t4" rel="nofollow">All posts on Oleg Sych's blog about T4 templates</a></li> </ul> <p>With these templates you can generate code at design time, for instance to create a shallow, partial class <code>UserViewModel</code> that maps all properties to an internal User object transparently. Then, using the partial class approach, you can add extra properties and methods to this type using another partial class declaration in a .cs file and simply data bind against your <code>UserViewModel</code>:</p> <pre><code>DataGrid.DataSource = GetAllUsers(). .AsQueryable() .Select(u =&gt; new UserViewModel(u)); DataGrid.DataBind() </code></pre> <p>Data bind becomes straight-forward again using <code>&lt;asp:BoundField&gt;</code>:</p> <pre><code>&lt;asp:BoundField DataField="FirstName" /&gt; &lt;asp:BoundField DataField="LastName" /&gt; &lt;asp:BoundField DataField="FullName" /&gt; </code></pre> <p>Using T4 templates you could generate these custom view model classes automatically for all your domain types. When using reflection in T4 there are caveats:</p> <ul> <li><a href="http://www.olegsych.com/2007/12/how-to-use-t4-to-generate-decorator-classes/" rel="nofollow">How to use T4 to generate Decorator classes</a></li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload