1

I am trying to create a generic method for HTML table building.

As part of the functionality I need, I'd like the user to be able to specify the properties that will be turned into columns.

As this is a generic method, I had thought that the user could pass in the properties they need as some sort of LINQ expression, and from that I would apply this select to the dataset, and loop through the properties to build the table data up:

  public static string BuildCollapsibleHtmlTable<T>(
        IEnumerable<T> dataSet,
        Func<T, object> tableDataColumnDefinitions,
        KeyValuePair<string, string>[] tableColumnNames,
        Func<T, object> groupByQuery,
        Func<T, decimal> groupSumQuery) where T : class, new() {

      ... implementation ..
   }

The 'tableColumnDefinitions' part is where I'm struggling (2nd parameter). I can get this to work for grouping and summing, but not for selecting columns/properties to use in the table:

var test = HtmlBuilders.BuildCollapsibleHtmlTable<Client>(
               Model.Clients,
               (clients => clients.ClientName),
               new KeyValuePair<string, string>[] { 
                   new KeyValuePair<string, string> ("Client", "tdCSSLeft"),
                   new KeyValuePair<string, string> ("Debt", "tdCSSCenter")
                },
               (client => client.ClientName),
               (client => client.TotalDebt)
           );

I seem only to be able to get it to work for pulling one property a time (and thus I'd need an array of expression). I'm not against this, but wondered if I'm going about this all wrong? Is there a easier/better way to pass an arbitrary select query as a parameter?

1 Answer 1

1

Yes, you'll need to use an array. Note that you seem to already have a similar array: KeyValuePair<string, string>[] tableColumnNames, so I don't see where the problem is.

Technically you could change the signature of your method in this way:

public static string BuildCollapsibleHtmlTable<T>(
    IEnumerable<T> dataSet,
    KeyValuePair<string, string>[] tableColumnNames,
    Func<T, object> groupByQuery,
    Func<T, decimal> groupSumQuery,
    params Func<T, object>[] tableDataColumnDefinitions
) where T : class, new() {

so that you wouldn't need to create an array when calling the method, but you could call it like

var test = HtmlBuilders.BuildCollapsibleHtmlTable<Client>(
           Model.Clients,
           //new KeyValuePair<string, string>[] { 
           new[] {  // Shorter
               new KeyValuePair<string, string> ("Client", "tdCSSLeft"),
               new KeyValuePair<string, string> ("Debt", "tdCSSCenter")
           },
           (client => client.ClientName),
           (client => client.TotalDebt),

           // tableDataColumnDefinitions
           (clients => clients.ClientName),
           (clients => clients.ClientSurname),
           (clients => clients.ClientAddress)
       );
Sign up to request clarification or add additional context in comments.

2 Comments

How would I select all properties at once using this method? (dataSet.Select(xxxxxx))
@pierre What do you want to do with all the properties together? Normally instead of using LINQ you should/would use a foreach (var row in dataSet) { for (int i = 0; i< tableDataColumnDefinitions.Length; i++) { object data = tableDataColumnDefinitions[i](row);. Now, if you want this expression can be changed to a LINQ expression, but what you'll have will be a IEnumerable<object[]> (a "list" of rows, each row an array of object[])

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.