how to change my Node-Text - c#

i created some symbol without Labels, after dropping my Symbols from Palette, my symbol will automatic be labeled with Text. my problem is that the first Node-Drop from every symbol i´ve created is not labeled, after the second, third, fourth, etc. Node-Drop that node will automatic assigned with Label.
Second requirement i would to know, after dropping my Node, how can i edit my nodeText. by clicking or double-clicking the node.
Here is my Code:
protected void DiagramWebControl1_NodeDropFromPalette(object sender, Syncfusion.Web.UI.WebControls.Diagram.NodeDropFromPaletteEventArgs e)
{
if (e.Node is PathNode || e.Node is Group)
{
PathNode node = e.Node as PathNode;
if (node != null)
{
if (node.FullName == "Prozess Start")
{
node.Name = "Prozess Start";
node.Labels.Add(new Syncfusion.Windows.Forms.Diagram.Label(node, node.Name));
}
else if (node.FullName == "Prozess")
{
node.Name = "Prozess";
node.Labels.Add(new Syncfusion.Windows.Forms.Diagram.Label(node, node.Name));
}
}
else
{
Group gnode = e.Node as Group;
if (gnode.FullName == "Organisationseinheit")
{
gnode.Name = "Organisationseinheit";
gnode.Labels.Add(new Syncfusion.Windows.Forms.Diagram.Label(gnode, gnode.Name));
}
else if (gnode.FullName == "Rolle")
{
gnode.Name = "Rolle";
gnode.Labels.Add(new Syncfusion.Windows.Forms.Diagram.Label(gnode, gnode.Name));
}
else if (gnode.FullName == "Externe Rolle")
{
gnode.Name = "Externe Rolle";
gnode.Labels.Add(new Syncfusion.Windows.Forms.Diagram.Label(gnode, gnode.Name));
}
else if (gnode.FullName == "IT-System")
{
TextNode rtxNode = new TextNode("");
rtxNode.Text = "IT-System";
gnode.Labels.Add(new Syncfusion.Windows.Forms.Diagram.Label(gnode, rtxNode.Text));
}
}
}

Since the node’s FullName is generated uniquely by appending the ‘Model’ to the node’s name by the DiagramWebControl, check whether the dropped node’s FullName and the name given in your code are the same one. If you want to add ‘Labels’ to the node based on their names, then use the node’s ‘Name’ property instead of using FullName.
Refer the Syncfusion’s public forum regarding your requirement of editing nodeText in double-clicking the node.
Here's a link.

Related

C# LinkedListNode reference after calling Remove on LinkedList

My question: Hi, does method- LinkedList.Remove(LinkedListNode n) changing references of others elements in LinkedList?
Application is little bit complex so atleast I will try to explain how I got here, but maybe It will be confusing
I have a program which storing references(LinkedListNodes from
LinkedList) into another iterable class. And in some point,
application starts deleting these LinkedListNodes with
method-Remove(LinkedListNode node) and also delete this element from
my class which stores these references. It runs good for a while, but
in some point It will loose one of the reference in my class and I get
null reference(in myNode) when i want to call
LinkeList.AddAfter(myNode, value) with error: “The LinkedList node
does not belong to current LinkedList”.
EDIT:
I was translating notes, etc...
So I am using BinarySearchTree for quick search, LinkedList for normal iterating and QUEUE for deleting old elements.
This is insert in my Tree class:
public Node Insert(DictionaryPair dictionaryPair, LinkedList<DictionaryPair> dictionary)
{
Node currentNode = nodeRoot;
while (true)
{
if (currentNode == null) //if i inserting 1st element
{
nodeRoot = new Node(); //creating node(root)
dictionary.AddFirst(dictionaryPair); //inserting into Linked list on 1st place
nodeRoot.dictionaryNode = dictionary.First; //and taking a reference
return nodeRoot; //end while
}
else if (currentNode.dictionaryNode.Value.CompareTo(dictionaryPair) >= 0)
{ //sending element into left
if (currentNode.left == null) // and is empty
{
currentNode.left = new Node(); //creating new node
currentNode.left.myParent = currentNode; //reference to parent
currentNode.left.dictionaryNode = dictionary.AddBefore(currentNode.dictionaryNode, dictionaryPair);
//and inserting into dictionary (Before) current node and save the refence on it to left
return currentNode.left; //end while
}
else
{ //or shift to left
currentNode = currentNode.left;
}
}
else
{ //sending element into right
if (currentNode.right == null) // is null
{
currentNode.right = new Node(); //create new node
currentNode.right.myParent = currentNode; //reference on parent
currentNode.right.dictionaryNode = dictionary.AddAfter(currentNode.dictionaryNode, dictionaryPair);
//and insert into dictionary (After) current node and save the refence on it to right
return currentNode.right; //endwhile
}
else
{ //or shift to right side
currentNode = currentNode.right;
}
}
}
}
class Node:
public LinkedListNode<DictionaryPair> dictionaryNode;
public Node left;
public Node right;
public Node myParent;
I can call delete method on my Node:
public LinkedListNode<DictionaryPair> DeleteMe()
{
LinkedListNode<DictionaryPair> deletedNode = this.dictionaryNode;
if (this.left == null && this.right == null)
{ //Delete leaf
if(myParent.left == this)
{
myParent.left = null;
}
else // else if(myParent.right == this)
{
myParent.right = null;
}
}
else if (this.left != null && this.right == null)
{
this.right = this.left.right;
this.dictionaryNode = this.left.dictionaryNode;
this.left = this.left.left;
}
else if (this.left == null && this.right != null)
{
this.left = this.right.left;
this.dictionaryNode = this.right.dictionaryNode;
this.right = this.right.right;
}
else
{ //on left and right are tries
Node currentNode = this.left; //throught the left side
bool oneCycle = false; //possibility of not iterating once thought the left side into the right (so it would be left)
while (currentNode.right != null)
{ //searching element most to the right
currentNode = currentNode.right;
oneCycle = true;
}
if (currentNode.left == null)
{ //i am leaf
if (oneCycle)
{
currentNode.myParent.right = null; //deleting refence on me
this.dictionaryNode = currentNode.dictionaryNode; //and change a value
}
else
{
currentNode.myParent.left = null; //deleting refence on me
this.dictionaryNode = currentNode.dictionaryNode; //and change a value
}
}
else
{ //im not leaf
if (oneCycle)
{
currentNode.myParent.right = currentNode.left; //change refence on my tree
this.dictionaryNode = currentNode.dictionaryNode; //and change value
}
else
{
currentNode.myParent.left = currentNode.left; //change refence on my tree
this.dictionaryNode = currentNode.dictionaryNode; //and change value
}
}
}
return deletedNode;
}
This is my main class for working with the arrays MyDictionary, whichs have
private LinkedList<DictionaryPair> data; //for iterating search
private Tree binarySearchTree; //for quick search
private Queue<Node> queue; //references on added nodes
//in binarySearchTree... they are ready to be deleted
private int maxCount;
private bool maxCountReached;
When I am inserting into MyDictionary, I calling this method
public void Insert(DictionaryPair input)
{
if (!maxCountReached)
{
if (queue.Count() >= maxCount)
{
maxCountReached = true;
}
}
if (maxCountReached)
{
data.Remove(queue.Dequeue().DeleteMe());
}
queue.Enqueue(binarySearchTree.Insert(input, data));
}
[...] does method LinkedList.Remove(LinkedListNode n) change references of other[s] elements in LinkedList?
When we look at the source code of the LinkedList.Remove method, we find that the framework does not mess with other elements except for adjusting their prev and next pointers (in order to close the gap caused by the removal, and as per definition of the linked list principle).
Except for the border cases, it is simply
node.next.prev = node.prev;
node.prev.next = node.next;
The object (item in the internal data structure) of other elemenst is not modified by the Remove operation. The object targeted by the Remove operation itself is also not directly affected. As the node is detached from the list, it becomes eligible for garbage collection if no other living objects keep a reference.
The exception you see is generated here:
if ( node.list != this) {
throw new InvalidOperationException(SR.GetString(SR.ExternalLinkedListNode));
}
If this validation fails in AddAfter, it can mean that:
Calling code is attempting to reference an existing node that is not attached to any LinkedList at all, for example a node that was previously removed from the list. In the code you posted, this would be currentNode.dictionaryNode and I'd focus on lines where this is assigned when debugging
Calling code is attempting to reference an existing node that belongs to another instance of LinkedList.
I found a mistake in implementation of DeleteMe method in my BinarySearchTree. I didnt change parents reference of nodes which was under a found currentNode. But thank you for help. Have a great day...

Restricting child element in Enterprise Architect through C# add-in

I am working on C# add-ins in Enterprise Architect to give a restriction to user so that only a particular child element can be added to a specific parent element.
For example if child element A must be dropped on parent element B it is deleted if child element A is dragged and dropped on parent element C. I am using EA_OnPostNewElement method and a delete method for the same and it works fine.
My doubt is, after the user has dropped the child element on the specific parent, after some time he can drag the child element outside the parent element and add it as a child to any other element in the diagram.
Is there a way to add a restriction here by observing the changes made by user on Enterprise architect GUI and bring back the child element to original parent location. Kindly help.
You need to use both EA_OnContextItemChanged and EA_OnNotifyContextItemModified so you can achieve it .
declare a dictonry
public Dictionary<int, int> lstChildElements = new Dictionary<int, int>();
and here is the sample code
public void EA_OnContextItemChanged(EA.Repository Repository, string GUID, EA.ObjectType ot)
{
EA.Element addedElement = Repository.GetElementByGuid(GUID);
if (addedElement == null)
return;
int identifiedParentID = 0;
bool isAvailable = lstChildElements.TryGetValue(addedElement.ElementID, out identifiedParentID);
if (!isAvailable)
{
if (addedElement.Stereotype == "Child" && addedElement.ParentID != 0)
{
EA.Element parentElemnt = Session.Repository.GetElementByID(addedElement.ParentID);
if (parentElemnt != null)
if (parentElemnt.Stereotype == "anyCustomDefined")
lstChildElements.Add(addedElement.ElementID, addedElement.ParentID);
}
}
}
public void EA_OnNotifyContextItemModified(EA.Repository Repository, string GUID, EA.ObjectType ot)
{
EA.Element addedElement = Repository.GetElementByGuid(GUID);
if (addedElement == null)
return;
int identifiedParentID = 0;
bool isAvailable = lstChildElements.TryGetValue(addedElement.ElementID, out identifiedParentID);
if (isAvailable)
{
if (addedElement.Stereotype == "Child" && addedElement.ParentID != 0)
{
EA.Element parentElemnt = Repository.GetElementByID(addedElement.ParentID);
if (parentElemnt != null)
if (parentElemnt.Stereotype != "anyCustomDefined")
{
addedElement.ParentID = identifiedParentID != 0 ? identifiedParentID : addedElement.ParentID;
addedElement.Update();
lstChildElements[addedElement.ElementID] = addedElement.ParentID;
}
}
else if (addedElement.Stereotype == "Child" && addedElement.ParentID == 0)
{
addedElement.ParentID = identifiedParentID;
addedElement.Update();
}
}
}
Hope it helps..!
and for updating in diagram need to reload it.
EA.Diagram activeDiagram = Session.Repository.GetCurrentDiagram();
if (activeDiagram != null)
Session.Repository.ReloadDiagram(activeDiagram.DiagramID);
or
Repository.RefreshOpenDiagrams();
Both the codes can be used for reloading the diagram.
You can use the context events to keep track of the selected element and it's owner.
I'm not sure if the event EA_OnNotifyContextItemModified is being fired when you change the owner of an element.
But even it that is not the case you can verify if it still has the same owner after a new element has been selected.

Select a property in the property grid

I am using a PropertyGrid to display the content of an object to the user.
This PropertyGrid is synchronized with an Excel sheet, assuming a cell value match a property value.
As the user selects a property in the PropertyGrid, the application highlights the corresponding cell in the Excel sheet which is opened beside. I can do this using the SelectedGridItemChanged event.
Now, I want to have a property selected in my PropertyGrid when the user selects a cell in the Excel sheet.
void myWorkbook_SheetSelectionChangeEvent(NetOffice.COMObject Sh, Excel.Range Target)
{
if (eventMask > 0)
return;
try
{
eventMask++;
this.Invoke(new Action(() =>
{
propertyGrid1.SelectedGridItem = ... // ?
}
}
finally
{
eventMask--;
}
}
I noticed that the SelectedGridItem can be written to.
Unfortunately I do not find a way to access the GridItems collection of my PropertyGrid so I can look for the right GridItem and select it.
How can I do this?
You can get all the GridItems from the root. I am using the below code to retrieve all the griditems within a property grid
private GridItem Root
{
get
{
GridItem aRoot = myPropertyGrid.SelectedGridItem;
do
{
aRoot = aRoot.Parent ?? aRoot;
} while (aRoot.Parent != null);
return aRoot;
}
}
and pass the root to the below method
private IList<GridItem> GetAllChildGridItems(GridItem theParent)
{
List<GridItem> aGridItems = new List<GridItem>();
foreach (GridItem aItem in theParent.GridItems)
{
aGridItems.Add(aItem);
if (aItem.GridItems.Count > 0)
{
aGridItems.AddRange(GetAllChildGridItems(aItem));
}
}
return aGridItems;
}
I came up against this quite a bit a project so I wrote an extension method for it:
if (!SetupManagerSettings.BootStrapperLocation.IsFile()) // Just another extension method to check if its a file
{
settingsToolStripMenuItem.Checked = true; // Event handler OnChecked ensures the settings panel is unhidden
settingsPropertyGrid.ActivateControl();
settingsPropertyGrid.SelectPropertyGridItemByName("BootStrapperLocation"); // Here is the extension method
return false;
}
Here is the extension method with a private, supporting method for traversing the hierarchy of objects (if this applies to your object model):
public static bool SelectPropertyGridItemByName(this PropertyGrid propertyGrid, string propertyName)
{
MethodInfo getPropEntriesMethod = propertyGrid.GetType().GetMethod("GetPropEntries", BindingFlags.NonPublic | BindingFlags.Instance);
Debug.Assert(getPropEntriesMethod != null, #"GetPropEntries by reflection is still valid in .NET 4.6.1 ");
GridItemCollection gridItemCollection = (GridItemCollection)getPropEntriesMethod.Invoke(propertyGrid, null);
GridItem gridItem = TraverseGridItems(gridItemCollection, propertyName);
if (gridItem == null)
{
return false;
}
propertyGrid.SelectedGridItem = gridItem;
return true;
}
private static GridItem TraverseGridItems(IEnumerable parentGridItemCollection, string propertyName)
{
foreach (GridItem gridItem in parentGridItemCollection)
{
if (gridItem.Label != null && gridItem.Label.Equals(propertyName, StringComparison.OrdinalIgnoreCase))
{
return gridItem;
}
if (gridItem.GridItems == null)
{
continue;
}
GridItem childGridItem = TraverseGridItems(gridItem.GridItems, propertyName);
if (childGridItem != null)
{
return childGridItem;
}
}
return null;
}
I looked at the above options and did not like them that much, I altered it a bit found that this works well for me
bool TryFindGridItem(PropertyGrid grid, string propertyName, out GridItem discover)
{
if (grid is null)
{
throw new ArgumentNullException(nameof(grid));
}
if (string.IsNullOrEmpty(propertyName))
{
throw new ArgumentException("You need to provide a property name", nameof(propertyName));
}
discover = null;
var root = pgTrainResult.SelectedGridItem;
while (root.Parent != null)
root = root.Parent;
foreach (GridItem item in root.GridItems)
{
//let's not find the category labels
if (item.GridItemType!=GridItemType.Category)
{
if (match(item, propertyName))
{
discover= item;
return true;
}
}
//loop over sub items in case the property is a group
foreach (GridItem child in item.GridItems)
{
if (match(child, propertyName))
{
discover= child;
return true;
}
}
//match based on the property name or the DisplayName if set by the user
static bool match(GridItem item, string name)
=> item.PropertyDescriptor.Name.Equals(name, StringComparison.Ordinal) || item.Label.Equals(name, StringComparison.Ordinal);
}
return false;
}
it uses a local method named match, if you're version of C# does not allow it then just put it external to the method and perhaps give it a better name.
Match looks at the DisplayName as well as the property name and returns true if either is a match, this might not be what you would like so then update that.
In my usecase I need to select the property based on a value the user can select so call the above method like this:
if (TryFindGridItem(pgMain, propertyName, out GridItem gridItem))
{
gridItem.Select();
}
It could theoretically never not find it unless the user selects a string that is not proper this way the if can be updated using an else .. I rather keep it safe then have a null-pointer exception if I can't find the name specified.
Also I am not going into sub classes and lists of classes as my use case doesn't need that, if yours does than perhaps make recursive calls in the GridItem.
Small note, replace GridItem with var and the code brakes as at compile time the IDE has no clue what a GridItemCollection returns…

automatic labeling a node with a text

Hi i would like after dropping my Symbols from Palette, that my symbol to be automatic labeled with Text.
Here is the Code:
protected void DiagramWebControl1_NodeDropFromPalette(object sender, Syncfusion.Web.UI.WebControls.Diagram.NodeDropFromPaletteEventArgs e)
{
if (e.Node is PathNode || e.Node is Group)
{
PathNode node = e.Node as PathNode;
if (node != null)
node.Labels.Add(new Syncfusion.Windows.Forms.Diagram.Label( node, node.Name));
else
{
Group gnode = e.Node as Group;
node.Labels.Add(new Syncfusion.Windows.Forms.Diagram.Label (gnode, gnode.Name));
}
}
}
the problem is that every symbol (node) if its a PathNode or Group after the first dropping they are not labeled, after the second drop, third, etc.... from the same node, then they will be automatic labeled.
Need help!
Refer the Syncfusion’s public forum regarding your requirement of adding label automatically to the node. Here's a link.

How to add a child node to a dynamically added child node

I am having a treeview on my main form
I have my code from a from to main form is as follows
Buttonclick
StrNode = string.Empty;
StrNode = "Batch" + Append.Batchcnt.ToString() + "(" + strSelectedClassCode + ")";
frmmain.loadFromForm(StrNode, true, strSelectedClassCode);
On my main form i have my code as follows
public void loadFromForm(string strNode, bool bResult, string strStandardClsCode)
{
if (Append.oldbatchcontrol != strNode)
{
if (tvwACH.SelectedNode.Text == "FileHeader")
{
tvwACH.SelectedNode.Nodes.Add(strNode);
}
if (tvwACH.SelectedNode.Text == "BatchHeader")
{
tvwACH.SelectedNode.Nodes.Add(strNode);// After this i have to add another node as a child to that added node and also if a node with particular name exists i would like to write the text with a count value appended
}
}
}
So that my treeview should be as follows
ACH
|->Some.txt
|->Fileheader
|->BatchHeader
|->Batch1
|->Entry1
|->Entry2 and so on // These two should be added dynamically after that Batch1
Use this instead :
public void loadFromForm(string strNode, bool bResult, string strStandardClsCode)
{
if (Append.oldbatchcontrol != strNode)
{
if (tvwACH.SelectedNode.Text == "FileHeader")
{
tvwACH.SelectedNode.Nodes.Add(strNode);
}
if (tvwACH.SelectedNode.Text == "BatchHeader")
{
TreeNode node = tvwACH.SelectedNode.Nodes.Add(strNode,strNode);// After this i have to add another node as a child to that added node and also if a node with particular name exists i would like to write the text with a count value appended
node.Nodes.Add(...);
}
}
}
You usually need a recursive function to build a tree. For example:
private void AddNode(NodeParent, Data)
{
Node oNode;
//Check if this is the first node
if (NodeParent ==null)
{
oNode = new Node(Data.Name);
}
//Step though each child item in the data
foreach(DataItem in Data)
{
//Add the node
this.AddNode(oNode, DataItem);
}
oNode.Nodes.Add(new Node(Data));
}
This code is a rough guide, but it should give you an idea.

Categories