Trigger when adding new element.

Trigger when adding new element.

mohd.fadel
Enthusiast Enthusiast
2,905 Views
16 Replies
Message 1 of 17

Trigger when adding new element.

mohd.fadel
Enthusiast
Enthusiast

Hello everyone,

 

I'm still not quite sure if i get this right. Using a Dynamic Model Update, the GetAddedElementIds() function  retrieves added parameters, or added elements?

 

I mean, when i'm using GetAddedElementIds(), i'm waiting for a parameter to be added to the element, or i'm waiting for the user to draw a new element?

 

I'm trying to set a parameter's value for newly drawn elements.

 

This is my code:

 

 

                foreach (ElementId id in
                  data.GetAddedElementIds())//.GetModifiedElementIds())
                {
                     Element elem = doc.GetElement(id);
                     ParameterSet parameters = elem.Parameters;

                     foreach (Parameter param in parameters)
                     {
                         if (param.Definition.Name == "TEST")
                         {
                            switch (param.StorageType)
                             {
                           case Autodesk.Revit.DB.StorageType.String:
                                      if (!String.IsNullOrWhiteSpace(param.AsString()))
                                      {
                                          param.SetValueString(elem.UniqueId.ToString());
                                          param.Set(elem.UniqueId.ToString());
                                      }
                                  break;
                             }
                      }
                     } }

 

 

 

Note: I'm able to set the value if i use GetModifiedElementIds() and just try to modify an exiting element's parameter.

 

 

Any help is appreciated.

 

M.Fadel

0 Likes
Accepted solutions (1)
2,906 Views
16 Replies
Replies (16)
Message 2 of 17

jeremytammik
Autodesk
Autodesk

Dear M. Fadel,

 

A simpler way of obtaining newly added elements is to subscribe to the DocumentChanged method.

 

However, it does not allow you to modify the document in the same transaction as the action that triggered it, like the dynamic model update does.

 

Here is a comparison of the two approaches:

 

http://thebuildingcoder.typepad.com/blog/2012/06/documentchanged-versus-dynamic-model-updater.html

 

Best regards,

 

Jeremy



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

0 Likes
Message 3 of 17

mohd.fadel
Enthusiast
Enthusiast

Hello Jeremy,

 

Thank you for your reply. I'm aware of both approaches and how the first is read-only (that was my starting point).

 

I was able to work with the IUpdater class after a long struggle (not easy to work with). But like i said, i'm only being able to GetModifiedElementIds().

 

If i try GetAddedElementIds() to simply output a message:

 

          foreach (ElementId id in data.GetAddedElementIds())
                {
                    System.Windows.Forms.MessageBox.Show("Hello");
                }

it's not working. Is there a special way to draw a new element (for example Column) to the Revit project?!

 

 

M.Fadel

0 Likes
Message 4 of 17

jeremytammik
Autodesk
Autodesk

Thank you for your appreciation.

 

Glad you know what you are doing.

 

Of course it is not working!

 

Every call to the method returns a new list.

 

If you call it several times in a row, all except the first call will return an empty list.

 

Store the result of the first call to GetAddedElementIds in a suitable container, and then iterate over that instead of calling it anew every time.

 

Cheers,

 

Jeremy

 



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

0 Likes
Message 5 of 17

mohd.fadel
Enthusiast
Enthusiast

Oh!! I thought GetAddedElementIds() was the final list (usable by the program).

 

OK, I have 2 questions in this case:)

 

 

        1- How come you used the Id directly in your code in your blog:

 

 

 foreach( ElementId id in 
      data.GetAddedElementIds() )
    {
      View view = doc.GetElement( id ) as View;
 
      if( null != view 
        && ViewType.Elevation == view.ViewType )
      {
        TaskDialog.Show( "ElevationWatcher Updater",
          string.Format( "New elevation view '{0}'",
            view.Name ) );
      }
    }

 

        2- How come the GetModifiedElementIds() is usable as a list and the GetAddedElementIds() is not?! Is it because there's a chance of deciding to delete the new element?

 

 

Thank you for your help! I'm kind of finishing up here at the office now. Will check it first thing tomorrow!:)

 

M. Fadel

0 Likes
Message 6 of 17

jeremytammik
Autodesk
Autodesk

'Oh', from me too.

 

I think I was just plain wrong.

 

An all-too-quick assumption.

 

But if that is not it, then in what way is it not working for yoou?

 

By the way, if you are having any problems with DMU, you should always try out ChangeTypeAny and see whether that improves things.

 

Cheers,

 

Jeremy



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

0 Likes
Message 7 of 17

mohd.fadel
Enthusiast
Enthusiast

Hahahah. No problem.

 

What's not working is that when i add (draw) an element and not a parameter, my code doesn't work: 

 

 

foreach (ElementId id in data.GetAddedElementIds())
                {
                    System.Windows.Forms.MessageBox.Show("Hello");
                }

 

However, if the element already exists, and i'm trying to modify a parameter in this element (using GetModifiedElementIds()) it works.

 

So again, my initial question is this:

 

Is the GetAddedElementIds and GetModifiedElementIds functions at the level of adding, modifying, and deleting parameters, or on the level of adding, modifying, and deleting elements?!

 

 

Note: I tried to answer myself this question. I added a new parameter to my element (because modifying a parameter worked for me) to see if the message "Hello" will work, but it didn't! So this made me wonder even more!!:p On which level do these functions work?!!!

 

 

And one last thing, i can't use ChangeTypeAny because again, i'm trying to update my parameters. So i can't be using the DocumentChanged method.

 

Thanks in advance:)

 

M. Fadel

0 Likes
Message 8 of 17

jeremytammik
Autodesk
Autodesk

The element ids always refer to database elements, not to parameters.

 

Yes you can use ChangeTypeAny.

 

That defines your trigger, and means that it reacts to any change, including parameter modifications.



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

Message 9 of 17

Revitalizer
Advisor
Advisor
Accepted solution
Message 10 of 17

mohd.fadel
Enthusiast
Enthusiast

Hello Revitalizer,

 

Thanks for your post.. I followed Tim's code. Again, it's only working when modifying an element. But not when the element is newly added (drawn). And when i replaced:

 

Element.GetChangeTypeAny()

 

with

 

ChangeType.ConcatenateChangeTypes(Element.GetChangeTypeGeometry(), Element.GetChangeTypeElementAddition())

 

 

like you suggested, i got this error:

 

Third party updater 'WatcherUpdater' has experienced a problem and its action had to be canceled.

 

I attached my complete code in this post. If you can have a look i would really appreciate it!

 

M. Fadel

0 Likes
Message 11 of 17

Revitalizer
Advisor
Advisor

Hi,

 

you cannot modify an Element in the "OnModified"-Updater since it would generate a circular reference.

Modifying would trigger the Updater again and again and again...

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





0 Likes
Message 12 of 17

mohd.fadel
Enthusiast
Enthusiast

Hey,

 

So you think i should ommit Elmnts.AddRange(data.GetModifiedElementIds())?

 

I did, the same error occured.

 

M.Fadel

0 Likes
Message 13 of 17

Revitalizer
Advisor
Advisor

Hi,

 

my fault.

You can indeed modify Elements in the Execute method, but you cannot create new ones.

 

May it be that your ElementCategoryFilter is too common ?

In this version, you monitor thousands of elements without need.

 

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





0 Likes
Message 14 of 17

mohd.fadel
Enthusiast
Enthusiast

Hello again,

 

That's it! I tried applying a BuiltInCategory.OST_StructuralColumns as the filter. It worked fine!

 

Should i just add all categories manually? As i understand i can't use the AllowsBoundParameters function to get all my needed Categories on StartUp.

 

Is there any easier approach to this?

 

M.Fadel

0 Likes
Message 15 of 17

mohd.fadel
Enthusiast
Enthusiast

Hello again Jeremy,

 

Just wanted to let you know that Revitalizer helped me out with this problem. Actually, he showed me a post you participated in a couple of months ago. I think you were right the first time! I believe this solved the issue:

 

                List<ElementId> Elmnts = new List<ElementId>();
                Elmnts.AddRange(data.GetAddedElementIds());

I'm really not able to comprehend all this. I hope i will have an in-depth understanding of this once i am done with the work at my hand.

 

I appreciate your help!:)

 

M.Fadel

0 Likes
Message 16 of 17

Revitalizer
Advisor
Advisor

Hi,

 

I thought that you already use this get-BuiltInCategories-one-time-approach:

http://forums.autodesk.com/t5/revit-api/retrieve-all-elements-on-start-up/m-p/5844763/highlight/true...

 

What's so complicated in getting a document's categories, checking one property and casting the category's Id.IntegerValue to a BuiltInCategory ?

As already said, such a function would only to be run one single time in document context.

A throw-away macro.

The resulting list of BuiltInCategories (to whom a parameter could be added) is document independent, thus can be used OnStartup to initialize your MultiCategoryFilter.

 

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





Message 17 of 17

mohd.fadel
Enthusiast
Enthusiast

Hahaha! Good memory!!

 

I was using this method.. But it got complicated once i used the DocumentOpenedEventArgs, DocumentChangedEventArgs, and a OnStartUp methods. I'm not saying it didn't work! I made it work.

 

But i saw Tim's solution, and found it much easier! I thought maybe it would work (appartently for specific categories:s)! This made me forget about my initial dilemna!

 

For that i apologize! Thanks for your help yet again:)

 

M.Fadel

0 Likes