【问题标题】:add data to xml file at every mouse click每次单击鼠标时将数据添加到 xml 文件
【发布时间】:2011-07-03 12:04:07
【问题描述】:

每次鼠标事件发生时,我都必须将数据添加到 xml 文件中!这是我的代码,我会在你看过之后更好地为你解释。

 private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
    {


            if (radioButton1.Checked==true)
            {
                if (a > 3 && a < 11)
                {

                    rect.Width = 0;
                    rect.Height = 0;
                    pictureBox1.Invalidate();


                 raghu =   img.imageToByteArray(pictureBox1.Image);


                    int radius = 10; //Set the number of pixel you want to use here
                    //Calculate the numbers based on radius
                    int x0 = Math.Max(e.X - (radius / 2), 0),
                        y0 = Math.Max(e.Y - (radius / 2), 0),
                        x1 = Math.Min(e.X + (radius / 2), pictureBox1.Width),
                        y1 = Math.Min(e.Y + (radius / 2), pictureBox1.Height);
                    Bitmap bm = pictureBox1.Image as Bitmap; //Get the bitmap (assuming it is stored that way)
                    for (int ix = x0; ix < x1; ix++)
                    {
                        for (int iy = y0; iy < y1; iy++)
                        {
                            bm.SetPixel(ix, iy, Color.Black); //Change the pixel color, maybe should be relative to bitmap
                        }
                    }
                    pictureBox1.Refresh(); //Force refresh

                    //calculation part.
                    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;
                    }
                    textBox2.Text = string.Format("Latitude:{0}°{1}'{2}''\n Longitude:{3}°{4}'{5}'' \n ICAO LOC: {6} {7} \n Distance: {8:0.0} Nm", g[p] + (int)latmin / 60, (int)latmin % 60,(int) (((h[p]-w) % 60 - (int)(latmin % 60)) * 60), i[p] + (int)longmin / 60, (int)longmin % 60, (int)((longmin % 60 - (int)(longmin % 60)) * 60), textBox1.Text, Math.Abs((int)theta1), Math.Sqrt(Math.Pow((A1/u)* 60, 2) + Math.Pow((A2/v) * 60, 2))); 

现在有很多计算部分是不需要的。但是我要在 textBox2(代码的最后一行)中打印的数据很重要。所有打印的数据都应该添加到 Xml 文件中每次我在图片框上单击鼠标...

所以我尝试通过添加这种方式使用xdocument来实现..

             XDocument xdoc = XDocument.Load(string.Format("{0}.xml", textBox3.Text));
                    XElement ParentNode= xdoc.Root.Element(string.Format("{0}",radioButton1.Text));
                    XElement node= new XElement("WayPoints",new XElement("LatitudeDegrees",g[p] + (int)latmin / 60 ,
                                     new XAttribute("Minutes",(int)latmin % 60),
                                         new XAttribute("Seconds",(int)(((h[p] - w) % 60 - (int)(latmin % 60)) * 60)),
                                            new XElement("LongitudeDegrees",i[p] + (int)longmin / 60,
                                                new XAttribute("Minutes",(int)longmin % 60),
                                                  new XAttribute("seconds",(int)((longmin % 60 - (int)(longmin % 60)) * 60)),
                                                     new XElement ("IcaoLocator",textBox1.Text,
                                                         new XAttribute("angle",Math.Abs((int)theta1)),
                                                         new XElement("DistanceInNauticalMiles",Math.Sqrt(Math.Pow((A1 / u) * 60, 2) + Math.Pow((A2 / v) * 60, 2))

                )))));
                    ParentNode.Add(node);
                    xdoc.Save(string.Format("{0}.xml", textBox3.Text));

但问题是它说根元素丢失了。

实际上我在 Xdocument 中加载的文件是,我已经创建了它

  using (XmlWriter writer = XmlWriter.Create(string.Format("{0}.xml", textBox3.Text)))
            { 
            }

以前这里是这样的(因为我担心如果创建它是在 Picturebox_Mouseclick 中创建的,它会被覆盖)

 private void pictureBox1_MouseDoubleClick(object sender, MouseEventArgs e)
    {

            if (a > 1 && a <= 3)
            {
                c[f] = e.X;
                d[f] = e.Y;
                a++;
                f++;
            }
          using (XmlWriter writer = XmlWriter.Create(string.Format("{0}.xml", textBox3.Text)))
            { 
            }
    }        

如果您不懂计算,请不要打扰,它特定于我的需要我只需将数据打印到 xml 文件..请任何人帮助我..

这里有一个路点示例

<?xml version="1.0" encoding="UTF-8"?>
<WayPoints>
  <Latitude>
    <Degrees>48</Degrees>
    <Minutes>31.7363644</Minutes>
  </Latitude>
  <Longitude>
    <Degrees>11</Degrees>
    <Minutes>57.53425</Minutes>
  </Longitude>
  <IcaoLocator>
    <Type>EDML</Type>
    <Angle>288</Angle>
    <DistanceInPixels>346</DistanceInPixels>
  </IcaoLocator>
</WayPoints>

但它只包含一个航点。我需要在这个 XML 文件中添加很多航点。

【问题讨论】:

  • 您能否向我们展示一下 xml 文件的外观(不是您希望它最初的样子,而是其中的实际内容)。因为异常听起来你有几个根元素,这在 xml 中是非法的(至少据我所知)
  • 就像旁注一样,您在 UI 中执行所有业务逻辑和数据操作,这通常是一个糟糕的设计。难道你不能创建一些帮助类并将计算和 XML 操作移至这些类并保持 UI 更简单吗?
  • @Alxandr...我在问题中添加了一个示例,请检查!!
  • @David .. 你说的是正确的,但我对它完全陌生!现在应该学习了!

标签: c# .net xml mouseevent linq-to-xml


【解决方案1】:

这里的问题似乎是实际上(如例外所述)xml 没有根元素。这可以通过将 xml 的布局更改为以下内容来相当简单地解决:

<?xml version="1.0" encoding="UTF-8"?>
<WayPoints>
   <WayPoint>
      <Latitude>
        <Degrees>48</Degrees>
        <Minutes>31.7363644</Minutes>
      </Latitude>
      <Longitude>
        <Degrees>11</Degrees>
        <Minutes>57.53425</Minutes>
      </Longitude>
      <IcaoLocator>
        <Type>EDML</Type>
        <Angle>288</Angle>
        <DistanceInPixels>346</DistanceInPixels>
      </IcaoLocator>
   </WayPoint>
   <WayPoint> <!-- New waypoint here, not at the root -->
      <Latitude>
        <Degrees>48</Degrees>
        <Minutes>31.7363644</Minutes>
      </Latitude>
      <Longitude>
        <Degrees>11</Degrees>
        <Minutes>57.53425</Minutes>
      </Longitude>
      <IcaoLocator>
        <Type>EDML</Type>
        <Angle>288</Angle>
        <DistanceInPixels>346</DistanceInPixels>
      </IcaoLocator>
   </WayPoint>
</WayPoints>

那么你应该可以做到这一点:

var doc = XDocument.Load("PATH_TO_FILE.xml");
doc.Element("WayPoints").Add(new XElement("WayPoint", 
    new XElement("Latitude",
        new XElement("Degrees", 48),
        new XElement("Minutes", 31.7363644),
    ),
    new XElement("Longitude",
        new XElement("Degrees", 48),
        new XElement("Minutes", 31.7363644),
    ),
    new XElement("IcaoLocator",
        new XElement("Type", "EDML"),
        new XElement("Angle", 288),
        new XElement("DistanceInPixels", 346)
    )
);
doc.Save("PATH_TO_FILE.xml");

未测试(此计算机上没有 Visual Studio)。

【讨论】:

    【解决方案2】:

    当您使用 xml 编写器创建 xml 文件时,您没有在其中放入任何元素,因此当 XDocument 去加载它时,它找不到根元素并抛出您得到的异常。

    如果文件不存在,我建议跳过 xmlwriter 并将 XDocument 初始化为新的 XDocument:

    XDocument xdoc;
    if( File.Exist( string.Format("{0}.xml", textBox3.Text ) ) )
      xdoc = XDocument.Load( string.Format( "{0}.xml", textBox3.Text ) );
    else
      xdoc = new XDocument(...);
    

    【讨论】:

    • 如何先创建xml文件?我没明白你...如果它已经存在那么我们可以实现你所说的...但是如何使用 xdocument 创建 xml 文件
    • 您可以构造一个新的 XDocument 对象 (using one of its constructors),然后像往常一样调用 save 方法 :) 查看示例链接
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    相关资源
    最近更新 更多