【问题标题】:WPF Saving a canvas and then retrieving it back from the persisted stateWPF 保存画布,然后从持久状态中检索它
【发布时间】:2014-01-24 23:42:41
【问题描述】:

我正在开发一个 WPF 应用程序,我必须在其中向最终用户提供一个画布。画布应该有一个工具箱,其中包含基本形状,如矩形、正方形等,他可以将其拖放到画布上。用户完成后,他会点击保存按钮。

现在应该将画布保存到数据库中,并且当用户下次去检索它时,他应该使画布处于他上次离开时​​的相同状态,以便他可以继续编辑。 画布代表一个楼层,其中有多个部分,每个部分都由一个基本形状表示。

我们将不胜感激。

【问题讨论】:

  • 你有没有想过序列化到数据库?
  • 是的,序列化到数据库将是最后一步。 XAML 文件必须进行序列化和反序列化,但我卡住的地方是我采用什么方法来构建画布和工具箱。用户如何在表面上拖放以及如何在编辑后保存文件,然后再次加载它以进行编辑。
  • 这里的关键是MVVM。保留模型,而不是视图。
  • @Rachit,该数据库旨在处理您画布的抽象。创建一个 DTO,其中包含从头开始重新创建画布所需的所有值。如果你检查你的画布和工具等,你会发现它们都可以抽象成简单的字符串和数字。阅读 Sheridan 的答案以获取更多信息。

标签: c# sql-server wpf canvas


【解决方案1】:

如果您查看我对this question about writing a WPF chess application 的回答,您将了解如何使用数据驱动模型创建包含各种元素的画布。然后,您可以使用standard C# serialization 将该数据序列化到您需要的任何持久存储中。

【讨论】:

  • 标记感谢帖子的链接但是我希望画布是动态的,即不像棋盘那样固定。要求是用户可以拖放到画布上,然后必须存储画布,然后再次加载..
  • 如果您查看我发布的代码,您会发现它实际上是动态的,它只是可以操作和添加/删除等项目的集合,它是 XAML 的责任决定如何根据它们的属性来渲染这些项目。
【解决方案2】:

@Rachit,我可能是错的,但你似乎错过了这里的重点。也就是说,您不应该保存 UI 元素,而应该保存显示为 UI 元素的数据。

必须已经拥有包含Canvas 上的位置、颜色和形状类型的数据对象...这是您应该保存的内容,而不是实际的 XAML。使用Serialization,这是一个非常简单的过程。您可以关注How to save/restore serializable object to/from file?问题中的答案。

现在可以使用XamlWriter.Save Method 直接保存XAML。让我们假设您确实这样做了......所以您现在有一个包含一些 XAML 的保存文件。现在怎么办?即使您设法在视图模型或后面的代码中重新加载您的Canvas(实际上不应该对 UI 有任何了解),那么您会怎么做?

您手中可能有一个Canvas,但您不再拥有数据。如果用户想要移动一个对象怎么办?你没有数据,所以你不能。现在,如果您保存了数据,那么Canvas 可以总是随时重新渲染。这就是(众多原因之一)您需要保存数据而不是 UI 控件的原因。

【讨论】:

  • 完全同意,当然还有XamlReader.Load的方法。
  • 很好@Clemens,谢谢...我必须学会更好地集中注意力。 :)
  • @Sheridan 感谢您的想法.. 我明白了这一点.. 将尝试在一个小项目中实现这一点,然后可能无法实际实现... 将根据我的进度不断更新帖子..
【解决方案3】:

保存位于 WPF 表单中的画布mainImageCanvas

FileStream fs = File.Open("fileName.xaml", FileMode.Create);
XamlWriter.Save(mainImageCanvas, fs);
fs.Close();

将保存的画布读入mainImageCanvas

FileStream fs = File.Open("fileName.xaml", FileMode.Open, FileAccess.Read);
Canvas savedCanvas = XamlReader.Load(fs) as Canvas;
fs.Close();

while (savedCanvas.Children.Count > 0)
{
     UIElement uie = savedCanvas.Children[0];
     savedCanvas.Children.Remove(uie);
     mainImageCanvas.Children.Add(uie);
}

【讨论】:

    猜你喜欢
    • 2015-07-25
    • 1970-01-01
    • 1970-01-01
    • 2013-01-15
    • 2012-04-13
    • 2016-02-29
    • 2015-03-09
    • 2019-08-01
    • 2013-03-24
    相关资源
    最近更新 更多