Retrieve all elements on start-up

Retrieve all elements on start-up

mohd.fadel
Enthusiast Enthusiast
923 Views
7 Replies
Message 1 of 8

Retrieve all elements on start-up

mohd.fadel
Enthusiast
Enthusiast

Hello everyone,

 

I'm trying to to implement an Updater in my code since documentChanged has some limitations regarding setting parameter values (in documentChanged they are read-only).

 

Everything is great! And i was able to register it using OnStartup(). However, i need to get all the elements in the document.

 

As i understand, the updater needs a trigger to get the change type (AddTrigger(UpdaterID, Document, IColllection(ElementId), ChangeType)) this overloaded function is what interests me. But how can i get the collection from the document while inside the OnStartup() function:

 

This is my function:

 

public Result OnStartup(UIControlledApplication application)
        {
           
            FilteredElementCollector collector = new FilteredElementCollector(doc);
            collector.WherePasses(new LogicalOrFilter(new ElementIsElementTypeFilter(false), new ElementIsElementTypeFilter(true)));

            ICollection<ElementId> allLoads = collector.ToElementIds();


            if (null == _updater)
            {
                _updater = new WatcherUpdater(
                  application.ActiveAddInId);

                UpdaterRegistry.RegisterUpdater(_updater);


                UpdaterRegistry.AddTrigger(
                      _updater.GetUpdaterId(), doc, allLoads,
                      Element.GetChangeTypeAny());
            }
            else
            {
                UpdaterRegistry.UnregisterUpdater(
                  _updater.GetUpdaterId());

                _updater = null;
            }
            return Result.Succeeded;
}

 

As you can see, i scratched doc, this is what's i can't get implement. How can i get the document from UIControlledApplication?

 

I even tried to add the trigger (AddTrigger(UpdaterID, Document, IColllection(ElementId), ChangeType)) in my Execute function. I tried searching a lot but i can't find anything. I even tried implementing an Idling event in which i can get the collection. But still not working. 

 

Any thoughts are appreciated.

 

 

Thanks,

 

M. Fadel

0 Likes
Accepted solutions (1)
924 Views
7 Replies
Replies (7)
Message 2 of 8

Revitalizer
Advisor
Advisor

Hi,

 

OnStartup, you can register to the OnDocumentOpened or OnViewChanged event.

Inside this, you can access the current document.

 

AddTrigger has an overload that does not need a document argument.

 

By the way, are you sure that you need to watch all elements ?

Wouldn't it be better and more performant to use a ElementMultiCategoryFilter ?

 

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





0 Likes
Message 3 of 8

mohd.fadel
Enthusiast
Enthusiast

 

OnStartup, you can register to the OnDocumentOpened or OnViewChanged event.

Inside this, you can access the current document.

 

AddTrigger has an overload that does not need a document argument.

 

By the way, are you sure that you need to watch all elements ?

Wouldn't it be better and more performant to use a ElementMultiCategoryFilter ?

 

 

Hello,

 

So i can register to the OnDocumentOpened! I'll try this first thing tomorrow. I found this:

 

Question: by Matt:

 

[http://thebuildingcoder.typepad.com/blog/2015/03/automatically-open-a-project-on-startup.html]

 

Jeremy discussed "using reflection". Was trying this now, will continue tomorrow! And will try OnDocumentOpened.

 

I know AddTrigger has an overload that does not need a document argument. But that overload uses ElementFilter, and i don't want to filter. Which

 

answers your last question, yes i need to watch all the elements. I have a user-defined parameter that is being added to all elements in the Revit project.

 

 

Thanks a lot! I'll keep you posted.

 

M. Fadel.

 

0 Likes
Message 4 of 8

Revitalizer
Advisor
Advisor
Accepted solution

Hi,

 

there are many categories whose property AllowsBoundParameters is false.

So you can indeed use a filter.

Note that there are many elements "under the hood" which you cannot see because they are abstract ones.

No need to watch them, too.

There are hundreds of categories in the document but only a subset is suitable for adding parameters.

 

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





0 Likes
Message 5 of 8

mohd.fadel
Enthusiast
Enthusiast

Hello Revitalizer,

 

Sorry for the late reply. I'm not sure if i can use this property. Shouldn't i get all categories from the document as such:

 

Categories cats = doc.Settings.Categories;

[http://thebuildingcoder.typepad.com/blog/2014/04/category-support-for-shared-type-and-instance-param...

 

If so, again i can't use this. Because i'm doing this on startup. Which is the main issue here (i can't get the document on startup).

 

I ended up initiallizing the categories and adding the triggers manually. A bit tiring, but it got the job done!

 

Just wanted to let you know.

 

Thanks,

 

M. Fadel

0 Likes
Message 6 of 8

Revitalizer
Advisor
Advisor

Hi,

 

what about this:

 

You could check which Category is suitable for adding parameters when in document context.

 

Note that you can get the relating BuiltInCategory of a Category by just casting its Id.IntegerValue.

 

After that, you have a list of BuiltInCategory to whom parameters can be added.

 

This list is constant, it won't change between different documents.

So you need to do it exactly one time and don't need to do it again.

 

You could write down the BuiltInCategory list, somewhere.

 

Once knowing the list, you can define a ElementMultiCategoryFilter using it, independent of document context.

 

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





0 Likes
Message 7 of 8

mohd.fadel
Enthusiast
Enthusiast

Hello again Revitalizer,

 

I rechecked Matt's question! I think this post has been edited in the past couple of weeks! hahaha I just saw the last part!

 

I was able to use Arnošt's code, very simple!

 

I implemented an OnApplicationInitialized event. Inside, i used the condition you suggested (AllowsBoundParameters).

 

Works perfectly!! With much less code!

 

 

Thanks for your help!

 

M. Fadel

0 Likes
Message 8 of 8

mohd.fadel
Enthusiast
Enthusiast

Hahahaha i was writing you when you sent your message!

 

That is exactly what i did!:)

 

Thanks again!

0 Likes