private async void SearchBox_TextChangedAsync(object sender, EventArgs e) { var query = this.searchBox.Text; var searchVersion = Interlocked.Increment(ref this.searchVersion); await Task.Delay(TimeSpan.FromMilliseconds(500)).ConfigureAwait(true); if (this.searchVersion != searchVersion) { return; } Predicate <SearchResult> predicate; try { var term = new SearchGrammar().Parse(query ?? string.Empty); predicate = this.searchCompiler.Compile(term); } catch { predicate = r => false; } if (this.searchVersion == searchVersion) { this.visiblePredicate = predicate; this.UpdateListView(); } }
public static SearchResult <T> FilterUsingIrony <T>( this IQueryable <T> query, string queryString, params Expression <Func <T, string> >[] properties) { if (query == null) { throw new ArgumentNullException(nameof(query)); } if (properties == null) { throw new ArgumentNullException(nameof(properties)); } if (properties.Length == 0) { throw new ArgumentException("At least one property is expected", nameof(properties)); } if (string.IsNullOrWhiteSpace(queryString)) { return(new SearchResult <T>(query, Enumerable.Empty <string>())); } SearchGrammar searchGrammar = new SearchGrammar(); Parser parser = new Parser(searchGrammar); ParseTree parseTree = parser.Parse(queryString); if (parseTree.HasErrors() || parseTree.Root == null) { System.Diagnostics.Trace.WriteLine("Failed to parse search grammar '" + queryString); string errors = string.Join( "\r\n", parseTree.ParserMessages .Where(m => m.Level == Irony.ErrorLevel.Error) .Select(m => m.Message)); throw new InvalidSearchException("The search term is invalid:\r\n" + errors); } var arg = Expression.Parameter(typeof(T), "p"); MemberExpression[] memberExpressions = new MemberExpression[properties.Length]; for (int i = 0; i < properties.Length; i++) { var propertyMemberExpression = properties[i].Body as MemberExpression; if (propertyMemberExpression == null) { throw new ArgumentException( "The " + i + "th property is invalid. Please provide property member expression like 'o => o.Name'", nameof(properties)); } string propertyString = propertyMemberExpression.ToString(); string name = propertyString.Substring(propertyString.IndexOf('.') + 1); memberExpressions[i] = Expression.Property(arg, name); } var terms = new HashSet <string>(); var searchExpression = CreateChildExpression(parseTree.Root, memberExpressions, terms); var searchPredicate = Expression.Lambda <Func <T, bool> >(searchExpression, arg); return(new SearchResult <T>(query.Where(searchPredicate), terms)); }