I have the the following code sample
private TreeNode AddNode(TreeNode node, string key)
{
var child = node.ChildNodes.Cast<TreeNode>().FirstOrDefault(_ => _.Value == key);
if (child != null)
return child;
child = new TreeNode(key, key);
child.SelectAction = TreeNodeSelectAction.SelectExpand;
child.Selected = true;
node.ChildNodes.Add(child);
return child;
}
I'm not able to select the node. When I invoke treeview_SelectedNodeChanged, I'm getting NULL..
string v = ((TreeView)sender).SelectedNode.Value;
Use treeview.SelectedNode and check the code in page_load handler,
if(!IsPostBack)
{
//code to add nodes
}
Related
How to make parent node can not selected in treeview ?
If the node is "Parent" , it can not support select,
so I add code
if (drv["isParent"].ToBool())
{
node.Selected = false;
}
But not work? how to fix ?
TreeNode node;
var rows = dv.AsEnumerable().Where(r => r["ParentID"].ToString() == parentid);
foreach (DataRow drv in rows.AsEnumerable())
{
// DataRowView一行
node = new TreeNode();
node.Value = drv["NodeID"].ToString();
node.Text = drv["Name"].ToString();
if (drv["isParent"].ToBool())
{
node.Selected = false;
}
tnc.Add(node);
if (drv["ObjectCode"].ToString() != "0")
{
InitTree(node.ChildNodes, node.Value);
}
}
if (drv["isParent"].ToBool())
{
node.SelectAction = TreeNodeSelectAction.None;
}
I get data from tow database, db1,db2, then Now I want to create treeView for the data in the resulting datagridview; in datagrid view there are: id, name, director,the first record is the prim director, that mean he has not up director(he is owner), each record has no other record or has more records(child), and each child has grandchild and so on, this scenario Just Like in the this page:
I want to create treeview (parent and child and grandchild and so on), depending on xml file
when i used this snippet after some :
void setTree()
{
{
foreach(DataGridViewRow dt in DataGridView1.Rows)
{
var per = this.DataGridView1.Rows.Cast<DataGridViewRow>().Select(n => new person
{
name = dt.Cells[0].Value.ToString(),
Sex = dt.Cells[1].Value.ToString(),
Status = dt.Cells[2].Value.ToString(),
child = dt.Cells[3].Value.ToString(),
id = dt.Cells[4].Value.ToString(),
father = dt.Cells[5].Value.ToString()
}).ToList();
var rootTreeNode = GetTree(per, "").First();.........(1)
treeView1.Nodes.Add(rootTreeNode);
}
}
}
private TreeNode[] GetTree(List<person> per, string parent)
{
return per.Where(p => p.father == parent).Select(p =>
{
var node = new TreeNode(p.name);
node.Tag = p.id;
node.Nodes.AddRange(GetTree(per, p.id));
return node;
}).ToArray();
}
Now, when I use this code, I get error at mark(1),it say:Additional information: Sequence contains no elements.
thank you
after several readings in internet and attempts to solve this small problem, I successed finally.
this is the solution:
{
.............
TreeNode tn = new TreeNode(this.DataGridView2.Rows[0].Cells[0].Value.ToString());//text
tn.Tag = this.DataGridView2.Rows[0].Cells[4].Value.ToString();// id
tn.Name = this.DataGridView2.Rows[0].Cells[5].Value.ToString();//directorid
treeView1.Nodes.Add(tn);
settree(tn);
}
public void settree(TreeNode ns)
{
foreach (DataGridViewRow dr in DataGridView2.Rows)
{
if (dr.Cells[5].Value.ToString() == ns.Tag.ToString())
{
TreeNode tsn = new TreeNode(dr.Cells[0].Value.ToString());
tsn.Tag = dr.Cells[4].Value.ToString();
tsn.Name = dr.Cells[5].Value.ToString();
ns.Nodes.Add(tsn);
settree(tsn);
}
}
}
i will be happy if you benefit from this code.
There's my code:
private void removeToolStripMenuItem_Click(object sender, EventArgs e)
{
if (treeView1.SelectedNode != null)
{
if (treeView1.SelectedNode.Parent == null) treeView1.SelectedNode.Remove();
else if (treeView1.SelectedNode.Parent.Nodes.Count == 1) treeView1.SelectedNode.Parent.Remove();
else treeView1.SelectedNode.Remove();
}
XDocument doc = XDocument.Load("test.xml");
if (treeView1.SelectedNode.Parent != null)
{
var xElement = (from q in doc.Elements("dogs").Elements("dog")
where q.Attribute("id").Value == treeView1.SelectedNode.Tag.ToString()
select q);
foreach (var a in xElement)
a.Remove();
doc.Save("test.xml");
}
I want to search through my file for id value and if program will find it, it compares it to tag of selected node, and if it finds it, it'll delete this node. And everytime I'm trying to delete any node, error NullReferenceException was unhandled appears.
When you call:
treeView1.SelectedNode.Remove();
This will either set your treeView1.SelectedNode to null or set the SelectedNode to the removed node's parent or to the next available node.
Also this code will set the parent, of the node you removed, to null. These two cases are likely the root cause of your exception. I would suggest simply setting a temporary variable to point to the node you want removed:
TreeNode node = treeView1.SelectedNode;
treeView1.SelectedNode.Remove();
Then simply change your code to:
TreeNode node = treeView1.SelectedNode;
if (treeView1.SelectedNode != null)
{
if (treeView1.SelectedNode.Parent == null)
treeView1.SelectedNode.Remove();
else if (treeView1.SelectedNode.Parent.Nodes.Count == 1)
treeView1.SelectedNode.Parent.Remove();
else
treeView1.SelectedNode.Remove();
}
XDocument doc = XDocument.Load("test.xml");
var xElement = (from q in doc.Elements("dogs").Elements("dog")
where q.Attribute("id").Value == node.Tag.ToString()
select q);
foreach (var a in xElement)
a.Remove();
doc.Save("test.xml");
If the logic within this method is run from an event handler such as Button_Click it works perfectly, but, when running this from a method such as below I get the error:
hostView.SelectedNode.Nodes.Add(newNode);
Object reference not set to an instance of an object.
Here is my code:
private void SetupHostTree()
{
// Set internal host names
using (var reader = File.OpenText("Configuration.ini"))
{
List<string> hostnames = ParseInternalHosts(reader).ToList();
foreach (string s in hostnames)
{
TreeNode newNode = new TreeNode(s);
hostView.SelectedNode.Nodes.Add(newNode);
string title = s;
TabPage myTabPage = new TabPage(title);
myTabPage.Name = s;
tabControl1.TabPages.Add(myTabPage);
}
}
}
Maybe there are no Selected Nodes :)
Probably because no node is currently selected in the hostView TreeView.
The documentation says that the TreeView.SelectedNode property will return null when no node is currently selected. And since you've combined it into an expression, the entire expression is failing because there is no Nodes collection on a null object!
Try this code:
private void SetupHostTree()
{
// Set internal host names
using (var reader = File.OpenText("Configuration.ini"))
{
List<string> hostnames = ParseInternalHosts(reader).ToList();
foreach (string s in hostnames)
{
// Ensure that a node is currently selected
TreeNode selectedNode = hostView.SelectedNode;
if (selectedNode != null)
{
TreeNode newNode = new TreeNode(s);
selectedNode.Nodes.Add(newNode);
}
else
{
// maybe do nothing, or maybe add the new node to the root
}
string title = s;
TabPage myTabPage = new TabPage(title);
myTabPage.Name = s;
tabControl1.TabPages.Add(myTabPage);
}
}
}
I have a String List with items like this
"Root"
"Root/Item1"
"Root/Item2"
"Root/Item3/SubItem1"
"Root/Item3/SubItem2"
"Root/Item4/SubItem1"
"AnotherRoot"
How do I transfer this stringlist into a treeview ?
You can split each item into it's substrings. Then via recursion look for each item, if the parent exists add to it, and if the parent doesn't exists create it.
If you can't see how to do it, i`ll post you a sample code
Sample Code
public void AddItem(TreeView treeControl, TreeNode parent, string item)
{
TreeNodeCollection nodesRef = (parent != null) ? parent.Nodes : treeControl.Nodes;
string currentNodeName;
if (-1 == item.IndexOf('/')) currentNodeName = item;
else currentNodeName = item.Substring(0, item.IndexOf('/'));
if (nodesRef.ContainsKey(currentNodeName))
{
AddItem(treeControl, nodesRef[currentNodeName], item.Substring(currentNodeName.Length+1));
}
else
{
TreeNode newItem = nodesRef.Add(currentNodeName, currentNodeName);
if (item.Length > currentNodeName.Length)
{
AddItem(treeControl, newItem, item.Substring(item.IndexOf('/', currentNodeName.Length) + 1));
}
}
}
And the caller example:
string[] stringArr = {
"Root",
"Root/Item1",
"Root/Item2",
"Root/Item3/SubItem1",
"Root/Item3/SubItem2",
"Root/Item4/SubItem1",
"AnotherRoot"
};
foreach (string item in stringArr)
{
AddItem(treeView1, null, item);
}
One way is to iterate the items split the item and push them on a list and if the parent doesn't match pop an item from the list until the stack is empty or you have a match.
You can use this code:
private void button1_Click(object sender, EventArgs e) {
List<String> paths = new List<String> {
"Root", "Root/Item1", "Root/Item2", "Root/Item3/SubItem1",
"Root/Item3/SubItem2", "Root/Item4/SubItem1", "AnotherRoot"
};
List<TreeNode> nodeCollection = new List<TreeNode>();
foreach (var path in paths) {
AddPath(nodeCollection, path);
}
treeView1.Nodes.Clear();
treeView1.Nodes.AddRange(nodeCollection.ToArray());
}
public void AddPath(List<TreeNode> collection, String path) {
LinkedList<String> pathToBeAdded = new LinkedList<String>(path.Split(new String[] { #"/" }, StringSplitOptions.RemoveEmptyEntries));
if (pathToBeAdded.Count == 0) {
return;
}
String rootPath = pathToBeAdded.First.Value;
TreeNode root = collection.FirstOrDefault(n => n.Text.Equals(rootPath));
if (root == null) {
root = new TreeNode(rootPath);
collection.Add(root);
}
pathToBeAdded.RemoveFirst();
AddPath(root, pathToBeAdded);
}
public void AddPath(TreeNode rootNode, LinkedList<String> pathToBeAdded) {
if (pathToBeAdded.Count == 0) {
return;
}
String part = pathToBeAdded.First.Value;
TreeNode subNode = null;
if (!rootNode.Nodes.ContainsKey(part)) {
subNode = rootNode.Nodes.Add(part, part);
} else {
subNode = rootNode.Nodes[part];
}
pathToBeAdded.RemoveFirst();
AddPath(subNode, pathToBeAdded);
}
Hope this helps.
Ricardo Lacerda Castelo Branco