views:

637

answers:

3

I see that the .Net XamlWriter is not available in Silverlight. Well - I need one anyway, so I assume there is a solution to this..?

I have some UIElement objects (Path, Ellipse, Rectangle, ..), and I want to store their Xaml definition such that I can load these later using XamlWriter.Load(). Any ideas on how to do this? Any 3rdParty XamlWriter implementations etc that are recommended?

A: 

Use the XamlReader class instead, from System.Windows.Markup, see below. The namespace on the root element is required. More info from MS.

Alternatively you can put these in DataTemplates in your controls as a resources and just load them from the resources.

<UserControl x:Class="LoadingXaml.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
    <UserControl.Resources>
        <DataTemplate x:Key="TemplateXaml">
            <Rectangle Height="50"  Width="50" Fill="Blue" />
        </DataTemplate>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <StackPanel x:Name="Display" />
        <StackPanel Orientation="Horizontal" Grid.Row="1">
            <Button x:Name="LoadFromString" Content="Load From String" Click="LoadFromString_Click" />
            <Button x:Name="LoadFromDT" Content="Load From Data Template" Click="LoadFromDT_Click" />
        </StackPanel>
    </Grid>
</UserControl>

MainPage.xaml.cs:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;

namespace LoadingXaml
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void LoadFromString_Click(object sender, RoutedEventArgs e)
        {
            Display.Children.Add((UIElement)XamlReader.Load("<Rectangle xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' Height='50'  Width='50' Fill='Red' />"));
        }

        private void LoadFromDT_Click(object sender, RoutedEventArgs e)
        {
            var dt = (DataTemplate)Resources["TemplateXaml"];
            Display.Children.Add((UIElement)dt.LoadContent());
        }
    }
}
mattmanser
Thx for you answer, but I'm afraid this doesn't help me.. Sure, I use XamlReader, but that is for the opposite direction; create object from Xaml. My question was to extract the Xaml representation from an object. And I can't load from DataTemplate as the data will be all dynamically fetched from a DB. So; what I need is some function to extract a string representing the Xaml for a UIElement.
stiank81
+2  A: 

There seems to be some implementations of XamlWriter for Silverlight around. The one I've seen which looks most serious is in Silverlight Contrib, but this is not yet supported for SL3, which I'm using.

Since I only had a few specific objects to extract xaml from I created the functions to do so myself. Some more refactoring will be done, but this one works for finding the xaml for my path drawing - stored as a InkPresenter:

    public static string ConvertPathToXaml(InkPresenter drawObject)
    {
        string xmlnsString = "http://schemas.microsoft.com/client/2007";
        XNamespace xmlns = xmlnsString;

        var strokes = new XElement(xmlns + "StrokeCollection");             

        foreach (var strokeData in drawObject.Strokes)
        {
            var stroke = new XElement(xmlns + "Stroke",
                new XElement(xmlns + "Stroke.DrawingAttributes",
                    new XElement(xmlns + "DrawingAttributes",
                        new XAttribute("Color", strokeData.DrawingAttributes.Color),
                        new XAttribute("OutlineColor", strokeData.DrawingAttributes.OutlineColor),
                        new XAttribute("Width", strokeData.DrawingAttributes.Width),
                        new XAttribute("Height", strokeData.DrawingAttributes.Height))));                        
            var points = new XElement(xmlns + "Stroke.StylusPoints");

            foreach (var pointData in strokeData.StylusPoints)
            {
                var point = new XElement(xmlns + "StylusPoint",
                    new XAttribute("X", pointData.X),
                    new XAttribute("Y", pointData.Y));
                points.Add(point);
            }
            stroke.Add(points);
            strokes.Add(stroke);
        }

        var strokesRoot = new XElement(xmlns + "InkPresenter.Strokes", strokes);
        var inkRoot = new XElement(xmlns + "InkPresenter", new XAttribute("xmlns", xmlnsString), 
            new XAttribute("Opacity", drawObject.Opacity), strokesRoot);

        return inkRoot.ToString();
    }
stiank81
A: 

Where is the class in the silverlight contrib project?

It's in the class XamlWriter. In namespace SilverlightContrib.Xaml. You should find it through this link: http://silverlightcontrib.codeplex.com/sourcecontrol/changeset/view/49151?projectName=silverlightcontrib#602856 There seems to be some related files too. I ended up writing what I needed myself, so I haven't looked at the details of SilverlightContrib.
stiank81