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

时间:2009-09-03 10:53:41

标签: wpf custom-controls zoom drag

我正在尝试修改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的一部分,但背景画笔不知何故并没有在那里出现。此外,如果我用鼠标左键单击(不是在节点上,而是在灰色区域),我会 NOT 获取事件。如果我左键单击白色区域,我会把所有事件都搞定。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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