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

本文关键字:IValueConverter 转换 属性 绑定 Linq | 更新日期: 2023-09-27 18:26:06

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

示例:

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

过滤的UserInput:value="zero"

===>where子句"value''''"zero''"

但在我的linq中,与userInput"零"相比,我得到了PropertyValue 0

我已经提取了绑定值转换器到一个数组。所以我有转换器实例来用转换器转换我的模型中的属性。转换(propValue,null,null)

1) 有没有一种方法可以用普通的linq语法来实现这一点。我发现,如果paramter数组只有一个字典,它将在Dynamic.cs中转换为一个名为dict的扩展名。这可能有帮助吗?我的实际linq是:

创建可查询:

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

分配过滤器字符串:

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实现表达式的方法。但我找不到构造ExpressionCall的方法,所以当过滤完成时,模型中的值将转换为进行比较所显示的值。

我在左边是我的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?这行得通吗??

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

我找到了以下解决方案。在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;
}

在返回属性码字段表达式之前,我调用此方法

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。该参数是一个dict,其字段名称为IColumnInfoObjects。在ParseIdentifier方法中,您可以从dict.

中提取IColumnInfoObject