2011-12-26 56 views
0

我是.NET环境的初学者。 我有一个Windows应用程序与三个文本框和一个按钮。当用户点击按钮时,我想要将所有文本框值以XML格式序列化为文件。 我试图做这种方式,在C#中序列化文本框.net

DialogResult dr = new DialogResult(); 
    private void button1_Click(object sender, EventArgs e) 
    { 
     AddCustomer customer = new AddCustomer(); 
     customer.textBox1.Text = textBox1.Text; 
     customer.textBox2.Text = textBox2.Text; 
     customer.textBox3.Text = textBox3.Text; 
     customer.textBox4.Text = textBox4.Text; 

      saveFileDialog1.InitialDirectory = @"D:"; 
      saveFileDialog1.Filter = "Xml Files | *.xml"; 
      if (saveFileDialog1.ShowDialog().Equals(DialogResult.OK)) 
      { 

       SerializeToXML(customer); 
      }    
    } 

    public void SerializeToXML(AddCustomer customer) 
    { 

      XmlSerializer serializer = new XmlSerializer(typeof(AddCustomer)); 
      TextWriter textWriter = new StreamWriter(@"D:\customer.xml"); 
      serializer.Serialize(textWriter, customer); 
      textWriter.Close(); 
    } 

这回System.InvalidOperationException了未处理的异常

什么想法? 谢谢, 迈克尔

+1

什么是AddCustomer?它是一种形式吗?为什么不能创建一个具有四个字符串属性的类,然后对其进行序列化,而不是当前的实现。 – Anuraj 2011-12-26 03:05:04

+0

当方法调用对于对象的当前状态无效时引发的异常。 – 2011-12-26 03:16:45

+0

是的,它是一个包含4个文本框的表单,我需要将用户放入其中的值序列化为一个xml文件。 – Michael 2011-12-26 06:39:53

回答

0

有很多方法可以在.NET中编写XML。下面是使用XmlWriter,对于非常简单的内容,例如在这种情况下,工作的方式:

string text1 = /* get value of textbox */; 
string text2 = /* get value of textbox */; 
string text3 = /* get value of textbox */; 

// Set indent=true so resulting file is more 'human-readable' 
XmlWriterSettings settings = new XmlWriterSettings() { Indent = true }; 

// Put writer in using scope; after end of scope, file is automatically saved. 
using (XmlWriter writer = XmlTextWriter.Create("file.xml", settings)) 
{ 
    writer.WriteStartDocument(); 
    writer.WriteStartElement("root"); 
    writer.WriteElementString("text1", text1); 
    writer.WriteElementString("text2", text2); 
    writer.WriteElementString("text3", text3); 
    writer.WriteEndElement(); 
} 

一个注意:你应该避免在UI线程上执行的文件操作,因为这可能会导致阻塞行为(例如磁盘可以是速度慢并导致用户界面在写入文件时冻结,或者它可能正在写入网络位置并在连接时挂起一段时间)。最好放置一个进度对话框并显示一条消息“Please wait while file is saved ...”并在后台执行文件操作;一个简单的方法是发布后台操作的线程池using BeginInvoke/EndInvoke


如果你想使用XmlSerializer来代替,那么你就请按照下列步骤操作:

  1. 创建public类型作为文档的根元素,并与XmlRoot对它进行标记。
  2. 添加由原始/内置类型或您自己的public自定义类型构成的元素/属性,这些自定义类型也是XML可序列化的,并根据需要用XmlElementXmlAttribute标记它们。
  3. 要写出数据,请使用XmlSerializer.Serialize以及适当的Stream,StreamWriterXmlWriter以及您的根对象。
  4. 要重新读取数据,请使用XmlSerializer.Deseralize和适当的Stream,TextReaderXmlReader,将返回类型转换回您的根对象。

Full sample。

类型连载:

[XmlRoot("customer")] 
public class CustomerData 
{ 
    // Must have a parameterless public constructor 
    public CustomerData() 
    { 
    } 

    [XmlElement("name")] 
    public string Name { get; set; } 

    [XmlElement("city")] 
    public string City { get; set; } 

    [XmlElement("company")] 
    public string Company { get; set; } 

    public override string ToString() 
    { 
     return 
      "Name=[" + this.Name + "] " + 
      "City=[" + this.City + "] " + 
      "Company=[" + this.Company + "]"; 
    } 
} 

代码读/写数据:

// Initialize the serializer to write and read the data 
XmlSerializer serializer = new XmlSerializer(typeof(CustomerData)); 

// Initialize the data to serialize 
CustomerData dataToWrite = new CustomerData() 
{ 
    Name = "Joel Spolsky", 
    City = "New York", 
    Company = "Fog Creek Software" 
}; 

// Write it out 
XmlWriterSettings settings = new XmlWriterSettings() { Indent = true }; 
using (XmlWriter writer = XmlTextWriter.Create("customer.xml", settings)) 
{ 
    serializer.Serialize(writer, dataToWrite); 
} 

// Read it back in 
CustomerData dataFromFile = null; 
using (XmlReader reader = XmlTextReader.Create("customer.xml")) 
{ 
    dataFromFile = (CustomerData)serializer.Deserialize(reader); 
} 

Console.WriteLine(dataFromFile); 
+0

非常感谢,它帮助了很多! – Michael 2011-12-26 06:11:52

+0

出于好奇,你会知道我可以如何使用序列化? – Michael 2011-12-26 16:16:47

+0

@Michael:看到我更新的答案。 – bobbymcr 2011-12-26 20:15:34

1

你不能序列化控件,而不是你必须创建Serializable组件代表文本框值。 (更多详情请阅读MSDN文章)。

例如,

[Serializable] 
public class Customer 
{ 
    public string Name { get; set; } 
    public string Address {get;set;} 
} 
+0

我刚刚尝试过一个........和“button1_Click(object sender,EventArgs e)”我创建了一个名为customer1的客户类的对象,然后分配了Name = textbox1.Text ; ..等等......仍然会发生同样的事情。 – Michael 2011-12-26 06:54:20

1

你不应该序列化框对象,只是它们的值。 customer.textBox1应该是字符串类型的customer.text1。然后您需要分配customer.text1 = textbox1.text。 此外,请使用[Serializable]属性标记您的AddCustomer类。

编辑:这是我刚刚试过的代码,它工作正常。看看你是否可以在你的解决方案中工作。

添加新的类Customer

[Serializable] 
public class Customer 
{ 
    public string FullName { get; set; } 
    public string Age { get; set; } 
} 

尝试序列像这样

Customer customer = new Customer(); 
customer.FullName = "John"; // or customer.FullName = textBox1.Text 
customer.Age = "21"; // or customer.Age = textBox2.Text 

XmlSerializer serializer = new XmlSerializer(typeof(Customer)); 
TextWriter textWriter = new StreamWriter(@"D:\customer.xml"); 
serializer.Serialize(textWriter, customer); 
textWriter.Close(); 

这样做后,我得到了下面的内容创建一个XML文件。

<?xml version="1.0" encoding="utf-8"?> 
<Customer xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <FullName>John</FullName> 
    <Age>21</Age> 
</Customer> 

尝试并比较,看看你做错了什么。

+0

按照你的建议,我试过去做, – Michael 2011-12-26 06:35:33

+0

看我的编辑迈克尔。 – 2011-12-26 11:40:28

+0

是的,这个工作正常,因为它是一个控制台应用程序。但我不知道如何使用多个文本框和一个按钮来实现它到Windows应用程序。 .......这就是我遇到的问题 – Michael 2011-12-26 16:15:54