silverlight类库中没有提供,在网上找了找,貌似资料很少。现把我找到的一个并做了小量的修改,现拿出来分享一下:
总共分为两个类:XamlHelper和XamlWriter。
XamlHelper.cs
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Reflection; using System.Text.RegularExpressions; namespace SARuntimeXAMLWriter { internal class XamlHelper { internal static bool hasCollections(DependencyObject obj) { PropertyInfo[] props = obj.GetType().GetProperties(); foreach (var prop in props) if (prop.Name != "Parent" && (prop.PropertyType.BaseType.Name == "Collection`1" || prop.PropertyType.Name == "Transform")) return true; return false; } internal static bool hasDeepCollections(DependencyObject obj, PropertyInfo prop) { if (obj == null || prop.PropertyType.IsArray) return false; return ((prop.GetValue(obj, null) ?? new object()).ToString().StartsWith("System.")); } internal static string getSilverlightCompatibleXaml(string xaml) { Regex reg = new Regex(@"(\<(/)?\w+\.Children\>)", RegexOptions.None); return reg.Replace(xaml, "").Replace("xName", "x:Name"); } } }
XamlWriter.cs
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Reflection; using System.Text; using System.Xml; namespace SARuntimeXAMLWriter { public class XamlWriter { public static string Write(DependencyObject parent) { StringBuilder sb = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings(); settings.OmitXmlDeclaration = true; settings.Indent = true; XmlWriter writer = XmlWriter.Create(sb, settings); //if (!TypeValidator.isValid(parent)) // throw new TypeValidationException(); writer.WriteStartElement(parent.GetType().Name); writeCLRProperties(parent, writer); writeDPs(parent, writer); writeBrushes(parent, writer); writeCollections(parent, writer); writer.WriteEndElement(); writer.Flush(); writer.Close(); return XamlHelper.getSilverlightCompatibleXaml(sb.ToString()); } private static void writeCLRProperties(DependencyObject target, XmlWriter writer) { PropertyInfo[] props = target.GetType().GetProperties(); bool hdc = false; foreach (var prop in props) { hdc = XamlHelper.hasDeepCollections(target, prop); if (prop.Name == "Name") { if (prop.GetValue(target, null).ToString() != "") writer.WriteAttributeString("x" + prop.Name, prop.GetValue(target, null).ToString()); } else if (prop.Name != "Parent" && prop.CanRead && prop.CanWrite && prop.GetValue(target, null) != null && prop.PropertyType.BaseType.Name != "Collection`1" && prop.PropertyType.Name != "Brush" && !hdc) { var propValue = prop.GetValue(target, null).ToString(); if (!propValue.Equals("Infinity") && !propValue.Equals("NaN")) writer.WriteAttributeString(prop.Name, prop.GetValue(target, null).ToString()); } } } private static void writeDPs(DependencyObject target, XmlWriter writer) { //DPs problem try { writer.WriteAttributeString("Canvas.Left", target.GetValue(Canvas.LeftProperty).ToString()); writer.WriteAttributeString("Canvas.Top", target.GetValue(Canvas.TopProperty).ToString()); writer.WriteAttributeString("Canvas.ZIndex", target.GetValue(Canvas.ZIndexProperty).ToString()); } catch { } try { writer.WriteAttributeString("Storyboard.TargetName", target.GetValue(Storyboard.TargetNameProperty).ToString()); writer.WriteAttributeString("Storyboard.TargetProperty", target.GetValue(Storyboard.TargetPropertyProperty).ToString()); } catch { } } private static void writeBrushes(DependencyObject target, XmlWriter writer) { PropertyInfo[] props = target.GetType().GetProperties(); object val; foreach (var prop in props) if (prop.PropertyType.Name == "Brush" && (val = prop.GetValue(target, null) ?? new object()).ToString() != "") { if (val.ToString() == "System.Object") continue; writer.WriteStartElement(prop.ReflectedType.Name + "." + prop.Name); writer.WriteStartElement(val.ToString().Split('.')[3]); writeCLRProperties((DependencyObject)val, writer); writeDeepCollections((DependencyObject)val, writer); writeCollections((DependencyObject)val, writer); writer.WriteEndElement(); writer.WriteEndElement(); } } private static void writeCollections(DependencyObject target, XmlWriter writer) { if (target == null) return; PropertyInfo[] props = target.GetType().GetProperties(); int cnt; object val; string collectionElement = ""; foreach (var prop in props) if (prop.Name != "Parent" && prop.PropertyType.BaseType != null && prop.PropertyType.BaseType.Name == "Collection`1") { cnt = (int)prop.PropertyType.InvokeMember("get_Count", BindingFlags.InvokeMethod, null, prop.GetValue(target, null), null); for (int i = 0; i < cnt; i++) { val = prop.PropertyType.InvokeMember("get_Item", BindingFlags.InvokeMethod, null, prop.GetValue(target, null), new object[] { i }); if (XamlHelper.hasCollections((DependencyObject)val)) { if (collectionElement != prop.ReflectedType.Name + "." + prop.Name) { if (collectionElement != "") writer.WriteEndElement(); collectionElement = prop.ReflectedType.Name + "." + prop.Name; writer.WriteStartElement(collectionElement); } writer.WriteStartElement(val.GetType().Name); writeCLRProperties((DependencyObject)val, writer); writeDPs((DependencyObject)val, writer); writeBrushes((DependencyObject)val, writer); writeCollections((DependencyObject)val, writer); writer.WriteEndElement(); } else { writer.WriteStartElement(val.GetType().Name); writeCLRProperties((DependencyObject)val, writer); writeDPs((DependencyObject)val, writer); writeBrushes((DependencyObject)val, writer); writeDeepCollections((DependencyObject)val, writer); writer.WriteEndElement(); } } if (collectionElement != "") { writer.WriteEndElement(); collectionElement = ""; } } //TransformGroup not inherits from Collection, so it can not be added //through writeCollections/writeDeepCollections and we should handle //it separately else if (prop.PropertyType.Name == "Transform") { val = prop.GetValue(target, null); if (val == null) continue; if (val.GetType().ToString() != "System.Windows.Media.TransformGroup" || ((int)val.GetType().GetProperty("Children").GetValue(val, null).GetType().GetProperty("Count").GetValue(val.GetType().GetProperty("Children").GetValue(val, null), null)) == 0) continue; writer.WriteStartElement(prop.ReflectedType.Name + "." + prop.Name); writer.WriteStartElement(val.GetType().Name); writeCollections(val as DependencyObject, writer); writer.WriteEndElement(); writer.WriteEndElement(); } } private static void writeDeepCollections(DependencyObject target, XmlWriter writer) { PropertyInfo[] props = target.GetType().GetProperties(); object val; foreach (var prop in props) if (prop.PropertyType.BaseType.Name != "Collection`1" && prop.PropertyType.Name != "Transform" && XamlHelper.hasDeepCollections(target, prop)) { val = prop.GetValue(target, null); if (val != null & val.GetType().Equals(typeof(DependencyObject))) { writer.WriteStartElement(prop.Name); writeCollections((DependencyObject)val, writer); writer.WriteEndElement(); } } } } }
示例:
前台代码:
<Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition Height="200"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <Canvas Height="100" Width="200" x:Name="myCanvas" Background="Beige"> <TextBlock Text="Amyo Kabir"></TextBlock> </Canvas> <TextBox Grid.Row="1" x:Name="textBoxOutput"></TextBox> </Grid>
后台代码:
var root = XamlWriter.Write(myCanvas).Replace("x:", ""); var elm = XElement.Parse(root); foreach (var child in myCanvas.Children) { elm.Add(XElement.Parse(XamlWriter.Write(child).Replace("x:", ""))); } textBoxOutput.Text = elm.ToString();
textBoxOutput的内容为:
<Canvas Width="200" Height="100" MinWidth="0" MinHeight="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,0" FlowDirection="LeftToRight" Name="myCanvas" AllowDrop="False" Opacity="1" RenderTransformOrigin="0,0" IsHitTestVisible="True" Visibility="Visible" UseLayoutRounding="True" Canvas.Left="0" Canvas.Top="0" Canvas.ZIndex="0"> <Canvas.Background> <SolidColorBrush Color="#FFF5F5DC" Opacity="1" /> </Canvas.Background> <TextBlock FontSize="11" FontFamily="Portable User Interface" FontWeight="Normal" FontStyle="Normal" FontStretch="Normal" TextWrapping="NoWrap" TextTrimming="None" TextAlignment="Left" Text="Amyo Kabir" Padding="0,0,0,0" LineHeight="0" LineStackingStrategy="MaxHeight" MinWidth="0" MinHeight="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,0" FlowDirection="LeftToRight" AllowDrop="False" Opacity="1" RenderTransformOrigin="0,0" IsHitTestVisible="True" Visibility="Visible" UseLayoutRounding="True" Canvas.Left="0" Canvas.Top="0" Canvas.ZIndex="0"> <TextBlock.Foreground> <SolidColorBrush Color="#FF000000" Opacity="1" /> </TextBlock.Foreground> </TextBlock> </Canvas>