代碼: 選擇全部
@(Html.Kendo().Grid<ViewModel>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(p => p.PurchaseOrderNo).ClientTemplate(
Html.ActionLink("#=PurchaseOrderNo#", "Edit",
new { area = "Purchasing", controller = "PurchaseOrder", id = "#=Id#" })
.ToHtmlString());
})
)
期望:
代碼: 選擇全部
@(Html.Kendo().Grid<ViewModel>()
.Name("Grid")
.Columns(columns =>
{
columns.ActionLink(t => t.PurchaseOrderNo, "Edit", "PurchaseOrder", (item) => new { area = "Purchasing", id = "#=Id#" });
})
)
開始:
代碼: 選擇全部
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Web.Mvc;
using System.Web.Routing;
using Kendo.Mvc.UI.Fluent;
namespace Extensions
{
public static class TelerikGridExtensions
{
public static GridBoundColumnBuilder<T> ActionLink<T, TProperty>(this GridColumnFactory<T> factory, Expression<Func<T, TProperty>> linkText
, string action, string controller, Expression<Func<T, object>> routeValues)
where T : class
{
if (string.IsNullOrEmpty(controller))
controller = factory.Container.ViewContext.Controller.GetType().Name.Replace("Controller", "");
var urlHelper = new UrlHelper(factory.Container.ViewContext.RequestContext);
if (!(routeValues.Body is NewExpression))
throw new ArgumentException("routeValues.Body must be a NewExpression");
RouteValueDictionary routeValueDictionary = ExtractClientTemplateRouteValues(((NewExpression)routeValues.Body));
var link = urlHelper.Action(action, controller, routeValueDictionary);
string lintTextString = string.Format("#= {0} #", ((MemberExpression)linkText.Body).Member.Name);
var clientTemplate = string.Format(@"<a href=""{0}"">{1}</a>", link, lintTextString);
return factory.Bound(linkText).Template(x =>
{
var actionUrl = urlHelper.Action(action, controller, routeValues.Compile().Invoke(x));
return string.Format(@"<a href=""{0}"">{1}</a>", actionUrl, linkText.Compile().Invoke(x));
}).ClientTemplate(clientTemplate);
}
private static RouteValueDictionary ExtractClientTemplateRouteValues(NewExpression newExpression)
{
RouteValueDictionary routeValueDictionary = new RouteValueDictionary();
for (int index = 0; index < newExpression.Arguments.Count; index++)
{
var argument = newExpression.Arguments[index];
var member = newExpression.Members[index];
object value;
switch (argument.NodeType)
{
case ExpressionType.Constant:
value = ((ConstantExpression)argument).Value;
break;
case ExpressionType.MemberAccess:
MemberExpression memberExpression = (MemberExpression)argument;
if (memberExpression.Expression is ParameterExpression)
value = string.Format("<#= {0} #>", memberExpression.Member.Name);
else
value = GetValueOfExpression(memberExpression.Member, memberExpression); //GetValue(memberExpression);
break;
default:
throw new InvalidOperationException("Unknown expression type!");
}
routeValueDictionary.Add(member.Name, value);
}
return routeValueDictionary;
}
private static object GetValueOfExpression<T>(T target, Expression exp)
{
if (exp == null)
{
return null;
}
else if (exp.NodeType == ExpressionType.Parameter)
{
return target;
}
else if (exp.NodeType == ExpressionType.Constant)
{
return ((ConstantExpression)exp).Value;
}
else if (exp.NodeType == ExpressionType.Lambda)
{
return exp;
}
else if (exp.NodeType == ExpressionType.MemberAccess)
{
var memberExpression = (MemberExpression)exp;
var parentValue = GetValueOfExpression(target, memberExpression.Expression);
if (parentValue == null)
{
return null;
}
else
{
if (memberExpression.Member is PropertyInfo)
return ((PropertyInfo)memberExpression.Member).GetValue(parentValue, null);
else
return ((FieldInfo)memberExpression.Member).GetValue(parentValue);
}
}
else if (exp.NodeType == ExpressionType.Call)
{
var methodCallExpression = (MethodCallExpression)exp;
var parentValue = GetValueOfExpression(target, methodCallExpression.Object);
if (parentValue == null && !methodCallExpression.Method.IsStatic)
{
return null;
}
else
{
var arguments = methodCallExpression.Arguments.Select(a => GetValueOfExpression(target, a)).ToArray();
// Required for comverting expression parameters to delegate calls
var parameters = methodCallExpression.Method.GetParameters();
for (int i = 0; i < parameters.Length; i++)
{
if (typeof(Delegate).IsAssignableFrom(parameters[i].ParameterType))
{
arguments[i] = ((LambdaExpression)arguments[i]).Compile();
}
}
if (arguments.Length > 0 && arguments[0] == null && methodCallExpression.Method.IsStatic &&
methodCallExpression.Method.IsDefined(typeof(ExtensionAttribute), false)) // extension method
{
return null;
}
else
{
return methodCallExpression.Method.Invoke(parentValue, arguments);
}
}
}
else
{
throw new ArgumentException(
string.Format("Expression type '{0}' is invalid for member invoking.", exp.NodeType));
}
}
private static object GetValue(MemberExpression exp)
{
// expression is ConstantExpression or FieldExpression
if (exp.Expression is ConstantExpression)
{
return (((ConstantExpression)exp.Expression).Value)
.GetType()
.GetField(exp.Member.Name)
.GetValue(((ConstantExpression)exp.Expression).Value);
}
else if (exp.Expression is MemberExpression)
{
return GetValue((MemberExpression)exp.Expression);
}
else
{
throw new NotImplementedException();
}
}
}
}
http://www.codeproject.com/Articles/228870/Telerik-MVC-Grid-ActionLink-column?msg=4081136#xx4081136xx