2012-02-29 54 views
0

如何將屬性值轉換爲用戶看到的值?如何在Linq中綁定IValueConverter以轉換屬性

實施例:

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

UserInput過濾:值= 「零」

==> where子句 「值= \」 零\ 「」」

但在我LINQ我得到的PropertyValue 0與userInput「零」相比

我已經提取了綁定的值轉換器到一個數組,因此我有轉換器實例將轉換屬性從我的模型轉換ter.Convert(propValue,null,null,null)

1)有沒有辦法用普通的linq語法來做到這一點。我發現,如果參數數組只有一個字典,它將在Dynamic.cs中被轉換爲一個名爲擴展名的字典。這可能有幫助嗎?我的實際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周圍實現表達式的方法。但是我沒有找到構建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?這會工作嗎?

+1

爲什麼你需要建立一個轉換表達式?難道你不能在創建常量之前自己進行轉換嗎? – usr 2012-02-29 19:42:50

+0

不,我不能,因爲如果我將在我的代碼中執行此操作。我必須解析filterString來查找值,查找標識符,...... linq會爲我做的所有事情。另一方面,它是不明確的,如果轉換器可能會使用ony屬性的一部分,例如位0..6表示一個顯示值,其餘表示另一個值。所以我認爲唯一可行的方法是轉換源代碼。但這樣我看到了另一個問題。 IValueConverter的返回值是一個對象。這並不是過濾的要求。我需要轉換器提供的類型。在其他情況下,我會從linkq得到CastException。 – Schorsch 2012-03-01 08:45:40

回答

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; 
} 

我返回屬性 - 奧德FieldExpression之前調用這個方法:

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外側apropriate數據對象。它比作爲參數傳遞給DLINQ。該參數是一個帶有fieldNames-IColumnInfoObjects的字典。在ParseIdentifier mehod中,您可以從字典中提取IColumnInfoObject。