2012年8月27日月曜日

[C#][WPF][Siliverlight] XAML をロード


する話。

経緯についてうだうだ書いているが、面倒な人は下の方にコードを書いているので飛ばしてね。

既存アプリケーションの MVVM 化を目指しているんだけど、イベントドリブンでの開発しか知らない人たちを説得するのはなんとも骨が折れる話である。
勉強しようぜ。

いつも画面デザインはデザイナーの人にお願いして PNG ファイルもしくは PSD ファイルを提供してもらってたけど、とりあえず XAML で提供してもらえそうなところまでもっていけた。まぁ PSD を Blend でインポートすればいいだけかもしれんが。

そのまま使ってもいんだけど、現場で微調整出来るようにするには提供してもらった XAML をビルドするのではなくコンテンツそして動的にロードできるようにしなければならない。

ぽいっと読めればいんだけど、デザインさんから提供されるものは、CS ファイルがついている。つまりコードビハインドなので XAML ファイルを直接ロードすることはできない。

色々試してみたけど、どうやら x:Class タグがあるとコードビハインドだと認識されるっぽいな。こいつをスキップすればロードしてインスタンスを生成することが出来た。ちょっと強引だけど。こんな感じ。



            XamlSchemaContext xamlContext = System.Windows.Markup.XamlReader.GetWpfSchemaContext();
            XmlReader xmlReader = XmlReader.Create("test.xaml");
            XamlXmlReader xamlReader = new XamlXmlReader(xmlReader, xamlContext);
            XamlObjectWriter writer = new XamlObjectWriter(xamlReader.SchemaContext);
            while (!xamlReader.IsEof)
            {
                if (xamlReader.Member != null && (xamlReader.Member.Name == "Class")
                {
                    xamlReader.Skip();
                }
                else
                {
                    writer.WriteNode(xamlReader);
                    xamlReader.Read();
                }
            }

            UserControl control = writer.Result as UserControl;


[2012.11.08 追記]
Silverlight だとこのやり方は出来ないので、テキストファイルとして読み込んで、x:Classを正規表現で読飛ばすしかないのかな。



            using (var stream = File.OpenRead(file))
            {
                var reader = new StreamReader(stream);
                var xaml = reader.ReadToEnd();

                // 正規表現でClass属性を読み飛ばす
                Regex regex = new Regex("x:Class.*?\"\r\n");
                xaml = regex.Replace(xaml, "\r\n");

                var control = XamlReader.Load(xaml) as UserControl;
            }




x:Classから改行位置までを読飛ばしているので、その間にnamespaceとか記述しているとアウトですが。。。



0 件のコメント:

コメントを投稿