【问题标题】:Copy/Clone contents of one grid to the other in uwp在 uwp 中将一个网格的内容复制/克隆到另一个网格
【发布时间】:2020-04-03 21:33:08
【问题描述】:

我看到这篇帖子XamlWriter deepcopy 将一个网格的内容复制到另一个网格。它要求使用 XamlWriter 并将字符串传递给 XamlReader。但是 XamlWriter 类在 uwp 中不可用。所以我看到这篇文章Serializing in uwp 要求改用 XmlSerializer。当我尝试以下操作时,我得到一个异常,说不能序列化非公共成员。请帮忙。简单来说,如何在 UWP 中将一个 Grid 的内容克隆到另一个 Grid。

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>

我尝试了以下方法,但出现异常

    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.

所以我尝试了以下方法来进行深层复制。但它抱怨说 gridBarImagePanel.Children 没有标记为可序列化。当我尝试创建一个继承 UIElementCollection 的自定义类时,该类是密封的。

        string content;
        using (var stream = new MemoryStream())
        {
            BinaryFormatter f = new BinaryFormatter();
            f.Serialize(stream, gridBarImagePanel.Children);
            stream.Position = 0;
            content = new StreamReader(stream).ReadToEnd();
        }

【问题讨论】:

    标签: c# xaml uwp clone


    【解决方案1】:

    因为序列化 XAML 与序列化 XML 或 JSON 不同,您不能直接使用 XmlSerializer 来实现。在 UWP 中,有一个 XamlReader 类可以从 XAML 字符串解析 XAML,但是没有 api 可以将 XAML 解析为 xml 文件,因此您可以手动创建一个 xml 文件,然后将要复制的内容复制到文件中.之后就可以使用XamlReader将xml文件解析为内容了。

    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);
    

    更新:

    没有将 XAML 解析为 xml 的直接方法,但您可以参考这个类似的 thread,它手动实现了深层复制。当你想在另一个页面中复制 Grid 的内容时,传递 gridBarImagePanel 并调用它。如果要访问另一个页面中的 gridBarImagePanel,需要将其 FieldModifier 设置为 public

    MainPage.xaml:

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

    MainPage.cs:

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

    另一页:

    Grid myGrid = UIElementExtensions.DeepClone<Grid>(MainPage.Current.gridBarImagePanel);
    stackPanelRoot.Children.Add(myGrid);
    

    【讨论】:

    • 嗯我明白,但问题是我正在向网格动态添加一些 UI 元素,就像添加渲染转换一样。我还在画布上添加了一些可以拖动的孩子。稍后单击某些按钮单击,有没有办法获取 xaml 字符串并写入 XML。
    • 没有直接的方法来获取 xaml 字符串并写入 XML,有一个类似的 thread 关于手动实现深拷贝。我已经更新了我的答案,你可以检查一下。
    猜你喜欢
    • 2013-02-03
    • 1970-01-01
    • 2019-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多