Buggy implementation of Custom BrowserNodes

Buggy implementation of Custom BrowserNodes

Bert_Bimmel
Advocate Advocate
1,136 Views
13 Replies
Message 1 of 14

Buggy implementation of Custom BrowserNodes

Bert_Bimmel
Advocate
Advocate

When you have created a custom browser pane and you want to insert a custom browser node, you'll have to create a "BrowserNodeDefinition" using the "BrowserPanes.CreateBrowserNodeDefinition" first, before you can then apply this newly created BrowserNodeDefinition to your new BrowserNode, which is created using the "BrowserNode.AddChild-method". The "CreateBrowserNodeDefinition" requires a unique ID wich is not automatically generated, but has to be  supplied by the caller.

So, how will you know, which is the next free BrowserNodeDefinition-ID that can be applied?

There is no BrowserNodeDefinitions-Enumerator which you can iterate through to figure out, which IDs are allready in use, and which can be applied next. Instead, there is a "GetClientBrowserNodeDefinition"-Function, which requires the ID of the desired BrowserNodeDefinition as argument. Har har!

Yet I helped myself by iterating through the BrowserNodes themselves and their applied BrowserNodedefinition, to obtain the next free ID.

This works fine, as long as you don't start deleting BrowserNodes that have been created before:

The help to the "BrowserNode.Delete"-method claims: 

"None of the corresponding browser node definitions nor the client node resources are deleted, however".

Thus, your BrowserNode is gone, but the definition is still there, and the only way to get hold of that definition is by querying it by it's ID - which you might not know any more!

So how on earth am I supposed to figure out, which new ID i will have to apply, if i want to create another new Browsernode???

Or, to put the cart before the horse: how do i get rid of the orphaned BrowserNodeDefinitions?

 

Plus, the quotation from the help above does also claim, it will not delete the ClientNodeResource. Apparently, it does so, despite the help saying it won't. At least, when the last BrowserNode referring to a certain BrowserNodeResource has been deleted, the respective BrowserNodeResource is not acessible through the API any more. (Yes, it may still resides inside the XmBrowserSegment, but what it's worth for, if I can't access it any more?)

Any suggestions (Except for counting the occupied IDs somewhere else on my own)?

 

 

0 Likes
1,137 Views
13 Replies
Replies (13)
Message 2 of 14

Bert_Bimmel
Advocate
Advocate

Ok, couldn't find the butter in the fridge: Apparently, I tried to find the BrowsernodeDefinition.Delete method (which doesn't exist indeed) instead of the "ClientBrowserNodeDefinition.Delete"-method.

Anyway, that still doesn't explain, why it can't behave like almost all other enumerator-objects in the API, or the loss of the ClientNodeResource.

0 Likes
Message 3 of 14

Bert_Bimmel
Advocate
Advocate

Hello! Anybody out there? Am I the only dork in the milky way that has ever tried to use this part of the API? And noone at Autodesk who feels responsible?

0 Likes
Message 4 of 14

Bert_Bimmel
Advocate
Advocate

Wow! Apparently, its's more important to Autodesk to remove my P00P-emoji than to take a stand for the problem!

 

And while trying to solve it on my own...

 

Seriously??? The ID - provided as 32-Bit-Integer - stored in memory in its decimal representation as null-terminated UTF16-String???

 

Bert_Bimmel_0-1637218010842.png

 

0 Likes
Message 5 of 14

Bert_Bimmel
Advocate
Advocate

Well, at least, that amateurish representation in memory enables the following workaraound which works quite fine (and surprisingly performant) when you at least know the ClientID, and that ClientID is characteristic enough to be distinguished from any other random memory content when scanning the entire processes memory space for it...

 

 

Message 6 of 14

Bert_Bimmel
Advocate
Advocate

Ok, here's the next contribution to my soliloquy here:

Something else I stumbled over, that I find pretty confusing:

 

The BrowserNode-Object contains an enumeration of child nodes, plus a link to another object named BrowserNodeDefinition. The latter contains information about the appearance of the node in the browser such as BrowserNodeIcons, label and font (bold, strikethrough etc.). Just to point out again: The ChildNode-collection is a member of the BrowserNode-object, NOT of the linked BrowserNodeDefinition-object.

So, why does a newly created BrowserNode, that re-uses the definition of a previously created BrowserNode (i.e. its appearance) , contain all the subnodes of the the original node immediately upon creation? 

So, in fact, the SubNode-collection appears to be a member of the BrowserNodeDefinition-Object and not of the BrowserNode-Object, although the structure of the API suggests something else.

I admit, that probably in most cases, the programmer that re-uses the BrowserNodeDefinition, does also want the SubNodes to appear again, as it most likely represents the same object. I did so too, but it took me a while to figure out why my code fails to create the subnodes again, as i did'nt expect them to show up automagically, due to the circumstances described above.

 

0 Likes
Message 7 of 14

Bert_Bimmel
Advocate
Advocate

And one more:

 

In order to query a certain ClientBrowserNodeDefinition-Object from the BrowserPanes-Collection, you'll need the ID plus the ClientID...

ClientID??? When creating a new ClientBrowserNodeDefinition,  you don't need to pass any ClientID as argument, do you?

... Oh wait! The ClientID is implicitly inherited from the BrowserNodeRessource-Object which has to be passed as argument, when calling BrowserPanes.CreateBrowserNodeDefinition.

 

Dear Lord! Who implemented this crap? Can somebody at Autodesk clean that up, please???

0 Likes
Message 8 of 14

Bert_Bimmel
Advocate
Advocate

can't stop scathing:

Guess what you get, if you select a browser node with your mouse, and then query the document's SelectSet:

Correct: The Underlying BrowserNodeDefinition-Object. If you want to get hold of the selected BrowserNode itself, you'll have to iterate through all BrowserNodes, and check each one's "Selected"-Property, until you find it.

 

Himmel hilf!!!

 

Is anyone at Autodesk reading this???

 

0 Likes
Message 9 of 14

Bert_Bimmel
Advocate
Advocate

...and now try to highlight multiple Browsernodes with identical underlying BrowserNodeDefinition.

 

Har har! doesn't work, beacause you can add a BrowserNodeDefinitionObject to the Document's SelectSet, which results in the first corresponding Node beeing highlighted, but all others remaining unhighlighted. If you try to ad a BrowserNode-Object to the select set, you'll receive an error.

 

Hammering my forehead onto my desk, hoping to become unconscious!

0 Likes
Message 10 of 14

Bert_Bimmel
Advocate
Advocate

One and a half years later: I'm still trying to workaround all the crap mentioned above, but here's something else, i haven't yet found a solution for:

As described before, the ClientBrowserNodeResources deflagrate as soon as the last referencing BrowserNode will be deleted. So, the most likely workaround would be, to recreate them if necessary. So far so good. 

But whereas the initial creation is satisfyingly fast, recreating them becomes slower and slower the more often they are recreated, rendering the whole thing unusable after a couple of cycles. It does not even help to close the current document and start all over again with a new document created from scratch. The only thing that helps restoring a satisfying performance is closing and restarting the application.

Idea: create a hidden browserpane which maintains nodes whose only purpose is to maintain the underlying browsernoderesources. Despite the fact, that this is really fumbled, it won't help with new documents that don't already have this hidden BrowserPane.

Maybe I should give windows.forms treeview another chance. This here is UNUSABLE!!!

 

 

 

0 Likes
Message 11 of 14

Bert_Bimmel
Advocate
Advocate

Setting the Browser's visibility-Flag to "false" will not be stored inside the File. After closing and reopening it...

 

tadaaaaaa!

0 Likes
Message 12 of 14

Bert_Bimmel
Advocate
Advocate

Ok, the idea of storing my NodeRessources inside a hidden Browser Pane of the template doesn't really help:

Whereas selecting a resource the very first time inside a new document after starting the application in order to create the new BrowserPane's RootNode takes 0,0002191 seconds. Fine!

After - i did not really count them, let's say - twenty creations of new browserpanes, this period has increased to 18(!!!) seconds. All subsequent ressource selections to draw the tree underneath the rootnode take up fractins of a millisecond again. WTF is Inventor doing in that eighteen seconds???

 

0 Likes
Message 13 of 14

Bert_Bimmel
Advocate
Advocate

And what about that transience-flag that you can set for a custom browser?

 

  • You cannot declare a custom browser as transient upon creation. This flag can only be raised after creating, and thus dirtying the document
  • No matter if the flag is set or not, subsequent changes of the browsertree will not dirty the document. if you want your browsertree beeing saved with your file, you'll have to perform any random other action to dirty the file. if you don't, the browser will still be there after saving, closing and reopening the document, but it's entire content (except for it's root node) has gone down the drain
  • when the flag is set, the browser, whose initial creation did dirty the document, will be completely purged from the file when it's saved, closed and reopened

How is this supposed to make any sense???

0 Likes
Message 14 of 14

Bert_Bimmel
Advocate
Advocate

Now, how can I move a Browser node up or down inside its branch? A MoveUp or MoveDown method is not availlable, so the obvious workaround would be: Delete the old Node and recreate it at the desired position using BrowserNode.InsertChild Method...
Har har, this function seems documented, but not implemented: No matter what (legitimate) arguments are passed as TargetNode and InsertBefore, they're simply ignored, and the new node is created at the end of the branch.

So, delete and recreate all nodes in the desired order? 🤔

0 Likes