views:

449

answers:

2

Hello, I am trying to write an editor for an xml config file. I have the xml file bound to a listview and selecting an element and then clicking edit allows you to edit an element. When the user clicks save, a delegate is called which updates the element within the xml document. I have tried to do the updating in various ways including appendnode, prependnode, insertafter, and replace child. I have gotten them all working without any compile time or runtime errors, yet they don't update the xmldataprovider or the listview. It's probably just something simple that I am missing but I am having trouble figuring out what it is. Can someone please help?

Thanks, Brian

If it helps, here's the source code of my main form (the one with the listview)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;
using System.IO;

namespace g2config
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>

    public partial class MainWindow : Window
    {
        public XmlDataProvider dp;
        string cfgfile;
        public managecmpnts manage_components;
        public delegate void managecmpnts(int id, XmlElement component);


        public MainWindow()
        {
            InitializeComponent();
            dp = this.FindResource("configfile") as XmlDataProvider;

            cfgfile = "C:\\Users\\briansvgs\\Desktop\\g2config\\g2config\\bin\\Debug\\g2config.pxml";

            if(Environment.GetCommandLineArgs().Count() > 1)
            {
                string path = Environment.GetCommandLineArgs().ElementAt(1);
                //MessageBox.Show("Path: " + path);
                cfgfile = path;
            }

            if (File.Exists(cfgfile))
            {
                dp.Source = new Uri(cfgfile, UriKind.RelativeOrAbsolute);
            }
            else
            {
                MessageBox.Show("config file not found");
            }

            this.Title = this.Title + " (" + cfgfile + ") ";
        }

        public void browsedir( object sender, EventArgs e)
        {
              System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
            ofd.Filter = "PXML Files (*.pxml)|*.pxml"; ;

            //http://www.kirupa.com/net/using_open_file_dialog_pg4.htm
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) //how to browse dirs instead of files?????
            {
                 startpath.Text = ofd.FileName;
            }
        }

        public void newcomponent(object sender, RoutedEventArgs e)
        {            
            componentsettings new_cmpnt = new componentsettings();
            new_cmpnt.Title = "Add Component";
            new_cmpnt.ShowDialog();         
        }

        public void editcomponent(object sender, RoutedEventArgs e)
        {
            int selected = components.SelectedIndex;
            XmlElement current = (XmlElement)components.Items.CurrentItem;
            componentsettings edit_cmpnt = new componentsettings(current);
            edit_cmpnt.cmpnt_mgr.manage_components += new manager.mngcmpnts(test);
            edit_cmpnt.Title = "Edit Component";
            edit_cmpnt.ShowDialog();
        }

        private void browsedir(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog directory;
            directory = new System.Windows.Forms.FolderBrowserDialog();
            directory.Description = "Please select the folder containing your g2 configuration (pxml) files. Default is C:\\Program Files\\Exacom, Inc.";
            directory.ShowDialog();
            startpath.Text = directory.SelectedPath;
        }

        private void save(object sender, RoutedEventArgs e)
         {
             MessageBox.Show(dp.Source.ToString());

            if(File.Exists(cfgfile + ".old"))
            {
                File.Delete(cfgfile + ".old");
            }

             File.Move(cfgfile, cfgfile + ".old");
             dp.Document.Save(cfgfile);
         }

        private void remove(object sender, RoutedEventArgs e)
        {
            XmlNode component = dp.Document.DocumentElement["Components"].ChildNodes[components.SelectedIndex];
            dp.Document.DocumentElement["Components"].RemoveChild(component);
        }

        private void temp(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(dp.Document.DocumentElement["Components"].ChildNodes[components.SelectedIndex].InnerText.ToString()); //will this give me trouble????? Probably not since it's my config, but...
        }
        private void test(int id, XmlElement testelement)
        {

            //dp.Document.DocumentElement["Components"].ChildNodes[id] = testelement;
            //XmlNode testnode = dp.Document.DocumentElement["Components"].ChildNodes[id + 1];
            //XmlNode testnode = testelement;
            MessageBox.Show(testelement.OuterXml.ToString());
            //dp.Document.DocumentElement["Components"].InsertAfter(dp.Document.DocumentElement["Components"].ChildNodes[0], testelement);
            //dp.Document.DocumentElement["Components"].RemoveChild(testelement);
            //dp.Document.DocumentElement["Components"].ReplaceChild(testnode, dp.Document.DocumentElement["Components"].ChildNodes[id]);
            dp.Document.DocumentElement["Components"].PrependChild(testelement);

            //dp.Document.NodeChanged();

            //dp.Document.DocumentElement["Components"].CloneNode(true);
            dp.Document.DocumentElement["Components"].AppendChild(testelement);
            //dp.Document.
            //MessageBox.Show(dp.Document.OuterXml.ToString());
            //MessageBox.Show(dp.Document.DocumentElement["Components"].FirstChild.AppendChild(testelement).OuterXml.ToString());
        }


    }
}
A: 

My suggestion would be to create a class for each element by using a composite pattern, lazy loading the XML doc in the class and perform operations as you need. Then again save it. Quite a handful though.

JMSA
A: 

JMSA. Thank you for the suggestion. I was playing around with it today and I found a solution. It's a little messy, but it works. I copy one of the present nodes and then clear all of the values. Here is the code if anyone is interested.

private void add(object sender, RoutedEventArgs e) { System.Xml.XmlNode test = configfile.Document.DocumentElement["Components"].FirstChild; System.Xml.XmlNode testclone = test.Clone(); for (int i = 0; i < testclone.ChildNodes.Count; i++) { testclone.ChildNodes[i].RemoveAll(); }

        configfile.Document.DocumentElement["Components"].AppendChild(testclone);
        components.SelectedItem = components.Items.Count + 1;
    }
Brian