0

I have a image loaded in a picture box.When i click on the image there is some data(not required here) which will be stored in an XML file.But the problem is when ever i click the mouse on image, the data is getting over written.Instead i need to add the data that is obtained after every mouse click.here is my part of the program under MouseClick event.

private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{            
    float u = l[p + 1] - l[p];
    float v = m[p + 1] - m[p];
    float w = (e.Y - m[p]) / v; //subtract from latitude
    float z = (e.X - l[p]) / u; //add to longitude.
    float latmin = h[p] - w;
    float longmin = j[p] + z;

    A1 = e.X - c[p];
    A2 = e.Y - d[p];
    B1 = c[p + 1] - c[p];
    B2 = d[p + 1] - d[p];
    A = Math.Sqrt(Math.Pow(A1, 2) + Math.Pow(A2, 2));
    B = Math.Sqrt(Math.Pow(B1, 2) + Math.Pow(B2, 2));
    dotproduct = A1 * B1 + A2 * B2;
    theta = (180 / Math.PI) * Math.Acos( dotproduct / (A * B));
    if (e.X < c[p])
    {
        theta1 = 360 - theta;
    }
    else
    {
        theta1 = theta;
    }

    MessageBox.Show(string.Format(" Latitude:{0}°{1:0.0}'\n Longitude:{2}°{3:0.0}' \n ICAO LOC: {4} {5}", g[p] + (int)latmin / 60, latmin % 60, i[p] + (int)longmin / 60, longmin % 60, textBox1.Text, Math.Abs((int)theta1)));

    using (XmlWriter writer = XmlWriter.Create(string.Format("{0}.xml", textBox2.Text)))
    {
        writer.WriteStartDocument();
        writer.WriteStartElement("WayPoints");

         writer.WriteStartElement("Latitude");
         writer.WriteElementString("Degrees",XmlConvert.ToString( g[p] + (int)latmin / 60));
         writer.WriteElementString("Minutes", XmlConvert.ToString(latmin % 60));
         writer.WriteEndElement();

        writer.WriteStartElement("Longitude");
        writer.WriteElementString("Degrees", XmlConvert.ToString(i[p] + (int)longmin / 60));
        writer.WriteElementString("Minutes", XmlConvert.ToString(longmin % 60));
        writer.WriteEndElement();

        writer.WriteStartElement("IcaoLocator");
        writer.WriteElementString("Type", textBox1.Text);
        writer.WriteElementString("Angle", XmlConvert.ToString(Math.Abs((int)theta1)));
        writer.WriteEndElement();

        writer.WriteEndElement();
        writer.WriteEndDocument();
    }
}

The file name of the XML is taken from the text in the textbox2.

Please give me some suggestion ,such that i can store data of all mouseclicks in one file.

3
  • 2
    General observation, some comments would make the code more readable in terms of a mathematical algorithm. Commented Jun 22, 2011 at 7:49
  • the math code is not so important here,as there is no problem with it.only problem is how i can store all data in one file. Commented Jun 22, 2011 at 8:01
  • Yes I know, as I said, general observation :) Commented Jun 22, 2011 at 8:03

3 Answers 3

2

use the include features of xml.

The idea is to have one "master" file that holds the document declaration, and a "child" file that holds the inner nodes. In this case, you can simply append text to the child file, and the master will remain valid.

master.xml file :

<?xml version="1.0"?>

<WayPoints xmlns:xi="http://www.w3.org/2001/XInclude">
    <xi:include href="slave.xmlpart"/>
</WayPoints>

slave.xmlpart :

<WayPoint>
    <Latitude>
      <Degrees>1</Degrees>
    </Latitude>
    <Longitude>
      <Degrees>1</Degrees>
    </Longitude>
</WayPoint>
<WayPoint>
    <Latitude>
      <Degrees>2</Degrees>
    </Latitude>
    <Longitude>
      <Degrees>2</Degrees>
    </Longitude>
<WayPoint>

This will allow you to benefits both the Xml standard, and the perf of text writing. Only, you have to use File.AppendText, instead of XmlWriter class, to be able to works with slave file. You could, if you still want to use XmlWriter, use a temp MemoryStream where you build the nodes, before appending the content of the stream to the slave file.

[Edit] here is a sample code :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            EnsureFiles();
            Console.WriteLine("Press espace to quit");
            ConsoleKeyInfo key;
            do
            {
                key = Console.ReadKey();
                Append(key);
            }
            while (key.Key != ConsoleKey.Escape);

            Console.ReadLine();
        }

        private static void Append(ConsoleKeyInfo key)
        {
            var keyEvent = new XElement("KeyEvent",
                new XElement("Key", new XAttribute("key", key.Key.ToString())), 
                new XElement("At", DateTime.Now.ToString())
                );
            File.AppendAllText("slave.xmlpart", keyEvent.ToString());
        }

        private static void EnsureFiles()
        {
            if (!File.Exists("slave.xmlpart"))
            {
                File.WriteAllText("slave.xmlpart", ""); // simply create the file
            }
            if (!File.Exists("master.xml"))
            {
                var doc = new XDocument(
                    new XElement("WayPoints",
                        new XElement("{http://www.w3.org/2001/XInclude}include",
                            new XAttribute("href", "slave.xmlpart")
                            )
                    )
                );
                doc.Save("master.xml");
            }
        }
    }
}

However, it seems that the Xdocument class does not follow includes, but this article shows a solution : http://www.catarsa.com/Blog/Kohler-Radim/2010/5/Linq-To-Xml-XInclude

Sign up to request clarification or add additional context in comments.

2 Comments

can you help me with the code in c#,which i have to add.As I am new to both C# and XML.
which version of .NEt are you using ?
1

I will use an instance of XmlDocument inside the class, and append to it the proper nodes at any mouse click. You can save the doc on disk each time ( not so efficient, but you will not notice any performance decrease if file is not huge ) or delay the save in some other cirumstance ( explicit button, or window close )

Comments

1

You could look at using XDocument which is part of the System.Xml.Linq namespace. This form of XML document gives you a much easier API to reading and amending XML Docs, utilizing common liq functionality. Here's a MSDN link which details it.

To add a node you can do the following:

XDocument xmlDocument = XDocument.Load("FilePath");
XElement parentNode = xmlDocument.Root.Element("ParentNode");
XElement node = new XElement("NodeName"); 
parentNode.Add(node);
xmlDocument.Save("FilePath");

That is a simple example and is not implementing any null checks and is assuming that the parent node only has one instance.

Hope that helps.

Paul

2 Comments

Ya this was helpful ,but if you can you give more detailed solution with respect to code i have ,it would more helpful.As i am implementing the mouseclick event, i am not sure where to implement the parent node i.e either inside or outside the event.
It's a bit difficult without seeing your schema but I would say that you probably want to separate the responsibilities of your method into different classes or methods. I would probably have an instance of a class to handle the XML document, this class would then be broken down into reusable atomic methods handling different aspects. Such as having a method to get a node, to create a node, create attributes etc. I would say the best way to start is to get your class to build up your xml a bit at a time. So start creating your root node like "Data" and add methods until you have what you need.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.