ElementParameterFilter for Parameter.AsValueString and Parameter.ToString values

ElementParameterFilter for Parameter.AsValueString and Parameter.ToString values

ottosson_mathias
Advocate Advocate
1,345 Views
6 Replies
Message 1 of 7

ElementParameterFilter for Parameter.AsValueString and Parameter.ToString values

ottosson_mathias
Advocate
Advocate

I'm implementing a filter feature where I want to be able to filter the parameter values of family instances.

 

I'm using an ElementParameterFilter like so:

 

var parameterProvider = new ParameterValueProvider(parameterId);
var rule = new FilterDoubleRule(parameterProvider, new FilterNumericGreater(), doubleValue, double.Epsilon);
var collector = new FilteredElementCollector(doc).WherePasses(new ElementParameterFilter(rule)).Cast<FamilyInstance>();

 

Which works... but not on the values visible in Revit instance properties list, which in this case should be the "Flow" parameter with value "76".

 

parameterFilter.png

 

When I write the parameter value and valueString:

 

var result = $"id: {element.Id.IntegerValue}, valueString: {parameter.AsValueString()}, value: {parameter.AsDouble().ToString()}"

 

it gives: "id: 4865584, valueString: 76, value: 2,68391467083313"

 

When I use the filter it will be applied on the value (2,68391467083313), not the valueString (76)!

 

But the user will most likely expect to be able to filter on 76, not 2,68391467083313.

 

How can I filter on the valueString as well?

 

Thanks!

0 Likes
Accepted solutions (1)
1,346 Views
6 Replies
Replies (6)
Message 2 of 7

mhannonQ65N2
Collaborator
Collaborator
Accepted solution

Revit stores values in using its internal units, which are independent of how the project's units are configured. For example, even in a metric project, Revit stores length in Feet. In your case, I think you'll want to first convert the user provided value (76 in your example) into internal units using UnitUtils.ConvertToInternalUnits() and then using the result in the FilterDoubleRule.

0 Likes
Message 3 of 7

lukaskohout
Advocate
Advocate

Or vice versa have the value in filter converted to units displayed in the UI. This way you will convert only one value once.


Hitting Accepted Answer is a Community Contribution from me as well as from you.
======================================================================
0 Likes
Message 4 of 7

mhannonQ65N2
Collaborator
Collaborator

@lukaskohout wrote:

Or vice versa have the value in filter converted to units displayed in the UI. This way you will convert only one value once.


I'd have to strongly recommend against that. AFIK, there is no way to do that conversion within the Revit filter. As such, you would have to load all the elements being filtered into .NET memory and do the logic there--which is Considered Harmful. Instead, just let Revit do the filtering work for you.

0 Likes
Message 5 of 7

lukaskohout
Advocate
Advocate

Yes @mhannonQ65N2 , my bad.

I have read your answer one more time and it seems I misunderstood it first time i read it. 

Thanks for clarifiying.


Hitting Accepted Answer is a Community Contribution from me as well as from you.
======================================================================
0 Likes
Message 6 of 7

RPTHOMAS108
Mentor
Mentor

Not sure you should be using Double.Epsilon for your Epsilon.

 

How many decimal places are required in the internal unit for each whole unit of the UI units (or fraction of such displayed in the UI)? These are probably the factors that should govern the choice of Epsilon not the ultimate accuracy of the Double structure. Two double values that the user sees as equal may not compare as such when using Double.Epsilon.

0 Likes
Message 7 of 7

ottosson_mathias
Advocate
Advocate

Ah! I should have known it was being stored as Revit internal units...

 

Thanks a lot @mhannonQ65N2!

0 Likes