/// <summary> /// Converts source values to a value for the binding target. /// </summary> /// <param name="values">The array of values that the source bindings produces.</param> /// <param name="targetType">The type of the binding target property.</param> /// <param name="parameter">The converter parameter to use.</param> /// <param name="culture">The culture to use in the converter.</param> /// <returns>A converted value.</returns> public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { try { // First time around we parse the evaluation input if (_eval == null) { _eval = new Eval(_language); _eval.ResolveIdentifier += new EventHandler<ResolveIdentifierEventArgs>(OnResolveIdentifier); _eval.Parse(_expression); } // Every time we evaluate we could throw an exception. This is because each time around the // bindings can provide values of different types. So first time round the binding has an // integer and so works correctly but next time it could provide a string and cause a type // error in the evaluation. EvalResult ret = _eval.Evaluate(values); // Null means we have no result to provide if (ret == null) return DependencyProperty.UnsetValue; else { // If the return type is different to the target type if (ret.Value.GetType() != targetType) { // If possible we perform an implicit conversion to the target TypeCode targetTypeCode = Type.GetTypeCode(targetType); if (ImplicitConverter.CanConvertTo(targetTypeCode, ret.Value, _language)) ret.Value = ImplicitConverter.ConvertTo(targetTypeCode, ret.Value, _language); else { // Use type converters to attempt an explicit conversion ret.Value = ConvertUsingConverter(ret, targetType); } } return ret.Value; } } catch (ParseException pe) { Console.WriteLine("EvalBinding Parsing Exception : {0} : Index '{1}'", pe.Message, pe.Index); return DependencyProperty.UnsetValue; } catch (Exception e) { Console.WriteLine("EvalBinding Evaluation Exception : {0} : Eval '{1}'", e.Message, _eval.ToString()); return DependencyProperty.UnsetValue; } }
/// <summary> /// Initialize a new instance of the EvalNodeIdentifier class. /// </summary> /// <param name="eval">Owning eval instance..</param> /// <param name="identifier">Specifies identifier of the member to call.</param> /// <param name="language">Language used for evaluation.</param> public EvalNodeIdentifier(Eval eval, string identifier, Language language) { _eval = eval; _identifier = identifier; _language = language; }
public static void TestEvalFailedError(string input, object thisArray, Language language) { try { Eval eval = new Eval(input, language); eval.Evaluate(thisArray); } catch (ParseException pe) { throw new ApplicationException("Eval parse error not expected. Input string '" + input + "' and parse error at index '" + pe.Index.ToString() + "'."); } catch (Exception) { return; } throw new ApplicationException("Eval error expected but not found. Input string '" + input + "'."); }
public static void TestEvalFailedParseError(string input, int errorIndex, Language language) { try { Eval eval = new Eval(input, language); throw new ApplicationException("Eval parse error expected but not found. Input string '" + input + "' and expected error at index '" + errorIndex.ToString() + "'."); } catch (ParseException pe) { if (pe.Index == errorIndex) return; else throw new ApplicationException("Eval parse error at wrong index location. Input string '" + input + "' and expected error at index '" + errorIndex.ToString() + "' but found at '" + pe.Index.ToString() + "'."); } }
public static void TestEvalSuccess(string input, TypeCode resultCode, object resultValue, object thisArray, Language language) { Eval eval = new Eval(input, language); EvalResult result = eval.Evaluate(thisArray); if ((resultCode != result.Type) || ((resultValue == null) && (result.Value != null)) || ((result.Value != null) && (Type.GetTypeCode(resultValue.GetType()) != resultCode))) throw new ApplicationException("Eval result type incorrect. Expected '" + resultCode.ToString() + "' but received '" + result.Type.ToString() + "' for input string '" + input + "'."); else { // Check result specific value switch (resultCode) { case TypeCode.Boolean: if ((Boolean)resultValue == (Boolean)result.Value) return; else break; case TypeCode.Byte: if ((Byte)resultValue == (Byte)result.Value) return; else break; case TypeCode.Char: if ((Char)resultValue == (Char)result.Value) return; else break; case TypeCode.DateTime: if ((DateTime)resultValue == (DateTime)result.Value) return; else break; case TypeCode.DBNull: if ((DBNull)resultValue == (DBNull)result.Value) return; else break; case TypeCode.Decimal: if ((Decimal)resultValue == (Decimal)result.Value) return; else break; case TypeCode.Double: if ((Double)resultValue == (Double)result.Value) return; else break; case TypeCode.Empty: if (resultValue == null) return; else break; case TypeCode.Int16: if ((Int16)resultValue == (Int16)result.Value) return; else break; case TypeCode.Int32: if ((Int32)resultValue == (Int32)result.Value) return; else break; case TypeCode.Int64: if ((Int64)resultValue == (Int64)result.Value) return; else break; case TypeCode.Object: if (resultValue == result.Value) return; else break; case TypeCode.SByte: if ((SByte)resultValue == (SByte)result.Value) return; else break; case TypeCode.Single: if ((Single)resultValue == (Single)result.Value) return; else break; case TypeCode.String: if ((String)resultValue == (String)result.Value) return; else break; case TypeCode.UInt16: if ((UInt16)resultValue == (UInt16)result.Value) return; else break; case TypeCode.UInt32: if ((UInt32)resultValue == (UInt32)result.Value) return; else break; case TypeCode.UInt64: if ((UInt64)resultValue == (UInt64)result.Value) return; else break; } throw new ApplicationException("Eval result value incorrect. Expected '" + resultValue.ToString() + "' but received '" + result.Value.ToString() + "' for input string '" + input + "'."); } }