Esempio n. 1
0
        private Tuple <string, Delegate, string[], DataContainer[]> GetLambda(string expression)
        {
            Tuple <string, Delegate, string[], DataContainer[]> tuple;

            if (handlers.TryGetValue(expression, out tuple))
            {
                return(tuple);
            }
            List <ParameterExpression> parameters;
            List <DataContainer>       dataContainers;
            Expression exp = EquationTokenizer.Tokenize(expression, false).GetExpression(out parameters, out dataContainers, DynamicContext, false);
            Delegate   del = Expression.Lambda(exp, parameters.ToArray()).Compile();

            tuple = new Tuple <string, Delegate, string[], DataContainer[]>(exp.ToString(), del, parameters.Select(p => p.Name).ToArray(), dataContainers.ToArray());
            handlers.Add(expression, tuple);
            return(tuple);
        }
Esempio n. 2
0
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            for (int i = 0; i < values.Length; ++i)
            {
                if (values[i] == DependencyProperty.UnsetValue || _namedObjectType.IsInstanceOfType(values[i]) || (PTypes[i] != null && !PTypes[i].IsInstanceOfType(values[i])))
                {
                    return(DependencyProperty.UnsetValue);
                }
            }

            object result;

            try { result = _converter(values, _values); }
            catch (Exception e)
            {
                LastException = e;
                ++ExceptionCount;
                if (Debugger.IsAttached)
                {
                    Console.WriteLine("QuickMultiConverter Exception (\"" + ConvertExpression + "\") - " + e.Message + (e.InnerException != null ? " (Inner - " + e.InnerException.Message + ")" : ""));
                }
                EquationTokenizer.ThrowQuickConverterEvent(new RuntimeMultiConvertExceptionEventArgs(ConvertExpression, ConvertExpressionDebugView, values, pIndices, null, _values, parameter, this, e));
                return(DependencyProperty.UnsetValue);
            }
            finally
            {
                if (_toDataContainers != null)
                {
                    foreach (var container in _toDataContainers)
                    {
                        container.Value = null;
                    }
                }
            }

            result = CastResult(result, targetType);
            return(result);
        }
Esempio n. 3
0
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            object[] ret = new object[_convertBack.Length];

            if (ValueType != null && !ValueType.IsInstanceOfType(value))
            {
                for (int i = 0; i < ret.Length; ++i)
                {
                    ret[i] = System.Windows.Data.Binding.DoNothing;
                }
                return(ret);
            }

            for (int i = 0; i < _convertBack.Length; ++i)
            {
                try { ret[i] = _convertBack[i](value, _values); }
                catch (Exception e)
                {
                    LastException = e;
                    ++ExceptionCount;
                    if (Debugger.IsAttached)
                    {
                        Console.WriteLine("QuickMultiConverter Exception (\"" + ConvertBackExpression[i] + "\") - " + e.Message + (e.InnerException != null ? " (Inner - " + e.InnerException.Message + ")" : ""));
                    }
                    EquationTokenizer.ThrowQuickConverterEvent(new RuntimeMultiConvertExceptionEventArgs(ConvertBackExpression[i], ConvertBackExpressionDebugView[i], null, pIndices, value, _values, parameter, this, e));
                    ret[i] = DependencyProperty.UnsetValue;
                }
                ret[i] = CastResult(ret[i], targetTypes[i]);
            }
            if (_fromDataContainers != null)
            {
                foreach (var container in _fromDataContainers)
                {
                    container.Value = null;
                }
            }
            return(ret);
        }
Esempio n. 4
0
        private Tuple <string, Delegate, ParameterExpression[], DataContainer[]> GetLambda(string expression, bool convertBack)
        {
            List <ParameterExpression> parameters;
            List <DataContainer>       dataContainers;
            Expression          exp = EquationTokenizer.Tokenize(expression).GetExpression(out parameters, out dataContainers, DynamicContext);
            ParameterExpression invalid;

            if (convertBack)
            {
                invalid = parameters.FirstOrDefault(par => par.Name != "value" && (par.Name.Length != 2 || par.Name[0] != 'V' || !Char.IsDigit(par.Name[1])));
            }
            else
            {
                invalid = parameters.FirstOrDefault(par => par.Name.Length != 2 || (par.Name[0] != 'P' && par.Name[0] != 'V') || !Char.IsDigit(par.Name[1]));
            }
            if (invalid != null)
            {
                throw new Exception("\"$" + invalid.Name + "\" is not a valid parameter name for conversion " + (convertBack ? "to" : "from") + " source.");
            }
            Delegate del = Expression.Lambda(Expression.Convert(exp, typeof(object)), parameters.ToArray()).Compile();

            return(new Tuple <string, Delegate, ParameterExpression[], DataContainer[]>(exp.ToString(), del, parameters.ToArray(), dataContainers.ToArray()));
        }
Esempio n. 5
0
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            try
            {
                Tuple <string, Func <object[], object[], object>, string[], DataContainer[]> func = null;
                if (Converter != null && !toFunctions.TryGetValue(Converter, out func))
                {
                    Tuple <string, Delegate, ParameterExpression[], DataContainer[]> tuple = GetLambda(Converter, false);
                    if (tuple == null)
                    {
                        return(null);
                    }

                    List <string>       parNames = new List <string>();
                    int                 pCount   = 0;
                    ParameterExpression inputP   = Expression.Parameter(typeof(object[]));
                    ParameterExpression inputV   = Expression.Parameter(typeof(object[]));
                    int[]               inds     = new int[10];
                    foreach (var par in tuple.Item3.Where(p => p.Name[0] == 'P').OrderBy(e => e.Name))
                    {
                        parNames.Add(par.Name);
                        inds[par.Name[1] - '0'] = pCount++;
                    }
                    var arguments = tuple.Item3.Select <ParameterExpression, Expression>(par =>
                    {
                        if (par.Name[0] == 'P')
                        {
                            return(Expression.ArrayIndex(inputP, Expression.Constant(inds[par.Name[1] - '0'])));
                        }
                        return(Expression.ArrayIndex(inputV, Expression.Constant((int)(par.Name[1] - '0'))));
                    });

                    Expression exp    = Expression.Call(Expression.Constant(tuple.Item2, tuple.Item2.GetType()), tuple.Item2.GetType().GetMethod("Invoke"), arguments);
                    var        result = Expression.Lambda <Func <object[], object[], object> >(exp, inputP, inputV).Compile();
                    func = new Tuple <string, Func <object[], object[], object>, string[], DataContainer[]>(tuple.Item1, result, parNames.ToArray(), tuple.Item4);

                    toFunctions.Add(Converter, func);
                }
                Tuple <string, Func <object, object[], object>, DataContainer[]>[] backFuncs = new Tuple <string, Func <object, object[], object>, DataContainer[]> [10];
                for (int i = 0; i <= 9; ++i)
                {
                    var converter = typeof(QuickMultiConverter).GetProperty("ConvertBack" + i).GetValue(this, null) as string;
                    if (String.IsNullOrWhiteSpace(converter))
                    {
                        backFuncs[i] = new Tuple <string, Func <object, object[], object>, DataContainer[]>(null, null, new DataContainer[0]);
                        continue;
                    }
                    Tuple <string, Delegate, ParameterExpression[], DataContainer[]> tuple = GetLambda(converter, true);
                    if (tuple == null)
                    {
                        backFuncs[i] = new Tuple <string, Func <object, object[], object>, DataContainer[]>(null, null, new DataContainer[0]);
                        continue;
                    }

                    ParameterExpression val = Expression.Parameter(typeof(object));
                    ParameterExpression inV = Expression.Parameter(typeof(object[]));
                    var arguments           = tuple.Item3.Select <ParameterExpression, Expression>(par =>
                    {
                        if (par.Name[0] == 'V')
                        {
                            return(Expression.ArrayIndex(inV, Expression.Constant((int)(par.Name[1] - '0'))));
                        }
                        return(val);
                    });

                    Expression exp    = Expression.Call(Expression.Constant(tuple.Item2, tuple.Item2.GetType()), tuple.Item2.GetType().GetMethod("Invoke"), arguments);
                    var        result = Expression.Lambda <Func <object, object[], object> >(exp, val, inV).Compile();
                    backFuncs[i] = new Tuple <string, Func <object, object[], object>, DataContainer[]>(tuple.Item1, result, tuple.Item4);
                }

                if (func == null)
                {
                    func = new Tuple <string, Func <object[], object[], object>, string[], DataContainer[]>(null, null, null, null);
                }

                List <object> pTypes    = new List <object>();
                List <int>    pIndicies = new List <int>();
                List <Tuple <string, Func <object, object[], object>, DataContainer[], string> > backs = new List <Tuple <string, Func <object, object[], object>, DataContainer[], string> >();
                if (func.Item3 != null)
                {
                    foreach (string name in func.Item3)
                    {
                        int index = name[1] - '0';
                        pIndicies.Add(index);
                        pTypes.Add(typeof(QuickMultiConverter).GetProperty(name + "Type").GetValue(this, null));
                        backs.Add(new Tuple <string, Func <object, object[], object>, DataContainer[], string>(backFuncs[index].Item1, backFuncs[index].Item2, backFuncs[index].Item3, typeof(QuickMultiConverter).GetProperty("ConvertBack" + name[1]).GetValue(this, null) as string));
                    }
                }

                List <object> vals = new List <object>();
                for (int i = 0; i <= 9; ++i)
                {
                    vals.Add(typeof(QuickMultiConverter).GetProperty("V" + i).GetValue(this, null));
                }

                _parameterOrder = func.Item3;

                return(new DynamicMultiConverter(func.Item2, backs.Select(t => t.Item2).ToArray(), vals.ToArray(), Converter, func.Item1, backs.Select(t => t.Item4).ToArray(), backs.Select(t => t.Item1).ToArray(), pTypes.Select(t => QuickConverter.GetType(t)).ToArray(), pIndicies.ToArray(), QuickConverter.GetType(ValueType), func.Item4, backs.SelectMany(t => t.Item3).ToArray(), ChainedConverter));
            }
            catch (Exception e)
            {
                EquationTokenizer.ThrowQuickConverterEvent(new MarkupExtensionExceptionEventArgs(Converter, this, e));
                throw;
            }
        }
Esempio n. 6
0
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            try
            {
                if (P == null)
                {
                    return(null);
                }

                bool getExpression;
                if (serviceProvider == null)
                {
                    getExpression = false;
                }
                else
                {
                    var targetProvider = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
                    if (targetProvider != null && (targetProvider.TargetObject is Setter))
                    {
                        getExpression = false;
                    }
                    else if (targetProvider == null || !(targetProvider.TargetProperty is PropertyInfo))
                    {
                        getExpression = true;
                    }
                    else
                    {
                        Type propType = (targetProvider.TargetProperty as PropertyInfo).PropertyType;
                        if (propType == typeof(Binding))
                        {
                            return(this);
                        }
                        getExpression = !propType.IsAssignableFrom(typeof(System.Windows.Data.MultiBinding));
                    }
                }

                P.Converter = new QuickConverter()
                {
                    Convert        = Convert,
                    ConvertBack    = ConvertBack,
                    DynamicContext = DynamicContext,
                    PType          = PType,
                    V0             = V0,
                    V1             = V1,
                    V2             = V2,
                    V3             = V3,
                    V4             = V4,
                    V5             = V5,
                    V6             = V6,
                    V7             = V7,
                    V8             = V8,
                    V9             = V9
                }.Get();

                return(getExpression ? P.ProvideValue(serviceProvider) : P);
            }
            catch (Exception e)
            {
                EquationTokenizer.ThrowQuickConverterEvent(new MarkupExtensionExceptionEventArgs(Convert, this, e));
                throw;
            }
        }
Esempio n. 7
0
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            try
            {
                bool getExpression;
                if (serviceProvider == null)
                {
                    getExpression = false;
                }
                else
                {
                    var targetProvider = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
                    if (targetProvider != null && (targetProvider.TargetObject is Setter))
                    {
                        getExpression = false;
                    }
                    else if (targetProvider == null || !(targetProvider.TargetProperty is PropertyInfo))
                    {
                        getExpression = true;
                    }
                    else
                    {
                        Type propType = (targetProvider.TargetProperty as PropertyInfo).PropertyType;
                        if (propType == typeof(MultiBinding))
                        {
                            return(this);
                        }
                        getExpression = !propType.IsAssignableFrom(typeof(System.Windows.Data.MultiBinding));
                    }
                }

                var holder = new System.Windows.Data.MultiBinding()
                {
                    Mode = Mode, UpdateSourceTrigger = UpdateSourceTrigger
                };
                if (FallbackValue != null)
                {
                    holder.FallbackValue = FallbackValue;
                }
                if (TargetNullValue != null)
                {
                    holder.TargetNullValue = TargetNullValue;
                }

                if (ExternalConverter == null)
                {
                    holder.ConverterParameter = ConverterParameter;
                    string[] parameterOrder;
                    holder.Converter = new QuickMultiConverter()
                    {
                        Converter      = Converter,
                        DynamicContext = DynamicContext,
                        P0Type         = P0Type,
                        P1Type         = P1Type,
                        P2Type         = P2Type,
                        P3Type         = P3Type,
                        P4Type         = P4Type,
                        P5Type         = P5Type,
                        P6Type         = P6Type,
                        P7Type         = P7Type,
                        P8Type         = P8Type,
                        P9Type         = P9Type,
                        V0             = V0,
                        V1             = V1,
                        V2             = V2,
                        V3             = V3,
                        V4             = V4,
                        V5             = V5,
                        V6             = V6,
                        V7             = V7,
                        V8             = V8,
                        V9             = V9,
                        ConvertBack0   = ConvertBack0,
                        ConvertBack1   = ConvertBack1,
                        ConvertBack2   = ConvertBack2,
                        ConvertBack3   = ConvertBack3,
                        ConvertBack4   = ConvertBack4,
                        ConvertBack5   = ConvertBack5,
                        ConvertBack6   = ConvertBack6,
                        ConvertBack7   = ConvertBack7,
                        ConvertBack8   = ConvertBack8,
                        ConvertBack9   = ConvertBack9
                    }.Get(out parameterOrder);

                    foreach (string name in parameterOrder)
                    {
                        holder.Bindings.Add(typeof(MultiBinding).GetProperty(name).GetValue(this, null) as BindingBase);
                    }

                    if (!_modeSet)
                    {
                        bool exists = false;
                        for (int i = 0; i <= 9; ++i)
                        {
                            exists |= !String.IsNullOrWhiteSpace(typeof(MultiBinding).GetProperty("ConvertBack" + i).GetValue(this, null) as string);
                        }
                        holder.Mode = exists ? BindingMode.TwoWay : BindingMode.OneWay;
                    }
                }
                else
                {
                    if (ExternalConverterParameterMode == ConverterParameterMode.Parameter)
                    {
                        holder.ConverterParameter = ConverterParameter;
                    }
                    else
                    {
                        holder.ConverterParameter = new object[] { V0, V1, V2, V3, V4, V5, V6, V7, V8, V9 }
                    };
                    holder.Converter = ExternalConverter;
                    for (int i = 0; i <= 9; ++i)
                    {
                        var binding = typeof(MultiBinding).GetProperty("P" + i).GetValue(this, null) as BindingBase;
                        if (binding != null)
                        {
                            holder.Bindings.Add(binding);
                        }
                    }
                }

                return(getExpression ? holder.ProvideValue(serviceProvider) : holder);
            }
            catch (Exception e)
            {
                EquationTokenizer.ThrowQuickConverterEvent(new MarkupExtensionExceptionEventArgs(Converter, this, e));
                throw;
            }
        }
Esempio n. 8
0
        private object DoConversion(object value, Type targetType, object parameter, Func <object, object[], object, object> func, bool convertingBack, CultureInfo culture)
        {
            if (convertingBack)
            {
                if (_chainedConverter != null)
                {
                    try { value = _chainedConverter.ConvertBack(value, targetType, parameter, culture); }
                    catch (Exception e)
                    {
                        EquationTokenizer.ThrowQuickConverterEvent(new ChainedConverterExceptionEventArgs(ConvertExpression, value, targetType, parameter, culture, true, _chainedConverter, this, e));
                        return(DependencyProperty.UnsetValue);
                    }

                    if (value == DependencyProperty.UnsetValue || value == System.Windows.Data.Binding.DoNothing)
                    {
                        return(value);
                    }
                }

                if (ValueType != null && !ValueType.IsInstanceOfType(value))
                {
                    return(System.Windows.Data.Binding.DoNothing);
                }
            }
            else
            {
                if (value == DependencyProperty.UnsetValue || _namedObjectType.IsInstanceOfType(value) || (PType != null && !PType.IsInstanceOfType(value)))
                {
                    return(DependencyProperty.UnsetValue);
                }
            }

            object result = value;

            if (func != null)
            {
                try { result = func(result, _values, parameter); }
                catch (Exception e)
                {
                    LastException = e;
                    ++ExceptionCount;
                    if (Debugger.IsAttached)
                    {
                        Console.WriteLine("QuickMultiConverter Exception (\"" + (convertingBack ? ConvertBackExpression : ConvertExpression) + "\") - " + e.Message + (e.InnerException != null ? " (Inner - " + e.InnerException.Message + ")" : ""));
                    }
                    if (convertingBack)
                    {
                        EquationTokenizer.ThrowQuickConverterEvent(new RuntimeSingleConvertExceptionEventArgs(ConvertBackExpression, ConvertBackExpressionDebugView, null, value, _values, parameter, this, e));
                    }
                    else
                    {
                        EquationTokenizer.ThrowQuickConverterEvent(new RuntimeSingleConvertExceptionEventArgs(ConvertExpression, ConvertExpressionDebugView, value, null, _values, parameter, this, e));
                    }
                    return(DependencyProperty.UnsetValue);
                }
                finally
                {
                    var dataContainers = convertingBack ? _fromDataContainers : _toDataContainers;
                    if (dataContainers != null)
                    {
                        foreach (var container in dataContainers)
                        {
                            container.Value = null;
                        }
                    }
                }
            }

            if (result == DependencyProperty.UnsetValue || result == System.Windows.Data.Binding.DoNothing)
            {
                return(result);
            }

            if (!convertingBack && _chainedConverter != null)
            {
                try { result = _chainedConverter.Convert(result, targetType, parameter, culture); }
                catch (Exception e)
                {
                    EquationTokenizer.ThrowQuickConverterEvent(new ChainedConverterExceptionEventArgs(ConvertExpression, result, targetType, parameter, culture, false, _chainedConverter, this, e));
                    return(DependencyProperty.UnsetValue);
                }
            }

            if (result == DependencyProperty.UnsetValue || result == System.Windows.Data.Binding.DoNothing || result == null || targetType == null || targetType == typeof(object))
            {
                return(result);
            }

            if (targetType == typeof(string))
            {
                return(result.ToString());
            }

            Func <object, object> cast;

            if (!castFunctions.TryGetValue(targetType, out cast))
            {
                ParameterExpression par = Expression.Parameter(typeof(object));
                cast = Expression.Lambda <Func <object, object> >(Expression.Convert(Expression.Dynamic(Binder.Convert(CSharpBinderFlags.ConvertExplicit, targetType, typeof(object)), targetType, par), typeof(object)), par).Compile();
                castFunctions.TryAdd(targetType, cast);
            }
            if (cast != null)
            {
                try
                {
                    result = cast(result);
                }
                catch
                {
                    castFunctions[targetType] = null;
                }
            }
            return(result);
        }