0

I saw this post XamlWriter deepcopy to copy contents of one grid to the another. It asks to use a XamlWriter and the pass on the string to XamlReader. But the XamlWriter class is not available in uwp. So I came across this article Serializing in uwp asking to use a XmlSerializer instead. When I try the following I get an exception saying cannot serialize non public members. Please help. In simple terms how can I clone the contents of one Grid to another in UWP.

xaml: I want to clone elements in this Grid into a new Grid from code behind.




               <Grid x:Name="gridBarImagePanel" 
                              RenderTransformOrigin="0.5,0.5" 
                              Width="800" VerticalAlignment="Stretch">
                        <Image x:Name="BarCodeImage" Stretch="None"></Image>

                        <Canvas Background="Pink" x:Name="cnvBarCodeImage" Opacity="0.5" AllowDrop="True">

                    </Canvas>
                </Grid>

I tried the following but get an exception

    var tempGrid = new Grid();
    XmlSerializer serializer = new XmlSerializer(typeof(Grid));
    StringWriter stringWriter = new StringWriter();
    serializer.Serialize(stringWriter, gridBarImagePanel.Children); //Gives an exception saying it does not have a parameterless constructor.

So I tried the following to do a deep copy. But it complains saying gridBarImagePanel.Children is not marked as Serializable. When I try to create a custom class that inherits UIElementCollection that class is sealed.

        string content;
        using (var stream = new MemoryStream())
        {
            BinaryFormatter f = new BinaryFormatter();
            f.Serialize(stream, gridBarImagePanel.Children);
            stream.Position = 0;
            content = new StreamReader(stream).ReadToEnd();
        }
nikhil
  • 1,578
  • 3
  • 23
  • 52

1 Answers1

0

For serializing XAML is not the same thing as serializing XML or JSON, you can not directly use XmlSerializer to achieve that. In UWP, there is a XamlReader class can parse the XAML from a XAML string, but there is no api can parse the XAML to xml file, so you could create a xml file manually and then copy the content you want to copy in the file. After that, you can use XamlReader to parse the xml file to the content.

XMLFile1.xml:

<?xml version="1.0" encoding="utf-8" ?>
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  x:Name="gridBarImagePanel"
  RenderTransformOrigin="0.5,0.5"
  Width="800" VerticalAlignment="Stretch">

  <Image x:Name="BarCodeImage" Source="Assets/StoreLogo.png" Stretch="None"></Image>
  <Canvas Background="Pink" x:Name="cnvBarCodeImage" Opacity="0.5" AllowDrop="True">
  </Canvas>
</Grid>

MainPage.xaml.cs:

StorageFile xml = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///XMLFile1.xml"));
Grid myCopyGrid = XamlReader.Load(await FileIO.ReadTextAsync(xml)) as Grid;
parentPanel.Children.Add(myCopyGrid);

Update:

There is no direct way to parse the XAML to xml, but you could refer to this similar thread which implements deep copy manually. When you want to copy the content of Grid in another page, pass the gridBarImagePanel and call it. If you want to access the gridBarImagePanel in antoher page, you need to set its FieldModifier to public.

MainPage.xaml:

<Grid x:Name="gridBarImagePanel" x:FieldModifier="public" ...>...

MainPage.cs:

public MainPage()
{
    this.InitializeComponent();
    Current = this;
}
public static MainPage Current;

Another page:

Grid myGrid = UIElementExtensions.DeepClone<Grid>(MainPage.Current.gridBarImagePanel);
stackPanelRoot.Children.Add(myGrid);
Faywang - MSFT
  • 5,798
  • 1
  • 5
  • 8
  • Hmm I understand but the thing is I am adding some UI elements to the grid dynamically like adding the render transform. I'm also adding some children to the canvas which can be dragged. Later on click of some button click, is there a way to get the xaml string and write to XML. – nikhil Dec 11 '19 at 14:27
  • There is no direct way to get the xaml string and write to XML, there is a similar [thread](https://stackoverflow.com/questions/15564493/how-to-clone-uielement-in-winrt-xaml-c) about implementing deep copy manually. I have updated my answer, you can check it. – Faywang - MSFT Dec 12 '19 at 06:35