views:

2075

answers:

3

hello, i am using a BindingSource.Filter to list only certain elements of the datasource. especially i use it like this a lot:

m_bindingSourceTAnimation.Filter = "Name LIKE '" + FilterText + "'";

now my question is, if it is somehow possible to use regular expressions with these filters.

i would especially need multiple wildcard (*) characters like

*hello*world*

thanks!

+5  A: 

BindingSource relies on IBindingListView.Filter for this functionality. The behaviour depends entirely on the specific list implementation. Is this a DataTable/DataView? If so, this maps to DataView.RowFilter, with syntax listed here.

The DataView implementation has no regex support, but supports LIKE via * - i.e. where FilterText is something like "Foo*Bar*". At least, that is my understanding.


I'm still assuming that you are using DataTable/DataView... a pragmatic alternative might be to introduce an extra (bool) column for the purpose. Set/clear that marker as the predicate (using a regex or any other complicated logic), and just use the row-filter to say "where set". Not very clean, maybe, but a lot simpler than implementing a custom data-view / binding-source.


If you are using objects (rather than DataTable), then another option might be the Dynamic LINQ Library. I don't know the full range of what it supports, but it (Where(string)) certainly has some / much of the RowFilter capability. And since the code is available in the sample project, it is possible you could educate it to apply a regex?

Marc Gravell
thanks, this almost works, it only does not seem to understand * in the middle of a word but only at the beginning and the end, like this: *test*i would really need it in the middle of a word. :-)
clamp
thanks, i think i understand what you mean, but that would require to make some custom list of all the strings i want to filter and then apply regex on it. is there something for this in .NET already, or will i need to do my own regex?
clamp
Regex is built into .NET, but I didn't really follow the rest of the comment I'm afraid...
Marc Gravell
The DataView.RowFilter documentation explicitly states "Wildcards are not allowed in the middle of a string. For example, 'te*xt' is not allowed."
Brian ONeil
"The DataView.RowFilter documentation explicitly states "Wildcards are not allowed in the middle of a string.""thanks for the info. but infact, this is EXACTLY what i would need! :)
clamp
+8  A: 

You can query the DataTable with LINQ pretty easily and then you can use a actual Regex within the query to filter it anyway you like.

Something like this...

var source = myDataTable.AsEnumerable();

var results = from matchingItem in source
              where Regex.IsMatch(matchingItem.Field<string>("Name"), "<put Regex here>")
              select matchingItem;

//If you need them as a list when you are done (to bind to or something)
var list = results.ToList();

This will get you the rows that match based on an actual Regex, I don't know what you need to do with the information, but this would allow you to get the rows based on a Regex.

**Update - Trying to clarify based on comment

I don't know what you are using this for so I don't have a great context, but from what I can guess you are using a DataTable to data bind to a Grid or something like that. If this is the case, I think that you should be able to assign "list" from the snippet I put in here as the DataSource (assuming you are using a BindingSource) and I think that it will work. I don't use DataTables, I usually stick to objects for working with my data so I am not exactly sure how it will handle the list of rows, but I would think that it would work (or be close enough that a little google searching would do it).

Brian ONeil
thanks, but i have never used LINQ before. how can i use it inside my C# code where i have the BindingSource?
clamp
yes, the datatable is visualized using a DataGridView
clamp
+1  A: 

The comment below doesn't really work:

"...a pragmatic alternative might be to introduce an extra (bool) column for the purpose. Set/clear that marker as the predicate (using a regex or any other complicated logic), and just use the row-filter to say "where set". Not very clean, maybe, but a lot simpler than implementing a custom data-view / binding-source."

When you set the new column this causes the row state to change and you basically end up with the whole table/dataview thinking that it needs to do every row in the next update. Not sure how to get around this problem.