Easiest way to plot a node structure which re-groups its nodes? - c#

The kind of structure I am talking about is shown in the picture below.
By now my DB contains each item with giver_id (the previous item) | receiver_id (the next item). When I retrieve these items in-memory, I would like to show them in a meaningful way to the user.
I have researched and this seems to be called a "vertex/edge graph". The only option I've found is QuickGraph, and I don't seem to be able to implement it in my WindowsForm application (which is my other constraint).
Anybody knows about any other options to solve this problem?
Note: my solution does not need to be perfect, it will be used internally as a helper to configure the node chain in the DB.

Related

Get selected items in solution with native interfaces

I am trying to get all selected items in a solution and this with native code. With native code I am referring to code which does not use the DTE.
I checked the documentation and tried to find a suitable solution, however I din't come very far. What I found was the IVsUiHierarchy which contains the ExecCommand method which contains the following.
Commands that act on a specific item within the hierarchy. (If ItemID equals VSITEMID_SELECTION, the command is applied to the selected item or items.)
So I suspect the method they are talking about, is the before mentioned ExecCommand one. For one I am not quite sure how I will get to the IVsHierarchy object from a IVsHierarchy or similar, on the other hand I am not really sure on how to use the ExecCommand method properly. Additionally I am not even quite certain, if this is even the 'right way' of approaching this.
Note: I am searching for a solution which does not contain the following code in this answer.
You can use IVsMonitorSelection.GetCurrentSelection, to identify all the selected items in the solution explorer.
The above will return you an IVsMultItemSelect interface which you can use to invoke IVsMultiItemSelect.GetSelectedItems to retrieve an array of VSITEMSELECTION values.
There are a few extensibilty samples, that utilize GetSelectedItems, you can use as a reference.
Sincerely,
Ed Dore

What is the best way to associate a Nested Content node to an Umbraco Member

My initial thought was to create an Umbraco Relation and associate the Umbraco Member to the Nested Content node. Sadly, I found this form post asking a similar question and as you can see in Matt Bailsford's first response:
Unfortunately nested content can't have an ID value as they don't truely exist
I did find the issue/feature that was discussed in the forum post; however, it just adds parent information to the DetachedPublishedContent object and doesn't solve my issue. After reading the form post and the conversations of Hendy Racher, Matt Bailsford and Lee Kelleher in the github pull request, I still don't understand why Nested Content doesn't create a node in Umbraco.
So basically I need the Nested Content nodes to be created as Umbraco nodes and then stored as a JSON string in the property field. There are a few ways that I see this could be accomplished:
Create a Custom Property Editor for Umbraco Backoffice - I would start with a copy of Nested Content and add code to create the node and attach it before saving the node as a JSON string.
Use the Umbraco Multinode Treepicker control - This control was suggested by Hendy and Jeavon in this forum post as a way to allow a user to select multiple content nodes. Unfortunately going this route would require the user to create the "nested content" nodes first. Then they could associate those "nested content" nodes with the original node. We really like the user experience of the Nested Content control where it allows you to create nodes dynamically in the property editor.
Find a way to associate the Member to the "Nested Content" node - This option would require that I store an association between the top node and it's respective "nested content" node to a Member in Umbraco. There are two issues that come to mind when trying to go this route:
How should I associate the "nested content" node to the Member in a standard Umbraco way? - I immediately think of creating a link table in the database but, in my understanding, that is not the standard Umbraco way. I am still fuzzy about the best way to do this inside Umbraco.
Is there a way to uniquely identify the "nested content" node? - I realize there is a sort order value being set according to the pull request I found above but if the user reorders the nested content items will it change the "nested content" node to member association?
At this point, I am leaning towards going with option 1, but I wonder if option 3 is a better direction. In reality, I don't believe this is a new problem that someone hasn't already solved, and I hate to create another custom property editor if there is one just like it out there already.
So if you know of a better way to solve this problem please let me know.
The problem is - as you mention it - that Nested Content nodes aren't really real nodes. I don't think the right way to solve your problem is to try hacking Nested Content into doing something it really wasn't created to do.
The problem about creating nodes and also having references to them on the Nested Content node is that essentially every node in Umbraco needs to "live" somewhere.
You could choose to say that a node lives under the parent it is nested into, but how would you then differentiate between nested nodes and actual child nodes - this would require another hack as it is really working around how nodes are meant to be structured and handled in the Umbraco core.
Even if you did manage to get this working, I suspect you would have a lot to deal with to actually make it work as good as Nested Content currently does:
You would have somehow wrap every single node in the Nested Content editor into a object to be able to store meta data like the node ID it is connected to and the sortOrder when reordering all of the nested content nodes you have on there.
(edit: I think it actually already stores some sort of wrapper object here, but you would have to change the logic in here to actually handle a reference to another node instead of just deserializing json stored here, as a node)
You would also have to manually hook into events making sure the actual edits you do while on the parent node actually ends up being persisted to the nested nodes.
Deleting a nested content node, or a parent that has any nested nodes - you would have to handle deleting any orphaned nodes.
There's most likely a lot of stuff I've missed but my point is - you will have a lot of trouble trying to do this.
I think you should consider another approach if you really need to do this:
It would be possible to create a picker similar to a normal node picker, that simply allows you to browse through nodes as a normal picker would do. When you pick a node, instead of just selecting it, it should then fetch the nested content nodes and show those in the UI.
There's however the little quirk that you could essentially be having multiple properties storing each their set of nested content nodes on one single content item - so you would need some nice way of handling this in the UI.
When you select one or multiple of the nested nodes, what your picker would store would be something similar to [guid-of-the-real-node]_[propertyAlias]_[guid-of-nested-content-item].
I am not certain if Nested Content ever got the GUID unique ID/key feature implemented - Matt and I discussed it some time last year and we tried adding it in, in a custom build I needed for a project. If it isn't there I would suggest you ask Matt if he can get that in. It was essentially just giving each nested content item a "fake" unique ID (GUID) that you could use to identify it from other nested content items stored in the property. (You would have to ask Matt about the status of this)
Doing this would allow you to (on your member) have a reference that you lets you find the actual content node, then the property where the content is stored, and lastly the actual nested content node you have picked.
You should however note that this is very prone to breaking and needs a lot of null handling:
If you change the property alias of the property you are storing nested content in on the parent, it will lose the reference.
If you delete the content item storing the nested items, the picked items no longer exist and you have a missing reference in the picker on your member (needs null handling)
If you delete a nested content item - same as above. You have a missing reference in your picker.
Apart from the solution above, I don't really see another way of doing this currently with the requirements you have.

Sitecore - Programatically modify the source field of a template

Currently, all the templates that we have created have source fields whose path is a string.
e.g. :
"sitecore/content/Test"
Now if I want to move the Test folder to
sitecore/content/Shared/Tags/Test
the links are broken.
If i manually change this to use the GUID (Using the build option), I get :
datasource={62CF8494-B148-4B2E-9D36-52EC4CD75E13}&database=master
If i now move the test folder around, my links remain as is.
I wanted to write a routine that runs through the tree and updates all the source fields for my templates (in a particular folder only), to contain the GUID and db name.
Is this possible?
I tried doing this in the Process method of a class that inherits from PublishItemProcessor and added the appropriate entry in the web.config. This method is called, but the Source property of the field is read only and cannpt be modified.
Any ideas?
Thanks in advance.
The best/most efficient option here would be to use Sitecore Powershell Extensions to modify the items.
This is a good reference point: https://sitecorepowershell.gitbooks.io/sitecore-powershell-extensions/content/working-with-items.html
You could also do this in code.
You need to write a routine (code or SPE) that starts with the /sitecore/templates/user defined or whatever your root folder is.
Recurse thru the tree and get all items that have the template: Template Field. Then you can check value of the the Source field. If it is the one you want to change, update the value and save the item.
Remember to publish the templates tree after updating all the values.

How to access element cut areas/filled regions through Revit API

I'm trying to figure out how to access the filled regions created when an object is cut in plan or section. My aim is to write a tool that duplicates these regions in order to quickly create dual hatches in a view.
I'm unsure at the moment whether these regions are associated with the family instance itself, or the view, or the work plane, etc.I've poured through Revit Lookup but can't locate it.
There is some information here about creating new filled regions through
FilledRegion.Create(...)
But I'm more interested in accessing the ones already created in a view.
Any suggestions would be much appreciated.
The code snippet below would return Elements of all the FilledRegions of the current Document (doc) in a specified View (v). I hope that gets you going in the right direction.
FilteredElementCollector collector = FilteredElementCollector(doc,v.Id).OfClass(typeof(FilledRegion));
Sorry, I misunderstood what you were looking for.
You can get the CutPatternId of a Material, which would return the pattern you see when an element is cut. I don't have a code snippet for you, but, what you'd want is:
User selects the Element
API gets all the Materials of that Element
API returns all the CutPatternIds of those Materials
(FillPatternElement)
API returns all the FilledRegionType(s) with
the same FillPatternId (creating them is necessary)
API generates the FilledRegion using the correct FilledRegionType.
Item 5 is the trickiest part because I'm not sure how you could determine the boundary it's supposed to draw. #jeremy-tammik is super smart, and he's the author of the blog you referenced. Maybe he could fill in the gap on this part. Maybe there is something you could return from an "Intersect" method?

Dynamically mapping xml fields to a static object

I would like to provide the user a visual DOM like representation of an XML structure (here a completed infopath form) and allow them to specify which elements of the xml data they want to map to a statically compiled object.
As an example, the user has an infopath form that allows them to enter a sales deal, they fill it out and submit, the app should allow them to see the structure of the data in the infopath form (in a friendly, treeview kind of way) and specify how it should map to a static representation of the sales deal (think of a row that might go in the "Deals" table).
The Infopath forms (xml source) are not controlled by me.
I'm looking for suggestions on how to display the treeview of the XML and allow interaction with it to specify the mapping (possibly drag and drop?).
This will be in a wpf application (I know I'll have to host the infopath control in a forms host since it is not wpf) written in c#, and we would prefer to use .Net elements provided by Microsoft or open source software.
Edit: As a more thorough example, let's say there is an infopath form that results in xml that looks something like:
<Deal id="1" dateBooked="2011-01-01" term="24" language="en-us">
<Salesman>Jim Flowers</Salesman>
<FinancedAmount>55000.00</FinancedAmount>
<Items>
<Item id="1" quantity="10" unitPrice="10000.00">Tractor</Item>
<Item id="2" quantity="1" unitPrice="5000.00">Spare Blade</Item>
</Items>
<Notes>
<Note dateAdded="2010-09-20">Customer needs a spare blade</Note>
<Note dateAdded="2010-12-31">Customer wants to sign the deal on new year's day, I find this odd...</Note>
</Deal>
I want the user to, at run time and in an intuitive manner (the user will not know xpath...) map specific nodes of a treeview of this document to a field on my "Deal" object. So, the Deal object might have an id, salesman, amount, items collection, etc. that need to be populated but the notes and some other data are ignored, and the forms will not be the same (info path is providing configurable forms for the user to get data into the system however they want) or named in any consistent matter. The user is specifying the mapping.
Andreas's solution looks like it would be a good first step. Looks like for your input it would need to recurse into attributes of the nodes as well tho.
My description of your plan would be:
Build a control that shows all the data (Andreas uses a TreeView)
You'd probably want to show the Name and the Value for each
Build a similar control for the Object you are loading into
Setup events to build the mapping
You mentioned dragging between them
Or if they are both checkbox trees maybe have them check one in the Xml tree, then one in the Object tree and reset both, building a list of the mappings created
Finally use that mapping list to fill the object
I don't see any simple way to do it, its a lot of work and a lot of it depends on the specifics of the implementation so I can't just give you code that can do it.
How I think I might do it to get it working quickly:
Recurse through the xml generating xpaths as you go for each and every value
Load all of those xpaths and the names and values they represent into a table to be displayed to the user
With columns for "Name", "Value", "xpath"-hidden, "Load Into Property"-dropdown
Build a drop down listing every property in your object, have that in a column in the table displayed to the user
Basically I believe you need to break this down into smaller steps, and search for help on each specific step.
I'd go the simpliest way possible - create a treeview from the given xml and add a checkbox to each node. When the user clicks the "OK" (or whatever) button, you iterate all checkboxes that are checked and build your object.
Creating a treeview from a xml is rather simple - this should work (i did not test it however!)
public static class TreeViewExtensions
{
public static void LoadXml(this TreeView treeview, XmlDocument doc)
{
treeview.Nodes.Clear();
RecursiveImport(treeview.Nodes, doc.ChildNodes);
}
private static void RecursiveImport(TreeNodeCollection tvNodes, XmlNodeList xmlNodes)
{
TreeNode tvNode;
foreach (XmlNode xmlNode in xmlNodes)
{
tvNode = new TreeNode(xmlNode.Name);
if (xmlNode.ChildNodes.Count > 0)
RecursiveImport(tvNode.Nodes, xmlNode.ChildNodes);
tvNodes.Add(tvNode);
}
}
}
Edit: Well basically, you could list all xml fields in a listbox, and all fields of your object in another. When a user drag & drop's 1 field to your object's listbox, you'd need to save this relationship in another object.
I'm not familiar with wpf but this article seems pretty good - http://www.codeproject.com/KB/dotnet/csdragndrop01.aspx
The "link" Enumeration type looks pretty promising for what you try to achieve.

Categories

Resources