Exemplo n.º 1
0
        static public BaseNode BuildFromExpression(Expression expr, BaseNode parent = null, bool negate = false)
        {
            CriteriaNode result;

            switch (GetConditionType(expr))
            {
            // Structural nodes:
            case NodeType.Multi:
                return(BuildMulti(expr as BinaryExpression, parent, negate));

            case NodeType.Negatable:
                return(BuildNegatable(expr as UnaryExpression));

            default:
                if (parent != null)
                {
                    parent.HasUnparsedChilds = true;
                }
                return(new UnparsedNode {
                    Expression = expr, Negate = negate
                });

            // Criteria Nodes (leafs):
            case NodeType.TrueCriteria:
                result = new CriteriaNode(expr as MemberExpression); break;

            case NodeType.LeftCriteria:
                var be = expr as BinaryExpression;
                result = new CriteriaNode(be.Left as MemberExpression, be.Right as ConstantExpression, expr.NodeType); break;

            case NodeType.RightCriteria:
                var be2 = expr as BinaryExpression;
                var nt  = expr.NodeType;
                if (nt == ExpressionType.LessThan)
                {
                    nt = ExpressionType.GreaterThan;
                }
                else if (nt == ExpressionType.LessThanOrEqual)
                {
                    nt = ExpressionType.GreaterThanOrEqual;
                }
                else if (nt == ExpressionType.GreaterThan)
                {
                    nt = ExpressionType.LessThan;
                }
                else if (nt == ExpressionType.GreaterThanOrEqual)
                {
                    nt = ExpressionType.LessThanOrEqual;
                }
                result = new CriteriaNode(be2.Right as MemberExpression, be2.Left as ConstantExpression, nt); break;

            case NodeType.MethodCriteria:
                result = BuildMethodCriteria(expr as MethodCallExpression); break;

            case NodeType.StringCompareCriteria:
                var be3 = expr as BinaryExpression;
                result = BuildMethodCriteria(be3.Left as MethodCallExpression);
                switch (be3.NodeType)
                {
                case ExpressionType.Equal: result.Op = Operator.E; break;

                case ExpressionType.LessThan: result.Op = Operator.LT; break;

                case ExpressionType.LessThanOrEqual: result.Op = Operator.LToE; break;

                case ExpressionType.GreaterThan: result.Op = Operator.GT; break;

                case ExpressionType.GreaterThanOrEqual: result.Op = Operator.GToE; break;

                case ExpressionType.NotEqual: result.Op = Operator.NE; break;

                default: throw new NotSupportedException();
                }
                break;
            }

            if (negate)
            {
                result.Op = result.Op.Negate();
            }
            return(result);
        }
Exemplo n.º 2
0
        public CriteriaNodePanel(Type baseType, Panel parent, CriteriaNode node) : base(parent, node)
        {
            Node = node;
            flow = new FlowLayoutPanel {
                FlowDirection = FlowDirection.LeftToRight, Dock = DockStyle.Fill, ContextMenuStrip = this.ContextMenuStrip
            };

            // Operator:
            operatorCombo = new ComboBox()
            {
                DropDownStyle = ComboBoxStyle.DropDownList,
                Margin        = new Padding(2, MarginTop, 2, 0),
                Width         = CalcWidth(node.Op.GetName()),
                DropDownWidth = SuggestedOperatorComboBoxWidth()
            };
            operatorCombo.SelectionChangeCommitted += OperatorChanged;

            // Value (combobox for enum object types):
            valueComboBox = new ComboBox()
            {
                DropDownStyle = ComboBoxStyle.DropDownList,
                Margin        = new Padding(2, MarginTop, 2, 0),
                DropDownWidth = 120
            };
            valueComboBox.SelectionChangeCommitted += (s, e) => node.Value = valueComboBox.SelectedItem;

            // Value (textbox for non-enum object types):
            valueTextBox = new TextBox()
            {
                Margin = new Padding(2, MarginTop + 1, 2, 0),
                Width  = 100
            };
            valueTextBox.LostFocus += (s, e) => { node.Value = valueTextBox.Text; };
            if (node.Value != null)
            {
                valueTextBox.Text = node.Value.ToString();
            }

            // Checkbox for case sensitivity for string criteria:
            valueCaseSensitivity = new CheckBox()
            {
                Text     = "Case sensitive",
                Margin   = new Padding(2, MarginTop + 3, 2, 0),
                AutoSize = true,
                Checked  = node.CaseSensitive
            };
            valueCaseSensitivity.CheckedChanged += (s, e) => { node.CaseSensitive = valueCaseSensitivity.Checked; };

            // First property combobox which always appears, based on baseType (last item in stack):
            var firstPropValue = node.IsBlank ? null : node.PropertyPath.Last().Member.Name;

            AddPropCombo(flow, firstPropValue, baseType);

            if (firstPropValue != null)
            {
                // Sequence of sub-properties (may appear 0..x times based on how deep we go):
                if (node.PropertyPath.Count > 1)
                {
                    var i = 1;
                    foreach (var p in node.PropertyPath.Reverse().Skip(1))
                    {
                        AddPropCombo(flow, p.Member.Name, p.Member.ReflectedType);
                        i++;
                    }
                }
            }

            flow.Controls.Add(operatorCombo);
            flow.Controls.Add(valueComboBox);
            flow.Controls.Add(valueTextBox);
            flow.Controls.Add(valueCaseSensitivity);

            Controls.Add(flow);

            if (Node.PropertyPath.Count == 0)
            {
                Node.PropertyPath.Push(new CriteriaNode.PropertyPathItem());
            }
            UpdateOperatorAndValue();
            flow.Paint += Flow_Paint;
        }
Exemplo n.º 3
0
        static private CriteriaNode BuildMethodCriteria(MethodCallExpression mce)
        {
            CriteriaNode result;

            // Support for standard string methods (contains, ends with, starts with, etc.):
            if (mce.Method.DeclaringType == typeof(string))
            {
                var res = new CriteriaNode();

                switch (mce.Method.Name)
                {
                case "StartsWith":
                case "EndsWith":
                    res.CaseSensitive =
                        !(mce.Arguments.Count == 3 &&
                          mce.Arguments[1] is ConstantExpression &&
                          (bool)(mce.Arguments[1] as ConstantExpression).Value);
                    res.Value = (mce.Arguments[0] as ConstantExpression).Value.ToString();
                    res.Op    = mce.Method.Name == "StartsWith" ? Operator.StartsWith : Operator.EndsWith;
                    CriteriaNode.GetPropertyPath(mce.Object as MemberExpression).ForEach(ppi => res.PropertyPath.Push(ppi));
                    break;

                case "IsNullOrEmpty":
                    res.CaseSensitive = false;
                    res.Op            = Operator.IsBlank;
                    CriteriaNode.GetPropertyPath(mce.Arguments[0] as MemberExpression).ForEach(ppi => res.PropertyPath.Push(ppi));
                    break;

                case "Contains":
                    // The string Contains() method is always case sensitive:
                    res.CaseSensitive = true;
                    res.Value         = (mce.Arguments[0] as ConstantExpression).Value.ToString();
                    res.Op            = Operator.Contains;
                    CriteriaNode.GetPropertyPath(mce.Object as MemberExpression).ForEach(ppi => res.PropertyPath.Push(ppi));
                    break;

                case "Compare":
                    res.CaseSensitive = false;
                    if (mce.Arguments.Count == 3)
                    {
                        res.CaseSensitive = !(bool)(mce.Arguments[2] as ConstantExpression).Value;
                    }
                    res.Value = (mce.Arguments[1] as ConstantExpression).Value.ToString();
                    CriteriaNode.GetPropertyPath(mce.Arguments[0] as MemberExpression).ForEach(ppi => res.PropertyPath.Push(ppi));


                    break;

                case "IndexOf":
                    // For case insensitive comparisons, the IndexOf method can be used:
                    res.CaseSensitive = true;
                    if (
                        mce.Arguments.Count == 2 &&
                        mce.Arguments[1] is ConstantExpression &&
                        (mce.Arguments[1] as ConstantExpression).Type == typeof(StringComparison))
                    {
                        var ct = (StringComparison)(mce.Arguments[1] as ConstantExpression).Value;
                        switch (ct)
                        {
                        case StringComparison.CurrentCultureIgnoreCase:
                        case StringComparison.InvariantCultureIgnoreCase:
                        case StringComparison.OrdinalIgnoreCase:
                            res.CaseSensitive = false;
                            break;
                        }
                    }
                    res.Value = (mce.Arguments[0] as ConstantExpression).Value.ToString();
                    res.Op    = Operator.Contains;
                    CriteriaNode.GetPropertyPath(mce.Object as MemberExpression).ForEach(ppi => res.PropertyPath.Push(ppi));
                    break;
                }

                result = res;
            }
            else if (mce.Method.DeclaringType == typeof(System.Text.RegularExpressions.Regex))
            {
                var res = new CriteriaNode();

                if (mce.Method.Name == "IsMatch" && mce.Arguments.Count == 2 && mce.Arguments[1].Type == typeof(string))
                {
                    res.CaseSensitive = true;
                    res.Op            = Operator.RegExMatch;
                    res.Value         = (mce.Arguments[1] as ConstantExpression).Value.ToString();

                    CriteriaNode.GetPropertyPath(mce.Arguments[0] as MemberExpression).ForEach(ppi => res.PropertyPath.Push(ppi));
                }
                else
                {
                    return(null);
                }

                result = res;
            }
            else
            {
                // Other methods not supported:
                return(null);
            }

            return(result);
        }