だるろぐ

明日できることは、今日しない。

オブジェクトを XML でシリアライズ

f:id:daruyanagi:20120923232820p:plain

WinRT のファイル操作はまだ慣れていないので、いちいち MSDN を徘徊しなくちゃいけないのでつらい。でも、ちょっとずつ覚えていかなければ。

たとえば、.NET の XmlSerializer を使うときは Stream が必要なんだけれど、これは .NET のクラス。WinRT とどうやってつなげればいいんだろう……

public async void Save(object o, string filename)
{
    if (o == null) throw new ArgumentException();

    try
    {
        // WinRT のファイル操作
        var folder = ApplicationData.Current.LocalFolder;
        var file = await folder.CreateFileAsync(
                filename,
                CreationCollisionOption.ReplaceExisting
            );

        // .NET の書き込み stream として開く
        using (var stream = await file.OpenStreamForWriteAsync())
        {
            // おなじみの .NET !
            new XmlSerializer(o.GetType()).Serialize(stream, o);
        }
        // *
    }
    catch
    {
        throw;
    }
}

調べてみると、 WindowsRuntimeStorageExtensions(http://msdn.microsoft.com/ja-jp/library/hh582101.aspx)のような、WinRT と .NET のファイル操作を橋渡しする拡張メソッドが結構用意されているので、それを使えばいいみたい。

ちょっと注意が必要なのは、ファイルの保存場所。標準ではアプリフォルダしか認められていないみたい。アクセス権限がないって怒られまくってちょっと凹みそうになった。

そのアプリフォルダだけど、階層が結構深くてたどるのが面倒。なので、上記のコードの // * にダイアログを表示してパスをクリップボードにコピーするコードを仕込んでおいた。

var dialog = new MessageDialog(
    Path.GetFileName(file.Path) + " is saved successfully.");
dialog.Commands.Add(new UICommand("Close"));
dialog.Commands.Add(new UICommand("Copy file's path to Clipboard",
    (_) => {
        var p = new DataPackage();
        p.SetText(file.Path);
        Clipboard.SetContent(p);
        Clipboard.Flush();
    }));
await dialog.ShowAsync();

f:id:daruyanagi:20120923233730p:plain

Process.Start() みたいなので一発でフォルダを開けたらいいんだけど、あり方がよくわからなかった。 Windows.System.Launcher はローカルフォルダ開くためには使えないのかなぁ。

アプリフォルダ、今回初めてのぞいてみたんだけど、いろいろ面白そうなファイルがあった。ふぅん、そういうことか、みたいな。