How to fetch diagram object of EA.Element - c#

I have EA element. How can I get the Diagram object or Diagram id for the element's parent?
I am creating EA element through a tabular form. I want to programmatically add this element to the Diagram of parent element.
Parent element is already added to the diagram.
How can I get that parent diagram ?

You can not legally place the same element twice in the same diagram. The automation still (I guess) allows to do it, but is has strange side effects, so you should not attempt it.
If for any reason you want to do so, you need to locate the diagram itself. Since an element can be in more than one diagram, you have to find the relevant diagram or deal with all diagrams where it is placed. To find them you can issue the following:
Repository.SQLquery("SELECT do.diagram_id FROM t_diagramobjects AS do INNER JOIN t_object ON do.Object_ID = t_object.Object_ID WHERE t_object.ea_guid = '{B979A0E9-17CB-4ed2-ADAB-D6FB3BE10A2B}'")
Just replace the example GUID with that of your object. In return you get a XML string that lists all diagram ids where the element is used. This query looks into all diagram objects where your element is used and returns the diagram id of the appropriate diagram.
Now you can do whatever evil you want to do with those diagrams.
Well, honestly there is a legal way to have an element twice on a diagram. This is by using a virtualized connector. I haven't used that (neither manually not per automation) so far except for a short manual test. I can have a look if you need that.

Related

Show Tags in Enterprise-Architect Diagram via Add-In

I am using the following code to generate a diagram in Enterprise-Architect (Add-In with C#):
using EA;
...
public int AddDiagram(string name)
{
Package treeSelectedPackage = repository.GetTreeSelectedPackage();
Diagram dgr = treeSelectedPackage.Diagrams.AddNew(name, "Extended::Requirements");
dgr.Update();
treeSelectedPackage.Diagrams.Refresh();
treeSelectedPackage.Update();
return dgr.DiagramID;
}
repository is an EA.Repository-Object.
I am able to add elements to the diagram, but I need to turn on the display of tags/tagged values in the diagram. In Enterprise-Architect you enable it by:
right click in diagram -> Properties... -> Tab 'Elements' -> Show Compartments: Check 'Tags'
What do I have to add to the method above to enable this for a new diagram?
In the Diagram class, some of the diagram's properties are available for setting (eg ShowPackageContents), while others are not. The element tag property is one of the latter.
However, there are two additional attributes which encapsulate the other properties, StyleEx and ExtendedStyle, which correspond to the t_diagram table's StyleEx and PDATA columns, respectively. Both of these are read/write, but their contents are undocumented so there is no guarantee that the layout won't change from one version of EA to the next (although in practice you're safe since EA is typically very good at maintaining backward compatibility).
Each is on the form keyword=value;, where the value in most cases is 1 or 0 for true/false. The element tag property is in ExtendedStyle and is called ShowTags.
EA sets all these properties when the diagram is created, but you only want to change one. So what you need to do is create the diagram including the Update() call, do a search of ExtendedStyle, replacing ShowTags=0; with ShowTags=1;, and then call Update() again.
You might have to update the database, "ShowTags=0;" in t_diagram table, use repository.SQLQuery method

Umbraco: differences between Node, DynamicNode, Content

Then there are many class that represents Umbraco documents:
1) umbraco.cms.businesslogic.Content
2) umbraco.cms.businesslogic.web.Document
3) umbraco.MacroEngines.DynamicNode
4) umbraco.presentation.nodeFactory.Node
Are there any others?
Can you explain what they do, and when to use them?
umbraco.MacroEngines.DynamicNode and umbraco.presentation.nodeFactory.Node seem the same. Perhaps it is better to use Node class because it is faster?
I have a theory:
umbraco.cms.businesslogic.Content and umbraco.cms.businesslogic.web.Document are the representation of cmsContent and cmsDocument DB tables.
umbraco.presentation.nodeFactory.Node and umbraco.MacroEngines.DynamicNode represents the node cached in XML file, to utilize into website.
The first is the simply Node, the second is the same Node with added dynamic properties, one for property defined in nodeType.
So, I think that Node is faster than DynamicNode
Is there someone that can confirm this?
Based on personal use:
Content: Never use it directly, rather use the Document|Media|Member api (which inherits from this class).
Document: Use it for Create|Update|Delete operations. It does all of its operation directly to DB, so it should be used for Reading only when you need to values directly from the db.
Node: Use this most: when Reading|Displaying data through usercontrols, code libraries, xslt extensions, etc.
DynamicNode: Razor macros. I have not yet use this one enough to provide more info.
See below for more detail, but no, Node and DynamicNode are not the same (DynamicNode uses Examine and will also fall back to reading from the DB if needed).
umbraco.cms.businesslogic.Content:
Content is an intermediate layer between CMSNode and classes which will use generic data. Content is a datastructure that holds generic data defined in its corresponding ContentType. Content can in some sence be compared to a row in a database table, its ContentType holds a definition of the columns and the Content contains the data. Note that Content data in umbraco is not tabular but in a treestructure.
I have never had the need to use this class directly though, as all of its operations are handled by the corresponding subclass, e.g: Document, Media, Member. This class in turns inherits from CMSNode which is the base class for every piece of content data inside umbraco
umbraco.cms.businesslogic.web.Document:Document represents a webpage, published Documents are exposed to the runtime/the public website in a cached xml document.
Use this class when referencing nodes from your "Content Section". It handles CRUD operations. Through this class you also get a reference to the DataType of each property in case you want to render those controls in an aspx page.
umbraco.NodeFactory.Node: It implements the INode interface which exposes read-only methods. All of its information comes from the umbraco cached xml. You will not get access to the controls of each property, rather the values of each formatted depending on the datatype.
You can only use this class for reading operations. It makes it really fast to show data since everything comes from cache (published nodes only).
umbraco.MacroEngines.DynamicNode: It was implemented to work with razor macros. It uses NodeFactory under the hood, which means it also access the cached xml. Although if you use the related DynamicMedia be careful as it uses: 1: ExamineIndex which strips out any html tags, 2: it falls back to its default Media type (db if it isn't in runtime cache) in umbraco_v4.11.5.
Same as the above.
I just know the difference between Document and Node.
The Node class uses the data stored in the umbraco cache, the Document class will get data directly from the database.
Node is faster than Document.
Node only returns the content that is saved and published.
95% of time you should use Node.
Content allows you to retrieve/edit any content (page/media/..) from DB (including non-published content), Document allows you to retrieve/edit only page content from DB (including non-published content), Node is used for fast read-only access to (published only) page content from the XML cache and Dynamic Node is comparable to Node but implemented in later versions of Umbraco for macros using Razor

C# Graph Algorithm for shortest path

Here is my problem. I have a series of photos of different parts of a building and I need to link them together. After that I need to show each photo in sequence to display a path from point A to point B… I.e., from a classroom to a fire escape.
I have done a bit of research and I believe a non-directed unweighted graph should do the trick.
As I have not much experience in this area. I was wondering how I need to store the photos in a data structure and if there are any libraries out there to do the job?
Yes, you need to apply some algorith, that can solve the problem for you.
You can use this great libray:
QuickGraph
to solve this part of the problem.
As to the way of storing your data, you need to define vertices (the photos) and edges between vertices like (photo A-photoB), (photo A-photo C), and so on.
You have to recover that info from the database and load the corresponding structure in quickgraph and let it find the path for you.
Here you have extensive docs and samples:
Quick graph documentation
For something similar to this I used:
MyEdges class, which implements IEdge<T> (T should be you photo ID type, int or whatever is) - represents the edge between to photos (places)
Graph class, which inherits AdjacencyGraph<T,MyRelation>. You load it with the available MyEdges (this is directed graph)
PathFinder algorithm class: I inherited from FloydWarshallAllShortestPathAlgorithm<T, MyRelation>
Then you have to:
Create the edges (i.e. read them from the DB)
Instance a Graph class, and add all edges to it
Use the PathFinder constructor, using the graph as parameter. This finds the paths.
This algorithm lets you specify to which photos you can go from a given photo (edges), supposes that the distance is similar between them, but you have to define all the routes (from A to B, from B to A and so on). That's the "un-weighted" part of the OP. If your case differs you'll have to read the docs.
You can implement an UnDirected graph if you prefer that adding A To B also adds B to A. It can spare some lines of code, but I usually prefer adding all the possibilities myself. Its easier to think "from the Library I can go to aisle A and aisle B. From aisle B to Library and Laboratory", and so on, that trying to think of all edges.
You can create two tables in a database:
Photos (with IDs)
Path (IdFrom and IdTo)
This is easy to maintain and implement.

Localize node texts in treeview using resource files

For a project I need a tree view that allows the user to select a module, which then is displayed in a content area. The project relies heavily on localization and this is provided by the resource files.
Now I discovered today, that the text that are assigned to preset tree view nodes are not contained in the resource files.
So the question is whether there is a way of doing this, short of mapping the elemenst in code. I.e. assigning a name to the node, running over all nodes and pulling the resources from the resouce manager based on the node name.
This is what I am currently doing, however, it just doesn't "feel" right:
private void TranslateNodes(TreeNodeCollection treeNodeCollection) {
var rm = Resources.ResourceManager;
foreach (TreeNode node in treeNodeCollection) {
node.Text = rm.GetString(node.Name + "_Text");
this.TranslateNodes(node.Nodes);
}
}
Thanks!
Your approach looks ok for me, with one exception, it believes that node.Name is unique though entire treeview (which is not correct in general case).
You can use TreeNode.FullPath for unique identify node within treeview. Or alternatively your code can depend on node tag value, but this is highly depend on usage scenario.
And do not forget about calling TreeView's BeginUpdate-EndUpdate.
No suitable, solution found except the one statete in the op ... so closing the question seems apropriate.

Creating objects driven by the database to populate a Treeview - very slow

I have an application that reads a table from a database.
I issue an SQL query to get a result set, based on a unique string value I glean from the results, I use a case/switch statement to generate certain objects (they inherit TreeNode BTW). These created objects get shunted into a Dictionary object to be used later.
Whilst generating these objects I use some of the values from the result set to populate values in the object via the setters.
I query the Dictionary to return a particular object type and use it to populate a treeview. However it is not possible to populate 2 objects of the same type in a treeview from the Dictionary object (you get a runtime error - which escapes me at the moment, something to with referencing the same object). So what I have to do is use a memberwiseClone and implement IClonable to get around this.
Am I doing this right? Is there a better way - because I think this is causing my program to be real slow at this point. At the very least I think its a bit clunky - any advice from people who know more than me - greatly appreciated.
Is there a reason you are using the external dictionary? I would populate the tree directly as the data is queried.
If you do require the dictionary, you could set the .Tag property of the tree node to point to the data in your dictionary.
To add to #Brad, only populate the tree as needed. That means hooking into the expand event of the tree nodes. This is similar to how Windows Explorer functions when dealing with network shares.
There should be 1 TreeNode object per actual tree node in the tree - don't try to reuse the things. You may either associate them with your data using the Tag property (this is the recommended method), or you can subclass the TreeNode itself (this is the Java method, but used less in .NET).
(The use of cloning methods is usually a hint that you're either (a) doing something wrong, or (b) need to factor your domain model to separate mutable objects from immutable.)
have you considered using a Virtual Tree view which only loads the nodes the user actually wants to look at - i've had good success with the component from www.infralution.com

Categories