如何在Linq中绑定IValueConverter以转换属性

时间:2012-02-29 19:35:36

标签: c# linq expression ivalueconverter

如何将属性值转换为用户看到的值?

示例:

PropertyValue = 0
TextBox.Text = "zero"
Converter convert from 0 --> "zero"

用于过滤的UserInput:value =“zero”

==> where子句“value = \”零\“”“

但在我的linq中,我得到的PropertyValue 0与userInput“0”相比

我已将绑定值转换器提取到数组中。所以我有转换器实例来转换我的模型中的属性与converter.Convert(propValue,null,null,null)

1)有没有办法用普通的linq语法做到这一点。我发现,如果参数数组只有一个字典,它将被转换为Dynamic.cs中一个名为extension的dict。这可能有帮助吗?我的实际linq是:

创建可查询:

var queryableList = collection.AsQueryable();
return queryableList.Provider.CreateQuery(
    Expression.Call(
        typeof(Queryable), "Cast",
        new Type[] { itemType },
        queryableList.Expression));

分配filterString:

ParameterExpression[] parameterExpressions = new ParameterExpression[] {Expression.Parameter(Source.ItemType)};
ExpressionParser parser = new ExpressionParser(Source.ColumnInfoDict, parameterExpressions, filterText, new object[0]);

LambdaExpression lambda  =Expression.Lambda(parser.Parse(typeof(bool)), parameterExpressions);

var source = Queryable;
mQuery = source.Provider.CreateQuery(
         Expression.Call(
              typeof(Queryable), "Where",
              new Type[] { Source.ItemType },
              source.Expression, Expression.Quote(lambda))).Cast<object>();

2)转换器也提供给System.Linq.Dynamic.ExpressonParser。我希望找到一种在PropertyValue周围实现Expression的方法。但是我找不到构建ExpressionCall的方法,所以当完成过滤时,模型中的值将转换为显示值bevor进行比较。

我试过这个是我的PropertyExpression:

if(converter != null)
{
   Console.Out.WriteLine(left.NodeType);

   MethodInfo methodInfo = typeof (IValueConverter).GetMethod("Convert");
   Expression[] arguments = new Expression[] {left,null,null,null};
   left= Expression.Call(**converterExpression**, methodInfo,arguments);
}

但是如何构建 converterExpression ?这会有效吗?

1 个答案:

答案 0 :(得分:0)

我找到了以下解决方案。在System.Linq.Dynamic.ExpressonParser中,我添加了方法:

private Expression ProvideValueConverter(Expression expr)
{
    Expression result = expr;
    if (mItemInfo != null)
    {
        IValueConverter converter = mItemInfo.Converter;
        if(converter != null)
        {

            Expression objTypedExpr =  Expression.Convert(expr, typeof(object));
            MethodInfo methodInfo = typeof(IValueConverter).GetMethod("Convert");

            Expression[] arguments = new Expression[] { objTypedExpr, 
                                                        Expression.Default(typeof(Type)),
                                                        Expression.Default(typeof(object)),
                                                        Expression.Default(typeof(CultureInfo))

            };
            ConstantExpression converterExpression = Expression.Constant(converter);
            MethodCallExpression callExpression = Expression.Call(converterExpression, methodInfo, arguments);
            result = Expression.Convert(callExpression, mItemInfo.ItemType);
        }
    }
    return result;
}

在返回Property-oder FieldExpression之前调用This方法:

Expression ParseMemberAccess(Type type, Expression instance) {
// some code.....
    else {
        MemberInfo member = FindPropertyOrField(type, id, instance == null);

        if (member == null)
            throw ParseError(errorPos, Res.UnknownPropertyOrField,
                             id, GetTypeName(type));
        MemberExpression me = member is PropertyInfo ? Expression.Property(instance, (PropertyInfo)member) : Expression.Field(instance, (FieldInfo)member);
        return ProvideValueConverter(me);
    }
}

mItemInfo是在DLINQ外部填充的具有适当数据的对象。它作为参数传递给DLINQ。该参数是一个带有fieldNames-IColumnInfoObjects的dict。在ParseIdentifier方法中,您可以从dict中提取IColumnInfoObject。