I am using the Kendo UI MVC Grid and I want to encapsulate boilerplate code so I don't have to duplicate the same code on every grid. Configuring the commands on the grid looks like this:
columns.Command(command =>
{
command.Custom("Edit").Text("<span class='k-icon k-edit'></span>").Click("editRecord");
command.Custom("Delete").Text("<span class='k-icon k-i-delete'></span>").Click("deleteItem");
}).Width(130);
The edit and delete are boilerplate, however there is a potential for extra custom commands depending on the grid. The type of the lambda for command is of Action<GridActionCommandFactory<T>>
. How can I abstract the boilerplate to a method or something while still allowing custom commands to be entered? Psuedo-coding it out I figure it would look something like this:
columns.Command(command =>
{
//Custom commands here
SomeConfigClass.DefaultGridCommands(command);
//Custom commands here
}).Width(130);
or maybe:
columns.Command(command =>
{
//Custom commands here
command.DefaultCommands();
//Custom commands here
}).Width(130);
And this would include the edit and delete commands. But I have no idea how to modify a lambda expression in such a way, how can I achieve this?
Well I did some more digging and it ended up not being that hard. Not sure if it's the most elegant solution but I did it like this:
public static Action<GridActionCommandFactory<T>> GetDefaultGridCommands<T>(Action<GridActionCommandFactory<T>> customCommandsBeforeDefault = null, Action<GridActionCommandFactory<T>> customCommandsAfterDefault = null) where T : class
{
Action<GridActionCommandFactory<T>> defaultCommands = x =>
{
x.Custom("Edit").Text("<span class='k-icon k-edit'></span>").Click("editRecord");
x.Custom("Delete").Text("<span class='k-icon k-i-delete'></span>").Click("deleteItem");
};
List<Action<GridActionCommandFactory<T>>> actions = new List<Action<GridActionCommandFactory<T>>>();
if(customCommandsBeforeDefault != null)
actions.Add(customCommandsBeforeDefault);
actions.Add(defaultCommands);
if(customCommandsAfterDefault != null)
actions.Add(customCommandsAfterDefault);
Action<GridActionCommandFactory<T>> combinedAction = (Action<GridActionCommandFactory<T>>) Delegate.Combine(actions.ToArray());
return combinedAction;
}
Then calling it in the grid:
columns.Command(KendoUiGridConfig.GetDefaultGridCommands<MyViewModel>()).Width(130);
The Delegate.Combine
method was what I was looking for.