Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8391343
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 9, 20262026-06-09T19:14:08+00:00 2026-06-09T19:14:08+00:00

This is the UI of my application. It is a WPF based application that

  • 0

This is the UI of my application. It is a WPF based application that analyzes between devices (Something very similar to Wireshark).enter image description here

The class that is being binded to the DataGrid is the following (Everything except Error and FuncType is bound to the grid:)

public class CommDGDataSource
{
    public int Number { get; set; }
    public string Time { get; set; }
    public string Protocol { get; set; }
    public string Source { get; set; }
    public string Destination { get; set; }
    public string Data { get; set; }
    public bool Error { get; set; }
    public FunctionType FuncType { get; set; }
}

Basically, I’m trying to design something where users can enter certain filter commands and only the rows that matches the condition should be displayed. Here are some examples (without the quote),

  1. Entering “Error” should only display the datarows whose Error property has been set to true

  2. Entering “source==someipaddress” should only display the matching IP address

  3. Entering “number>100” should only display rows with number greater than 100

  4. Multiple conditions should apply if separated by comma. (Error,source==someipaddress)

I’ve already created ICollectionView for my binding data to handle the filtering but I’m not sure about the approach I should take to parse the commands and properly handle the filtering to meet the above requirements.

Any guidance would be appreciated.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-09T19:14:09+00:00Added an answer on June 9, 2026 at 7:14 pm

    The 10,000 feet overview

    Filtering data in a DataGrid is done by attaching a handler to the CollectionViewSource.Filter event, so the actual problem is how to create a FilterEventHandler from user input. This problem can be solved in a powerful manner with expression trees.

    I ‘m not going to go into detail with regards to how to parse the input string because that can range from very simple to very complicated; a powerful approach would be to use a tool like ANTRL to parse the input into an abstract syntax tree.

    What I will show is how you can create a filter given that the input is parsed and the user’s intent is known (it is also quite easy to create the filter on the fly while parsing).

    Let’s assume that the user entered “Number > 10” for the filter. If this filter were hardcoded, the FilterEventHandler would look like this:

    public void CustomFilterHandler(object sender, FilterEventArgs e)
    {
        CommDGDataSource source = (CommDGDataSource)e.Item;
        return source.Number > 10;
    }
    

    Constructing a filtering event handler dynamically

    What we ‘re going to do here is dynamically construct this method on the fly using expression trees. Let’s begin with some preamble:

    var sourceType = typeof(CommDGDataSource);
    var eventArgsType = typeof(System.Windows.Data.FilterEventArgs);
    

    We ‘re going to be constructing a LambdaExpression which has two parameters and a body. Let’s construct the parameters first:

    var parameters = new[] {
        Expression.Parameter(typeof(object), "sender"),
        Expression.Parameter(eventArgsType, "e"),
    };
    

    The body is going to be a BlockExpression (this is not strictly necessary, but could come in handy later on). A BlockExpression uses a number of variables and is comprised of any number of other expressions; very importantly, the last of these will be the block’s return value.

    The first line of the mock event handler given above tells us that we need one variable:

    var variable = Expression.Variable(sourceType, "source");
    

    And we definitely need a predicate that produces the return value:

    var predicate = Expression.GreaterThan(
        Expression.MakeMemberAccess(variable, sourceType.GetProperty("Number")),
        Expression.Constant(10));
    

    We are now ready to produce the body of the BlockExpression. The body will need to access the Item property of the second parameter of the event handler (parameters[1]) and cast it to sourceType because FilterEventArgs.Item is of type object, so we can’t use it directly. The result of the cast should be stored in variable and then predicate will perform the test:

    // Some intermediate variables to cut down on the line length
    var itemProperty = eventArgsType.GetProperty("Item");
    var itemAccessExpression = Expression.MakeMemberAccess(parameters[1], itemProperty);
    var castItemToCorrectType = Expression.TypeAs(itemAccessExpression, sourceType);
    
    // And the body is comprised of these two expressions:
    var body = new[] { Expression.Assign(variable, castItemToCorrectType), predicate };
    

    Since predicate is the last expression of the body it will also produce its return value.

    We can now construct the block expression and then finally the filtering lambda expression itself:

    var block = Expression.Block(new[] { variable }, body);
    var filter = Expression.Lambda<Func<object, FilterEventArgs, bool>>(block, parameters);
    

    Plugging in the filter

    One of the reasons we went to all this trouble is that now the compiler can construct a “real” method from the filter expression for us automatically! We can then simply plug it into the CollectionViewSource.Filter event and enjoy filtering:

    // It's a good idea to keep a reference to this around for now,
    // so that it can be removed from the event handler later.
    var filterMethod = filter.Compile();
    
    collectionViewSource.Filter += filterMethod;
    

    Constructing complicated filters

    The other reason to go with this approach is that it’s quite easy to extend the filtering logic. For example it’s easy to imagine that instead of hardwiring the predicate like this:

    var predicate = Expression.GreaterThan(
        Expression.MakeMemberAccess(variable, sourceType.GetProperty("Number")),
        Expression.Constant(10));
    

    We could construct it from user input like this:

    // Maps operators to Expression factory methods
    var dict = new Dictionary<string, Func<Expression, Expression, BinaryExpression>>
    {
        { "==", Expression.Equal },
        { ">", Expression.GreaterThan },
        { "<", Expression.LessThan },
        // etc
    };
    
    var predicate = Expression.Constant(true); // by default accept all rows
    
    // Logical AND everything in parseResult to construct the final predicate
    foreach (parseResult in parsedUserInput)
    {
        var exprConstructor = dict[parseResult.Operator];
        var property = sourceType.GetProperty(parseResult.PropertyName);
        var target = Expression.MakeMemberAccess(variable, property);
        var additionalTest = exprConstructor(target, Expression.Constant(parseResult.Value));
        predicate = Expression.AndAlso(predicate, additionalTest);
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

This question is related to a WPF application. I have a class as below
I have a simple WPF application that uses ClickOnce to handle installing. Within this
I'm writing a WPF application that uses a component, and this component returns a
I'm going to do a wpf application using MVVM(It based on http://www.codeproject.com/KB/WPF/MVVMQuickTutorial.aspx ). This
I develop desktop-based WPF-application, that uses SQL Server 2008 R2 Database and ADO.NET Entity
We are writing a WPF based application that is usually used on a touchscreen
I have a C# (2008/.NET 3.5) class library assembly that supports WPF (based on
I'm developing a WPF based application that must play some videos during its execution.
My desktop-based WPF-application (4.0) works with DB and in order to this it should
I have WPF 4 desktop-based application. In one of the windows of this application,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.