我正在尝试修改 Graph# 库的默认图形查看器,因为它的用户界面很糟糕(只需尝试将节点拖动到边界之外,你会看到!)
基本设置是这样的:有一个 GraphCanvas 控件(继承自 Panel),它具有 Vertex 和 Edge 控件类型的子项。我想要实现的是:
- 如果内容不适合屏幕,则 GraphCanvas 有滚动条;
- GraphCanvas 也可以通过“拖动”来滚动(只需点击空白处并拖动即可);
- GraphCanvas 可以放大和缩小(通过 CTRL+鼠标滚轮);
- 可以拖动顶点。如果一个顶点被拖到 GraphCanvas 的当前边界之外,边界就会增加。滚动条应该反映这一点,但是当顶点被拖动时,当前视口不应该滚动。如果拖动一个顶点会减少 GraphCanvas 的边界,情况也是如此——它应该保持相同的大小,直到拖动操作完成,然后才调整大小。在拖动操作期间自动滚动视口非常令人困惑,并且很容易引入拖动错误。如果您想知道我的意思,请参阅原始实现。
尽管我对 .NET 有一定的经验,但我仍然是 WPF 的初学者。我目前的尝试是(在测量/排列布局阶段)为每个顶点提供它想要的 XY 坐标(即使是负数),并通过处理 GraphCanvas 上的鼠标事件和修改 RenderTransform 属性来实现缩放/滚动。拖动只会更改特定顶点上的 XY 坐标(可能会触发整个事物的重新布局,这也可以避免)。滚动条是通过将 GraphCanvas 放置在 ScrollViewer 中并在 GraphCanvas 上实现 IScrollInfo 来实现的。
不幸的是,似乎有一个问题:只有当 GraphCanvas 本身有背景时,我才能在它本身上获取鼠标事件。没关系,无论如何我都想要一个白色背景,但是在 GraphCanvas 的负坐标中它不会绘制背景 - 因此不会响应鼠标事件。
我还想知道我是否通过允许我的所有子控件(顶点和边)进入负坐标来做正确的事情。你将如何实现这一点?
补充:要澄清背景问题,请查看以下屏幕截图:( 来源:valts.21.lv)
您在这里看到的是一个简单的 Windows 窗体窗体,上面有一个 WPF 主机控件。里面有一个 ScrollViewer,而 ScrollViewer 里面有 GraphCanvas。GraphCanvas 包含 4 个顶点和 6 个边。
GraphCanvas 被拉伸以填充 ScrollViewer。但是由于某些顶点位于负坐标,因此它应用了 RenderTransform,它只是将所有内容向右移动(TranslateTransform)。它还有一个白色背景画笔。
注意左边的灰色区域。这仍然是 GraphCanvas 的一部分,但背景画笔不知何故没有延伸到那里。此外,如果我用鼠标左键单击那里(不是在节点上,而是在灰色区域上),我不会收到事件。如果我左键单击白色区域,我会得到所有事件。