I created a Linked list and a few nodes, I want to link those node, kept getting this error message.
"
Property or indexer System.Collections.Generic.LinkedListNode<>.Next cannot be assigned to it is read only.
"
var link = new LinkedList<int>();
var node1 = new LinkedListNode<int>(1);
var node2 = new LinkedListNode<int>(2);
var node3 = new LinkedListNode<int>(3);
link.AddFirst(node1);
link.AddFirst(node2);
link.AddFirst(node3);
node1.Next = node2; ---> .next is read only
node2.Next = node3; ---> .next is read only
You need to use the AddAfter or AddBefore methods of the list. With these you can insert items directly before or after a given item.
Unfortunately the LinkedListNode<T> class in .NET does not allow you to change the Next and Previous properties directly, since they don't have a set accessor.
If you want to change the ordering of the list, you'll also need to use the Remove method to remove the item from its previous position. I recommend the following form:
LinkedListItem<T> foo = /*fetch your item here*/
LinkedListItem<T> bar = /*the one to come right after foo,
as a result of running the code*/
list.Remove(foo);
list.AddBefore(bar, foo);
You could change that to insert after instead of inserting before.
You don't have to link them. When you invoke the AddFirst method, it automatically links them to the first node which then becomes the second node.
You're trying to add items to other items, but you should be adding them to the LinkedList itself, which you're already doing:
link.AddFirst(node1);
link.AddFirst(node2);
link.AddFirst(node3);
Are you trying to change their ordering? It looks like that can only be done when adding them, based on the methods available on LinkedList<T>. So you would want to do something like this instead:
link.AddFirst(node1);
link.AddAfter(node1, node2);
link.AddAfter(node2, node3);
Or, in your case, simply reversing the order of the calls to .AddFirst() will produce the same results:
link.AddFirst(node3);
link.AddFirst(node2);
link.AddFirst(node1);
This would add node3 to the start of the list, then add node2 to the start of the list (pushing node3 to the second element), then add node1 to the start of the list (pushing node3 to the third element and node2 to the second element).
Related
I have a populated treeView with Node I created, there are several node classes, all inherit from treeNode.
When i edit a node (using a GUI dialog), it may change to different class, so I'm creating a new node in that process, and trying to replace the selected node with my new node, but that doesn't work, the node stays the old one, cant figure out what i'm doing wrong.
Code:
TreeNodeMission mission = (TreeNodeMission)treeView.SelectedNode;
TreeNodeMission newMission = ChangeMissionDialog(mission);
treeView.SelectedNode = newMission; // doesn't work
Also tried removing and adding it, also doesn't work
index = treeView.Nodes.IndexOf(treeView.SelectedNode); // index returns -1
treeView.Nodes.Remove(treeView.SelectedNode);
treeView.Nodes.Insert(index, newMission);
What am i doing wrong?
Update:
treeView.SelectedNode is not null, its a valid node i selected.
Solved it, found the bug.
I found a way to replace the node, by removing and re-adding it.
I guess i thought asking for index will give me general index in the tree, but it gives index to the parent only, so using the parent node, i can replace it:
int index = treeView.SelectedNode.Index;
treeView.SelectedNode.Parent.Nodes.RemoveAt(index);
treeView.SelectedNode.Parent.Nodes.Insert(index, mission);
treeView.SelectedNode = mission;
Thanks
I am trying to get all the elements in a selected "Xpath location" and add them to a comboBox/ drop down list.
I tried to select all these elements by using the Xpath query : /#* with the Select method from the XpathNodeIterator.
The problem is that it return an iterator which does not move forward, in fact, it says it has no childs and its not allowing me to convert the iterator neither to an xmlElement or node so that I could at least search inside them.
This is the code :
while (anIterator.MoveNext())
{
//im trying to select all nodes of selected path which and return them to an iterator
secondIterator = anIterator.Current.Select("/#*");
while (secondIterator.MoveNext())
{
aNode = new Nodes();
aNode.Name = anIterator.Current.MoveToFirstChild().ToString();
nodeList.Add(aNode);
}
nodeList.Add(aNode);
}
Any solution to get all the elements in the current node ?
This is definitely harder to answer without the XML file you're working with, and without you telling us what you're hoping to see, and what you're currently seeing.
Here are some observations:
The '#' character in your XPath suggests you're trying to get all of the attributes of the current Node. The '/' tells Path to start at the root of the DOM.
If you're trying to get all the elements under the current node, you might want to change to "./*"
The issue is the #, which indicates that you want to select the child attributes, not child elements. (See http://www.w3.org/TR/xpath/#path-abbrev).
Try anIterator.Current.Select("*") to get the child elements. If you want all descendant elements (not just immediate children), try anIterator.Current.Select(".//*")
I have a linq to xml query which returns 2 nodes. I am attempting to iterate over these nodes and replace their content. However the content that is being added to the XDocument contains nodes which match my query criteria.
protected internal virtual void AddLinkDocument(XDocument content, TaskRequest request)
{
var links = content.Descendants("some.link").Where(tag => tag.Attribute("document-href") != null);
foreach (XElement link in links) //first time through there are 2 links found
{
//do some stuff
link.ReplaceNodes(inlineContent); // after content is added, "links" now in foreach now has many new links found
}
}
Why is the collection, "links" being updated dynamically each time through the foreach?
Thanks for the help!
Seems like there are a few factors at play here:
The way you've defined links, it's going to be re-queried for each iteration of foreach.
The re-query will search for all descendants matching the query (not just immediate children).
My guess is that the iteration block adds some new elements that match the query (ie, contain a "document-href" attribute).
So, I'd suggest trying either:
adding a ToArray() to the end of the definition for links;
or using Elements instead of Descendants to query only the child nodes of content.
I've been looking for something like that for days. I'm trying to remove all the elements from a bigger list A according to a list B.
Suppose that I got a general list with 100 elements with differents IDS and I get another list with specific elements with just 10 records. I need remove all the elements from the first list that doesn't exists inside the second list.
I'll try to show the code that I actually don't know how it didnt works.
List<Obj> listA = new List<Obj>();
List<Obj> listB = new List<Obj>();
//here I load my first list with many elements
//here I load my second list with some specific elements
listA.RemoveAll(x => !listB.Contains(x));
I don't know why but it's not working. If I try this example with a List<int> type, it works nicely but I'd like to do that with my object. This object got an ID but I don't know how to use this ID inside the LINQ sentence.
You need to compare the IDs:
listA.RemoveAll(x => !listB.Any(y => y.ID == x.ID));
List(T).RemoveAll
I believe you can use the Except Extension to do this.
var result = listA.Except(listB)
Reference: http://www.dotnetperls.com/except
If you want to remove a list of objects (listB) from another list (listA) use:
listA = listA.Except(listB).ToList()
Remember to use ToList() to convert IEnumerable<Obj> to List<Obj>.
who ever is viewing this now.I think var result = listA.Intersect(listB) will give the result for common values in the both the list.
According to the documentation on MSDN ( http://msdn.microsoft.com/en-us/library/bhkz42b3.aspx ), contains uses the default Equality comparer to determine equality, so you could use IEquatable's Equals method on your Obj class to make it work. HiperiX mentions the ref comparison above.
How to add the IEquateable interface: http://msdn.microsoft.com/en-us/library/ms131190.aspx
What is the best method to loop through TreeView nodes and retrieve a node based on certain value?
It would more efficient to create something like a Dictionary<string, TreeNode> and add all the nodes in it. This of course must be done at the start of the form or whenever you add new tree nodes. The dictionary key can be anything e.g TreeNode Text or business object associated with the node.
You won't need to traverse through all the nodes - just use the search criteria (key) and retrieve the node.