WPF - 如何最好地实现具有可拖动/可缩放儿童的面板?

问题描述 投票:2回答:2

我正在尝试修改Graph#库的默认图形查看器,因为它的用户界面非常糟糕(只需尝试拖动边界外的节点,你会看到!)

基本设置是:有一个GraphCanvas控件(继承自Panel),它具有Vertex和Edge控件类型的子项。我想要实现的是:

  • 如果内容不适合屏幕,GraphCanvas有滚动条;
  • GraphCanvas也可以通过“拖动”来滚动(只需单击空白区域并拖动);
  • GraphCanvas可以放大和缩小(通过CTRL +鼠标滚轮);
  • 可以拖动顶点。如果将顶点拖动到GraphCanvas的当前边界之外,则会增加边界。滚动条应该反映这一点,但是当拖动顶点时,当前视口不应滚动。如果拖动顶点减少了GraphCanvas的边界,则同样如此 - 它应该保持相同的大小,直到拖动操作完成,然后才调整大小。在拖动操作期间自动滚动视口非常容易混淆并且容易引入拖动错误。如果你想知道我的意思,请参阅原始实现。

虽然我对.NET有相当多的经验,但我仍然是WPF的完全初学者。我目前的尝试是(在测量/排列布局阶段)为每个椎骨提供它所需的XY坐标(即使是负面),并通过处理GraphCanvas上的鼠标事件并修改RenderTransform属性来实现缩放/滚动。拖动只会改变特定顶点上的XY坐标(可能会触发整个事物的重新布局,这也是很好的避免)。通过将GraphCanvas放在ScrollViewer中并在GraphCanvas上实现IScrollInfo来实现滚动条。

不幸的是,似乎存在一个问题:只有在具有背景的情况下,我才能在GraphCanvas上获得鼠标事件。那没关系,我想要一个白色背景,但是在GraphCanvas的负坐标中它不会绘制背景 - 因此不会响应鼠标事件。

我也想知道我是否通过允许我的所有子控件(顶点和边)进入负坐标来做正确的事情。你会如何实现这个?


Added: To clarify about the background problem check out the following screenshot:
(source: valts.21.lv)

你在这里看到的是一个简单的Windows窗体表单,上面有一个WPF主机控件。其中有一个ScrollViewer,ScrollViewer中有GraphCanvas。 GraphCanvas包含4个顶点和6个边。

GraphCanvas被拉伸以填充ScrollViewer。但由于某些顶点位于负坐标处,因此应用了RenderTransform,它只是将所有内容向右移动(TranslateTransform)。它还有一个白色的背景画笔。

注意左边的灰色区域。那仍然是GraphCanvas的一部分,但背景画笔不知何故并没有在那里出现。此外,如果我用鼠标左键单击(不是在节点上,而是在灰色区域),我不会得到一个事件。如果我左键单击白色区域,我会把所有事件都搞定。

wpf custom-controls zoom drag
2个回答
0
投票

在鼠标上调用canvas.mouseDown和CaptureMouse上的ReleaseMouseCapture。此外,如果您将画布背景设置为transparent,它仍然会被测试


0
投票

您可以将“可拖动”行为附加到每个元素。

© www.soinside.com 2019 - 2024. All rights reserved.