Link to home
Start Free TrialLog in
Avatar of Rizzen1
Rizzen1

asked on

treeview AfterLabelEdit runs twice displaying the Message box twice

I am playing with Treeview and the AfterLabelEdit function and IM having a problem where after validation it displays the MessageBox Twice before it goes back to Editing.   If I step through the program it hits the BeginEdit() and goes back through the AfterLabelEdit a second time. Anyone see what I might be doing wrong here.

private void treeView1_AfterLabelEdit(object sender, System.Windows.Forms.NodeLabelEditEventArgs e)
    {
        var HostsXML = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Hosts.xml");

        XmlDocument doc = new XmlDocument();
        doc.Load(HostsXML);

        foreach (TreeNode pChild in e.Node.Parent.Nodes)
        {
            if (pChild.Text == e.Label)
            {
                // same name found, cancel the edit operation
                MessageBox.Show("That Name Cannot be Used.  Please Select a Different Name");
                e.CancelEdit = true;
                e.Node.BeginEdit();
                //treeView1.Nodes.Remove(treeView1.SelectedNode);
                return;
            }
        }

        if (e.Label != null)
        {
            if (e.Label.Length > 0)
            {
                if (String.IsNullOrEmpty(selectedNode))
                {
                    XmlNode rootNode = doc.SelectSingleNode("Servers");
                    XmlNode recordNode = rootNode.AppendChild(doc.CreateNode(XmlNodeType.Element, "Server", ""));
                    recordNode.AppendChild(doc.CreateNode(XmlNodeType.Element, "Name", "")).InnerText = e.Label;
                }
                else
                {
                    XmlElement root = doc.DocumentElement;
                    XmlNodeList xnList = doc.SelectNodes("/Servers/Server[Name ='" + selectedNode + "']");

                    foreach (XmlNode xn in xnList)
                    {
                        xn["Name"].InnerText = e.Label;
                    }
                }
            }
            else
            {
                MessageBox.Show("You Did Not Enter a Valid Name:1");
                e.CancelEdit = true;
                e.Node.BeginEdit();
                //treeView1.Nodes.Remove(treeView1.SelectedNode);
                return;
            }
        }
        else
        {
            e.CancelEdit = true;
            MessageBox.Show("You Did Not Enter a Valid Name: 2");
            e.Node.BeginEdit();
            //treeView1.Nodes.Remove(treeView1.SelectedNode);
            return;
        }

selectedNode = null;
    doc.Save(HostsXML);

    }

Open in new window

Avatar of Miguel Oz
Miguel Oz
Flag of Australia image

is this error for all cases? which lines fail?
Can you post the treeview declaration?

I notice that you do not use e.Node.EndEdit(false) for valid cases. In the mean time check:
http://stackoverflow.com/questions/8490621/treeview-afterlabeledit-keeps-firing
Avatar of Rizzen1
Rizzen1

ASKER

It does seem to effect all of the cases.  Nothing seems to fail but when it checks the node texts and there is something wrong, It displays the message box the first time as it should, then it hits the beginedit(), and re-fires the AfterLabelEdit again, and displays the message box a second time, before it allows me to re-edit the node.

The case I have been testing against in particular is the last else statement but they all seem to do it.

Here is the Treview

// 
            // treeView1
            // 
            this.treeView1.LabelEdit = true;
            this.treeView1.Location = new System.Drawing.Point(13, 13);
            this.treeView1.Name = "treeView1";
            treeNode2.Name = "Servers";
            treeNode2.Text = "Servers";
            this.treeView1.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
            treeNode2});
            this.treeView1.Size = new System.Drawing.Size(157, 217);
            this.treeView1.TabIndex = 0;
            this.treeView1.BeforeLabelEdit += new System.Windows.Forms.NodeLabelEditEventHandler(this.treeView1_BeforeLabelEdit);
            this.treeView1.AfterLabelEdit += new System.Windows.Forms.NodeLabelEditEventHandler(this.treeView1_AfterLabelEdit);

Open in new window

Can you post treeView1_BeforeLabelEdit implementation?
How is treeView1 nodes loaded?
Avatar of Rizzen1

ASKER

The nodes are initially loaded from an XML file.  There is a button that will add a new node, then the program will check to make sure that the node text is valid and save the new node to the XML.  Here is the whole thing.

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            LoadXML();
        }

        string selectedNode;

        public void LoadXML()
        {
            var HostsXML = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Hosts.xml");

            treeView1.Nodes.Clear();

            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(HostsXML);
             treeView1.Nodes.Clear();
            treeView1.Nodes.Add(new TreeNode(xDoc.DocumentElement.Name));
            TreeNode tNode = new TreeNode();
            tNode = (TreeNode)treeView1.Nodes[0];
            addTreeNode(xDoc.DocumentElement, tNode);
            treeView1.ExpandAll();    

        }

        private void addTreeNode(XmlNode xmlNode, TreeNode treeNode)
        {
            var HostsXML = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Hosts.xml");

            XmlDocument doc = new XmlDocument();
            doc.Load(HostsXML);

            foreach (XmlNode node in doc.DocumentElement.SelectNodes("//Name"))
            {
                TreeNode ChildNode = new TreeNode(node.InnerText);
                treeView1.Nodes[0].Nodes.Add(ChildNode);
               
            }
           
        }

        private void button1_Click(object sender, EventArgs e)
        {
            
            int myNodeCount = treeView1.Nodes[0].GetNodeCount(true);
                       
            TreeNode ChildNode = new TreeNode("NewServer "+ (myNodeCount + 1));
            treeView1.Nodes[0].Nodes.Add(ChildNode);
           
            treeView1.SelectedNode = ChildNode;
            treeView1.Focus();
            ChildNode.BeginEdit();

           
        }

        private void treeView1_BeforeLabelEdit(object sender, System.Windows.Forms.NodeLabelEditEventArgs e)
        {
            string HostsXML = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Hosts.xml");
            XmlDocument doc = new XmlDocument();
            doc.Load(HostsXML);

            XmlElement root = doc.DocumentElement;
            XmlNodeList xnList = doc.SelectNodes("/Servers/Server[Name ='" + treeView1.SelectedNode.Text + "']");
            
            
            foreach (XmlNode xn in xnList)
            {
                selectedNode = xn["Name"].InnerText;
             }

         }

private void treeView1_AfterLabelEdit(object sender, System.Windows.Forms.NodeLabelEditEventArgs e)
    {
        var HostsXML = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Hosts.xml");

        XmlDocument doc = new XmlDocument();
        doc.Load(HostsXML);

        foreach (TreeNode pChild in e.Node.Parent.Nodes)
        {
            if (pChild.Text == e.Label)
            {
                // same name found, cancel the edit operation
                MessageBox.Show("That Name Cannot be Used.  Please Select a Different Name");
                e.CancelEdit = true;
                e.Node.BeginEdit();
                //treeView1.Nodes.Remove(treeView1.SelectedNode);
                return;
            }
        }

        if (e.Label != null)
        {
            if (e.Label.Length > 0)
            {
                if (String.IsNullOrEmpty(selectedNode))
                {
                    XmlNode rootNode = doc.SelectSingleNode("Servers");
                    XmlNode recordNode = rootNode.AppendChild(doc.CreateNode(XmlNodeType.Element, "Server", ""));
                    recordNode.AppendChild(doc.CreateNode(XmlNodeType.Element, "Name", "")).InnerText = e.Label;
                }
                else
                {
                    XmlElement root = doc.DocumentElement;
                    XmlNodeList xnList = doc.SelectNodes("/Servers/Server[Name ='" + selectedNode + "']");

                    foreach (XmlNode xn in xnList)
                    {
                        xn["Name"].InnerText = e.Label;
                    }
                }
            }
            else
            {
                MessageBox.Show("You Did Not Enter a Valid Name:1");
                e.CancelEdit = true;
                e.Node.BeginEdit();
                //treeView1.Nodes.Remove(treeView1.SelectedNode);
                return;
            }
        }
        else
        {
            e.CancelEdit = true;
            MessageBox.Show("You Did Not Enter a Valid Name: 2");
            e.Node.BeginEdit();
            //treeView1.Nodes.Remove(treeView1.SelectedNode);
            return;
        }

selectedNode = null;
    doc.Save(HostsXML);

    }

Open in new window

Avatar of Rizzen1

ASKER

Any ideas as to why this is happening?
Could you post a sample xml file as well?
Thanks,
Avatar of Rizzen1

ASKER

sure, its copied here and i have attached the actual file.

<?xml version="1.0" encoding="utf-8"?>
<Servers>
  <Server>
    <Name>Test1</Name>
  </Server>
  <Server>
    <Name>Test2</Name>
  </Server>
</Servers>

Open in new window

Hosts.xml
Please clarify your business rules at treeView1_AfterLabelEdit:
- Program is doing node validation (not allowed same node text or previous values)
- If node text is not valid keep editing
- If node has new valid text then is displayed and saved to xml.

Is the above correct?
Note: I do not think you can call BeginEdit in  this event, we need to use a timer to separate events. I will post some code once you confirmed the rules.
ASKER CERTIFIED SOLUTION
Avatar of Miguel Oz
Miguel Oz
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Rizzen1

ASKER

Hi Mas,

That works perfectly!  Thanks so much!  Timers are something I am not familiar with.  I'll have to study up on these some more.  I really appreciate the help.  Been looking for an answer to this for a while.