WPF 元素的可视化工具
Visualizer for WPF elements
尝试为一些 WPF 元素创建可视化工具,包括 DrawingImage
和 UIElement
等。虽然 creating a visualizer 是微不足道的,但我的可视化工具总是抛出目标对象类型的异常(DrawingImage
和 UIElement
即)未标记为可序列化。
进一步阅读表明我需要实现 VisualizerObjectSource
以提供自定义序列化。此 class 被指定为 DebuggerVisualizer
属性中的参数之一。我按照这些步骤操作,现在我的自定义序列化器被调用了,但我真的不知道在那里做什么。这是被调用的相关函数:
public override void GetData(object target, Stream outgoingData)
{
var writer = new StreamWriter(outgoingData);
writer.WriteLine(/*???*/);
writer.Flush();
}
不明白它对我的期望(UIElement
的二进制序列化版本?)以及我该如何编写 UIElement
或 DrawingImage
到传出流。有人以前做过吗?
我终于成功了。这比我想象的要简单得多。对于任何其他试图找到自己的方式的人,这里是它的工作原理:
首先,GetData()
覆盖(阅读问题)将由您管理。您必须决定要发送给可视化工具的内容。发送足够的信息,以便您能够在 Show()
调用中构造对象。
事实证明,对于 WPF 元素,序列化比我想象的要简单得多。有内置的 XamlReader
和 XamlWriter
class 可用于执行 WPF 对象的 serialization/deserialization。
在 Show()
中重建对象后,只需在 Form
中显示它即可。请注意,Visual Studio 仅支持老式 Form
和 Control
classes(即 WinForms),不支持 WPF Window
s,但您可以解决此问题通过在您的表单或控件中放置一个 ElementHost
,然后将重构的 WPF 对象分配为此 ElementHost
.
的子对象
您可能想要在 ElementHost
和重建对象之间添加一个 ViewBox
层,以使其优雅地适合可用的 space。
我已经上传了 WPFVisualizers project on GitHub 以防有人感兴趣。目前它包含两个可视化工具,用于 DrawingImage
和 UIElement
类型。这些一起涵盖了 WPF 世界的大部分视觉元素,但您可以根据需要自由添加更多类型。该项目包含 VisualizerBase
class,其中包含所有可视化工具 serialization/communication 逻辑。这使得创建新的 WPF 可视化工具就像编写 1 行代码一样简单,如下所示:
public class GeometryDrawingVisualizer : VisualizerBase<GeometryDrawing, GeometryDrawingControl>
{
}
就是这样。您已经为 GeometryDrawing
类型创建了一个新的可视化工具。第二个通用参数(上例中的 GeometryDrawingControl
)是 WinForms Control
(如果您愿意,也可以是 Form
),它将构成可视化工具的 UI。在您的控件中放置一个 ElementHost
,然后放入您需要呈现的任何类型。
尝试为一些 WPF 元素创建可视化工具,包括 DrawingImage
和 UIElement
等。虽然 creating a visualizer 是微不足道的,但我的可视化工具总是抛出目标对象类型的异常(DrawingImage
和 UIElement
即)未标记为可序列化。
进一步阅读表明我需要实现 VisualizerObjectSource
以提供自定义序列化。此 class 被指定为 DebuggerVisualizer
属性中的参数之一。我按照这些步骤操作,现在我的自定义序列化器被调用了,但我真的不知道在那里做什么。这是被调用的相关函数:
public override void GetData(object target, Stream outgoingData)
{
var writer = new StreamWriter(outgoingData);
writer.WriteLine(/*???*/);
writer.Flush();
}
不明白它对我的期望(UIElement
的二进制序列化版本?)以及我该如何编写 UIElement
或 DrawingImage
到传出流。有人以前做过吗?
我终于成功了。这比我想象的要简单得多。对于任何其他试图找到自己的方式的人,这里是它的工作原理:
首先,GetData()
覆盖(阅读问题)将由您管理。您必须决定要发送给可视化工具的内容。发送足够的信息,以便您能够在 Show()
调用中构造对象。
事实证明,对于 WPF 元素,序列化比我想象的要简单得多。有内置的 XamlReader
和 XamlWriter
class 可用于执行 WPF 对象的 serialization/deserialization。
在 Show()
中重建对象后,只需在 Form
中显示它即可。请注意,Visual Studio 仅支持老式 Form
和 Control
classes(即 WinForms),不支持 WPF Window
s,但您可以解决此问题通过在您的表单或控件中放置一个 ElementHost
,然后将重构的 WPF 对象分配为此 ElementHost
.
您可能想要在 ElementHost
和重建对象之间添加一个 ViewBox
层,以使其优雅地适合可用的 space。
我已经上传了 WPFVisualizers project on GitHub 以防有人感兴趣。目前它包含两个可视化工具,用于 DrawingImage
和 UIElement
类型。这些一起涵盖了 WPF 世界的大部分视觉元素,但您可以根据需要自由添加更多类型。该项目包含 VisualizerBase
class,其中包含所有可视化工具 serialization/communication 逻辑。这使得创建新的 WPF 可视化工具就像编写 1 行代码一样简单,如下所示:
public class GeometryDrawingVisualizer : VisualizerBase<GeometryDrawing, GeometryDrawingControl>
{
}
就是这样。您已经为 GeometryDrawing
类型创建了一个新的可视化工具。第二个通用参数(上例中的 GeometryDrawingControl
)是 WinForms Control
(如果您愿意,也可以是 Form
),它将构成可视化工具的 UI。在您的控件中放置一个 ElementHost
,然后放入您需要呈现的任何类型。