Parameter Filter

Parameter Filter

vanlion
Advocate Advocate
1,888 Views
8 Replies
Message 1 of 9

Parameter Filter

vanlion
Advocate
Advocate

Hello,

 

I want to get all generic families that contains for example "test" in the name and show this in a windowsform combobox so i can use it in a form to set parameters etc. My thought was to do this with a parameter filter. I came this far as shown below this post. But how do you add the filter to the GenericFamilySymbolList? i tried collector.WherePasses(filter); But i get no results in the combobox . Without the filter everything works and shows all the generic models. but i need only the ones with test in the name (as example)

 

. Anyone an idea what i'm missing?

 

            IList<Element> GenericFamilySymbolList = new List<Element>();

            FilteredElementCollector collector = new FilteredElementCollector(doc);

            ////// Get Family Category//////
            //GenericFamilySymbolList =collector.OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_GenericModel).ToElements();

            collector.OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_GenericModel).ToElements();

            ElementId id = new ElementId(BuiltInParameter.DATUM_TEXT);

            ParameterValueProvider provider = new ParameterValueProvider(id);

            FilterStringRuleEvaluator evaluator = new FilterStringContains();

            FilterRule rule = new FilterStringRule(provider, evaluator, "test", true);

            ElementParameterFilter filter = new ElementParameterFilter(rule);
     
            GenericModelComboBox form = new GenericModelComboBox(GenericFamilySymbolList);
                form.ShowDialog();
0 Likes
Accepted solutions (4)
1,889 Views
8 Replies
Replies (8)
Message 2 of 9

FAIR59
Advisor
Advisor
Accepted solution

you are filtering for the wrong parameter. For the symbol.Name you need BuiltInParameter.ALL_MODEL_TYPE_NAME

0 Likes
Message 3 of 9

vanlion
Advocate
Advocate
Hi,

Thanks for the reply. I Will try it with this BuiltInParameter. I think you have to end with : collector.WherePasses(filter)?

0 Likes
Message 4 of 9

vanlion
Advocate
Advocate
Accepted solution

Hello,

 

It's working 🙂

 

this is the solution:

 

                IList<Element> GenericFamilySymbolList = new List<Element>();

                FilteredElementCollector collector = new FilteredElementCollector(doc);                

                collector.OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_GenericModel).ToElements();

                ElementId id = new ElementId(BuiltInParameter.ALL_MODEL_TYPE_NAME);

                ParameterValueProvider provider = new ParameterValueProvider(id);

                FilterStringRuleEvaluator evaluator = new FilterStringContains();

                FilterRule rule = new FilterStringRule(provider, evaluator, "test", false);

                ElementParameterFilter filter = new ElementParameterFilter(rule);

                GenericFamilySymbolList = collector.WherePasses(filter).ToElements();
0 Likes
Message 5 of 9

jeremytammik
Autodesk
Autodesk
Accepted solution

Thank you very much for the nice little sample and solution.

 

It prompts me to reiterate for the umpteenth time:

 

There is generally no need to call ToElements on a filtered element collector.

 

You can use and iterate over the collector directly.

 

The conversion costs time and memory and brings no advantage whatsoever.

 

I mentioned it here and many, many other places:

 

http://thebuildingcoder.typepad.com/blog/2018/08/naveen-zhong-and-deleting-non-shared-project-parame...

 

Here is a version that skips the conversion:

 

  ElementId id = new ElementId( BuiltInParameter
    .ALL_MODEL_TYPE_NAME );

  ParameterValueProvider provider 
    = new ParameterValueProvider( id );

  FilterStringRuleEvaluator evaluator 
    = new FilterStringContains();

  FilterRule rule = new FilterStringRule( 
    provider, evaluator, "test", false );

  ElementParameterFilter filter 
    = new ElementParameterFilter( rule );

  FilteredElementCollector genericSymbolsNamedTest
    = new FilteredElementCollector( doc )
      .OfClass( typeof( FamilySymbol ) )
      .OfCategory( BuiltInCategory.OST_GenericModel )
      .WherePasses( filter );

  

I added your sample code to The Building Coder samples and optimised it there, so you can see the difference:

 

https://github.com/jeremytammik/the_building_coder_samples/compare/2019.0.143.8...2019.0.143.9

  

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 6 of 9

vanlion
Advocate
Advocate

Hi Jeremy,

 

Thanks for the quick response!

 

Filter is working fine. But i used mine also to fill a combobox with this part:

 

 

IList<Element> GenericFamilySymbolList = new List<Element>();

 

 

    public partial class GenericModelComboBox : System.Windows.Forms.Form
    {

        public GenericModelComboBox(
            IEnumerable<Element> GenericFamilySymbolList)
        {
            InitializeComponent();
            comboBox1.DataSource = GenericFamilySymbolList;
            comboBox1.DisplayMember = "Name";
        }

 

maybe a stupid beginners question 😉 But how bind it now to the combobox? 

  FilteredElementCollector genericSymbolsNamedTest
    = new FilteredElementCollector( doc )

 

0 Likes
Message 7 of 9

vanlion
Advocate
Advocate

Sorry, already got it i think. It's shows up again in the combobox.

 

List<Element> genericSymbolsNamedTest = new List<Element>
(new FilteredElementCollector(doc)
.OfClass(typeof(FamilySymbol))
.OfCategory(BuiltInCategory.OST_GenericModel)
.WherePasses(filter));
0 Likes
Message 8 of 9

jeremytammik
Autodesk
Autodesk
Accepted solution

Good!

 

Maybe better:

 

  IList<Element> genericSymbolsNamedTest 
    = new FilteredElementCollector(doc)                    
      .OfClass(typeof(FamilySymbol))                    
      .OfCategory(BuiltInCategory.OST_GenericModel)                    
      .WherePasses(filter)
      .ToElements();

 

As you see, we are back to calling ToElements again, but AFTER all filtering has completed. so the number of elements is minimised.

 

Hoping that the built-in `ToElements` implementation is at least as efficient as calling `new List<...>` yourself.

 

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 9 of 9

vanlion
Advocate
Advocate

Works nice!!!

 

This is helping me a lot so thank you.

0 Likes