2009-12-31 82 views
0

我想为xml配置文件编写一个编辑器。我有xml文件绑定到列表视图并选择一个元素,然后单击编辑允许您编辑一个元素。当用户点击保存时,会调用一个代理来更新xml文档中的元素。我试图以各种方式进行更新,包括appendnode,prependnode,insertafter和replace child。我已经让它们在没有任何编译时或运行时错误的情况下工作,但它们不更新xmldataprovider或listview。这可能只是我失踪的一件简单的事情,但我无法弄清楚它是什么。有人可以帮忙吗?C#xmldataprovider插入节点

感谢, 布赖恩

如果有帮助,这是我的主要形式(具有列表视图)的源代码

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()); 
     } 


    } 
} 

回答

0

我的建议是创建一个类为每个元素通过使用复合模式,在类中延迟加载XML文档并根据需要执行操作。然后再保存它。相当少数,但。

1

JMSA。感谢您的建议。我今天在玩弄它,并且找到了解决方案。这有点混乱,但它有效。我复制当前节点中的一个,然后清除所有值。如果任何人有兴趣,这里是代码。

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; 
}