Reputation: 1245
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?
Upvotes: 1
Views: 2099
Reputation: 111850
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)
);
Upvotes: 1