Kendo UI Grid ActionLink Extensions

rusli
Site Admin
文章: 212
註冊時間: 週三 7月 07, 2010 9:49 pm

Kendo UI Grid ActionLink Extensions

文章rusli » 週三 2月 03, 2016 12:13 pm

問題:

代碼: 選擇全部

  @(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

回到「C#」

誰在線上

正在瀏覽這個版面的使用者:沒有註冊會員 和 1 位訪客