Let us continue to talk about the particular slow filter in Revit API, ElementParameterFilter.
In the previous article, we found some limitations of the existing FilterStringRuleEvaluator, like no way to determine whether a string parameter is numeric only. In this post, we are trying to address it.
We could get the expression that custom filter rule evaluators can be created to address some new situations like we talked about, checking whether a room number parameter is numeric only and in a range. Here is a try:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit.DB;
namespace RevitAddinCSProject
{
public class FilterNumericStringEquals : FilterStringEquals
{
public new bool Evaluate(string lhs,string rhs,bool caseSensitive)
{
int res1, res2;
if (!int.TryParse(lhs,out res1) || !int.TryParse(rhs, out res2))
{
return false;
}
if (res1 == res2)
return true;
else
return false;
}
}
public class FilterNumericStringGreater : FilterStringGreater
{
public new bool Evaluate(string lhs, string rhs, bool caseSensitive)
{
int res1, res2;
if (!int.TryParse(lhs, out res1) || !int.TryParse(rhs, out res2))
{
return false;
}
if (res1 > res2)
return true;
else
return false;
}
}
public class FilterNumericStringGreaterOrEqual : FilterStringGreaterOrEqual
{
//public override bool Evaluate(string lhs, string rhs, bool caseSensitive) { return true; }
//Error: cannot override inherited member 'Autodesk.Revit.DB.FilterStringRuleEvaluator.Evaluate(string, string, bool)'
// because it is not marked virtual, abstract, or override
// This compiles without warnings but does not really work!
public new bool Evaluate(string lhs, string rhs, bool caseSensitive)
{
System.Windows.Forms.MessageBox.Show("The Revit Filter system ignores me! :-(");
int res1, res2;
if (!int.TryParse(lhs, out res1) || !int.TryParse(rhs, out res2))
{
return false;
}
if (res1 >= res2)
return true;
else
return false;
}
}
public class FilterNumericStringLess : FilterStringLess
{
public new bool Evaluate(string lhs, string rhs, bool caseSensitive)
{
int res1, res2;
if (!int.TryParse(lhs, out res1) || !int.TryParse(rhs, out res2))
{
return false;
}
if (res1 < res2)
return true;
else
return false;
}
}
public class FilterNumericStringLessOrEqual : FilterStringLessOrEqual
{
//public override bool Evaluate(string lhs, string rhs, bool caseSensitive) { return true; }
//Error: cannot override inherited member 'Autodesk.Revit.DB.FilterStringRuleEvaluator.Evaluate(string, string, bool)'
// because it is not marked virtual, abstract, or override
// This compiles without warnings but does not really work!
public new bool Evaluate(string lhs, string rhs, bool caseSensitive)
{
System.Windows.Forms.MessageBox.Show("The Revit Filter system ignores me! :-(");
int res1, res2;
if (!int.TryParse(lhs, out res1) || !int.TryParse(rhs, out res2))
{
return false;
}
if (res1 <= res2)
return true;
else
return false;
}
}
}
Here is the test code for the custom evaluator and a comparison with the existing FilterStringRuleEvaluator:
ICollection<ElementId> roomids1 = GetRoomsNumberInRange(CachedDoc, "10", "20");
ICollection<ElementId> roomids2 = GetRoomsTrueNumberInRange(CachedDoc, "10", "20");
string message = string.Format("{0} rooms in the number range [10, 20]:\n\t", roomids1.Count);
foreach (ElementId id in roomids1)
message += (CachedDoc.get_Element(id) as Room).Number + ", ";
message += string.Format("\n\n{0} rooms in the true number range [10, 20]:\n\t", roomids2.Count);
foreach (ElementId id in roomids2)
message += (CachedDoc.get_Element(id) as Room).Number + ", ";
MessageBox.Show(message, "Custom FilterStringRuleEvaluator");
The code may report something like the following:
What’s going wrong here? The 2, 1A and 155 are still reported by the custom FilterStringRuleEvaluator as the existing FilterStringRuleEvaluator. They should be excluded, shouldn’t they?
Through some analysis, it’s found that custom filter rule evaluators cannot be really created. Though nothing prevents us from deriving from any existing filter rule evaluator classes, as commented in the code, the ‘override’ modifier does not work with the core method, Evaluate(), and it indicates that the Evaluate() method is not virtual and cannot be overridden.
To be more specific, the following compiler error would come out:
“ cannot override inherited member 'Autodesk.Revit.DB.FilterStringRuleEvaluator.Evaluate(string, string, bool)' because it is not marked virtual, abstract, or override”
Though the ‘new’ modifier makes the compiler happy but it does not do any good to our task here at all.
ElementParameterFilter Creator of RevitAddinCoder does not provide custom filter rule evaluators due to this limitation. It will take this into account when the API is ready.
Recent Comments