2011-12-26 23 views
0

私は.NET環境の初心者です。 私は3つのテキストボックスと1つのボタンを持つWindowsアプリケーションを持っています。ユーザーがボタンをクリックすると、すべてのテキストボックスの値をXML形式でファイルにシリアル化する必要があります。 私は、これはSystem.InvalidOperationExceptionが未処理の例外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(); 
    } 

、このようやってみましたか? ありがとう、 マイケル

+1

AddCustomerとは何ですか?それはフォームですか?なぜ、現在の実装ではなく、4つの文字列プロパティを持つクラスを作成し、それを直列化できないのですか? – Anuraj

+0

オブジェクトの現在の状態に対してメソッド呼び出しが無効な場合にスローされる例外です。 –

+0

はい、それは4つのテキストボックスを持つフォームなので、ユーザーがXMLファイルに入力する値をシリアル化する必要があります。 – Michael

答えて

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スレッド上でファイル操作を行うことを避ける必要があります(例えば、ディスクをすることができ遅くなり、ファイルを書き込んでいる間にUIがフリーズしたり、ネットワークの場所に書き込んでいて、接続している間にUIがハングする可能性があります)。進行状況ダイアログを表示し、「ファイルが保存されている間お待ちください...」というメッセージを表示し、ファイル操作をバックグラウンドで実行することが最善です。簡単な方法は、スレッドプールusing BeginInvoke/EndInvokeのバックグラウンド操作をポストすることです。


あなたの代わりにXmlSerializerを使用したい場合は、以下の手順を実行します:

  1. ドキュメントのルート要素として機能し、XmlRootでそれをマークするpublicタイプを作成します。
  2. プリミティブ/ビルトインタイプまたは独自のpublicカスタムタイプ(XMLシリアライズ可能)の要素/属性を追加し、必要に応じてXmlElementまたはXmlAttributeとマークします。
  3. データを書き出すには、適切なStream,StreamWriter、またはXmlWriterをルートオブジェクトとともに使用してください。
  4. XmlSerializer.Deseralizeを適切なStream,TextReader、またはXmlReaderと組み合わせて使用​​し、戻り値の型をルートオブジェクトにキャストし直します。

全サンプル。

シリアライズするタイプ:

[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

+0

、あなたは私がシリアル化を使用してそれを行う方法を知っていますか? – Michael

+0

@Michael:私の更新された答えを見てください。 – bobbymcr

1

代わりにコントロールをシリアル化できませんSerializable TextBox値を表すコンポーネントを作成する必要があります。 (詳細はMSDNの記事を参照してください)。例えば

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

私はちょうど........と "button1_Click(オブジェクトの送信者、EventArgs e)"私はcustomer1という顧客クラスのオブジェクトを作成し、次に割り当てられたName = textbox1.Text ; ..など.. .....同じことが起こります。 – Michael

1

あなただけのそれらの値、テキストボックスオブジェクトをシリアル化する必要がありません。 customer.textBox1は、文字列型のcustomer.text1である必要があります。次に、customer.text1 = textbox1.textを割り当てるだけです。 [Serializable]属性のAddCustomerクラスにもマークを付けます。

編集:これは私が試したコードで、うまくいきます。ソリューション内で動作させることができるかどうかを確認してください。

はこれをやった後、この

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

のようにそれをシリアル化してみCustomer

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

新しいクラスを追加し、私は以下の内容で作成した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

+0

マイケルマイケルを参照してください。 –

+0

はい、これはコンソールアプリケーションであるため、うまくいきます。しかし、私は複数のテキストボックスとボタンでWindowsアプリケーションにそれを実装する方法を知らない。 .......それは私が持っている問題です – Michael

関連する問題