C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: XMLへ出力した際に表示される形式について


(過去ログ 107 を表示中)

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■63844 / inTopicNo.1)  XMLへ出力した際に表示される形式について
  
□投稿者/ howling (11回)-(2012/10/18(Thu) 18:21:47)

分類:[.NET 全般] 

いつもお世話になっております。

今回はこの問題については、自分でクラスを作って回避しようと思っているのですが、
後学のために質問させてください。

現在、VisualStudio2010/C#を使用して、
Windows7上でPropertyGridを作成しています。

ここに割り当てるオブジェクトの中に、既存のColorクラスが存在します。
この割り当てたオブジェクトをアプリの終了時にXMLへ出力し、
その後アプリの再起動時に読み込んでいます。
概ね下記のような状態です。

class SaveData
{
Color clsColor = Color.White;
public Color MyColor
{ set; get; }
}

//ロード部分(FormのLoadイベントで呼んでます)
SaveData clsSomeSaveData = new SaveData();
PropertyGrid clsPG = new PropertyGrid();

System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(SaveData));
System.IO.FileStream fileStream = new System.IO.FileStream(strSaveFileName, System.IO.FileMode.Open);
clsSomeSaveData = (SaveData)serializer.Deserialize(fileStream);
fileStream.Close();

PropertyGrid.SelectedObject = clsSomeSaveData;


//セーブ部分(FormのCloseイベントで呼んでます)
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(SaveData));
System.IO.FileStream fileStream = new System.IO.FileStream(strSaveFileName, System.IO.FileMode.Create);
serializer.Serialize(fileStream, clsSomeSaveData);
fileStream.Close();

さて、ここでロードしたカラーの中身はRGBが全て0のデータとなってしまいます。
これは、なぜかXML上で<MyColor><Data /></MyColor>とだけ出力されてしまうためです。
「XMLにシリアライズした際にどのように表現されるのか」はどのように変更しているのでしょうか?
どなたかご存知ありませんか?

てっきり、
<MyColor>
<R>255</R>
<G>255</G>
<B>255</B>
</MyColor>
と出力されているものとばかり予想しておりましたので、意外でした。

また、他のクラスでこのようなクラスがもしあるのであれば、
いくつか例を挙げて頂けますと非常に助かります。

以上
宜しくお願い致します。

引用返信 編集キー/
■63845 / inTopicNo.2)  Re[1]: XMLへ出力した際に表示される形式について
□投稿者/ Hongliang (3回)-(2012/10/18(Thu) 20:04:22)
XmlSerializerでシリアライズできるメンバは、IXmlSerializableを実装していない限り、setとget両方のpublicなアクセサを持ったプロパティ(とpublicフィールド)のみです。
Color構造体はプロパティ全てgetのみですので、XmlSerializerによるシリアライズはまともに効きません。

・Color構造体をプロパティに持つクラスにIXmlSerializableを実装させ、Colorのシリアライズ・デシリアライズ処理を自分で書く
・ColorはXmlIgnore属性をつけてシリアライズ対象外とし、もう一つColorをシリアライズできるようなプロパティを用意する(例えばColorConverterを使って文字列・Colorの変換をget/set内で行うString型プロパティとか)

などの工夫が必要です。
なお、Color構造体はRGBだけでなくアルファ値も持っていますし、Color.FromKnownColorなどで作られた場合はその値も保持しています。
引用返信 編集キー/
■63854 / inTopicNo.3)  Re[2]: XMLへ出力した際に表示される形式について
□投稿者/ howling (12回)-(2012/10/19(Fri) 11:11:12)
2012/10/19(Fri) 11:11:33 編集(投稿者)
Hongliang様

ご返信頂きありがとうございます。
なるほど、確かにシリアライズでget、デシリアライズでsetするはずですよね。
それできっとset/getが無いといけないんですね。

なんとなく、丸々インスタンスを放り込むイメージでいたので、
プロパティが必要という認識に至っておりませんでした。
方針自体は後者に近い形でいきたいと思います。

実際には今のところ、Colorの値をメンバに持ち、
プロパティでColor自体の値と、Red,Green,Blueの値のset/getプロパティを用意し、
set/getプロパティ内でColorを再割り当てなどしています。

当該コードは下記の通りです。
実際にこれをそのまま使用していますので、そのままコピペでも使えます。
(後でこの質問を見た方へ)

public class LooksLikeColor
    {
        private Color clsDrawColor = Color.White;

        public LooksLikeColor() { }

        [RefreshProperties(RefreshProperties.Repaint)]
        public Color DrawColor
        {
            get { return clsDrawColor; }
            set
            {
                clsDrawColor = value;
            }
        }

        [RefreshProperties(RefreshProperties.Repaint)]
        public int R
        {
            get { return clsDrawColor.R; }
            set
            {
                if (clsDrawColor.R != value)
                {
                    clsDrawColor = Color.FromArgb(value, clsDrawColor.G, clsDrawColor.B);
                }
            }
        }

        [RefreshProperties(RefreshProperties.Repaint)]
        public int G
        {
            get { return clsDrawColor.G; }
            set
            {
                if (clsDrawColor.G != value)
                {
                    clsDrawColor = Color.FromArgb(clsDrawColor.R, value, clsDrawColor.B);
                }
                
            }
        }

        [RefreshProperties(RefreshProperties.Repaint)]
        public byte B
        {
            get { return clsDrawColor.B; }
            set
            {
                if (clsDrawColor.B != value)
                {
                    clsDrawColor = Color.FromArgb(clsDrawColor.R, clsDrawColor.G, value);
                }
                
            }
        }

    }

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -