WPF-如何最好地实现具有可拖动/可缩放子项的面板? [英] WPF - how to best implement a panel with draggable/zoomable children?

查看:395
本文介绍了WPF-如何最好地实现具有可拖动/可缩放子项的面板?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to modify the default graph viewer of the Graph# library because its user interface is awful (just try dragging a node outside of the boundaries, you'll see!)

基本设置是这样的:有一个GraphCanvas控件(从Panel继承),该控件具有Vertex和Edge控件类型的子级。我要实现的是:

The basic setup is this: there is a GraphCanvas control (inherited from Panel) which has children of Vertex and Edge control types. What I want to achieve is:


  • 如果内容不适合屏幕,GraphCanvas会带有滚动条;

  • GraphCanvas也可以通过拖动它来滚动(只需单击一个空白区域并拖动);

  • GraphCanvas可以放大和缩小(通过CTRL +鼠标滚轮) ;

  • 可以拖动顶点。如果将顶点拖到GraphCanvas的当前边界之外,则边界会增加。滚动条应反映这一点,但是在拖动顶点时,当前视口不应滚动离开。如果拖动顶点会减小GraphCanvas的边界,情况也是如此-它应保持相同的大小,直到拖动操作完成,然后才调整大小。在拖动操作期间自动滚动视口会造成极大的混乱,并容易引起拖动错误。如果您想了解我的意思,请参见原始实现。

  • GraphCanvas has scroll bars if the contents do not fit in the screen;
  • GraphCanvas can also be scrolled by "dragging" it (just click on an empty space and drag);
  • GraphCanvas can be zoomed in and out (via CTRL+mouse wheel);
  • Vertices can be dragged around. If a vertex is dragged outside the current boundaries of GraphCanvas, the boundaries are increased. The scroll bars should reflect this, however the current viewport should not scroll away while the vertex is being dragged . The same goes if dragging a vertex reduces the boundaries of GraphCanvas - it should stay the same size until the drag operation is finished and resize only then. Automatically scrolling the viewport during a drag operation is awfully confusing and easily introduces dragging errors. See the original implementation if you want to know what I mean.

尽管我在.NET方面有丰富的经验,我仍然是WPF的完整入门者。我当前的尝试是(在度量/排列布局阶段)为每个文本提供所需的XY坐标(即使是负数),并通过处理GraphCanvas上的鼠标事件并修改RenderTransform属性来实现缩放/滚动。拖动只会更改特定顶点上的XY坐标(可能会触发整个对象的重新布局,这也很可能避免)。滚动条是通过将GraphCanvas放在ScrollViewer中并在GraphCanvas上实现IScrollInfo来实现的。

Although I've got a fair bit of experience with .NET, I'm still a complete beginner in WPF. My current attempt is (in the measure/arrange layout phase) to give each vertext the XY coordinate it desires (even if negative) and implement zooming/scrolling by handling mouse events on the GraphCanvas and modifying the RenderTransform property. Dragging just changes the XY coordinates on the specific vertex (probably triggering the re-layout of the whole thing which would be nice to avoid too). Scrollbars are implemented by placing the GraphCanvas inside a ScrollViewer and implementing IScrollInfo on the GraphCanvas.

不幸的是,这似乎是一个问题:我只能在GraphCanvas本身上获取鼠标事件如果有背景的话。没关系,我仍然想要一个白色背景,但是在GraphCanvas的负坐标中,它不会绘制背景-因此不会响应鼠标事件。

Unfortunately there seems to be a problem: I can get mouse events on the GraphCanvas itself only if it has a background at the point. That would be OK, I want a white background anyway, but in the negative coordinates of the GraphCanvas it does not draw the background - and thus does not respond to mouse events.

我也想知道是否通过允许所有子控件(顶点和边)进入负坐标来执行正确的事情。您将如何实施?



已添加:要澄清背景问题,请查看以下屏幕截图:


(来源: valts.21.lv

I'm also wondering if I'm doing the Right Thing by allowing all my child controls (vertices and edges) to go into negative coordinates. How would you implement this?


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

在这里看到的是带有WPF Host控件的简单Windows窗体表单。里面有一个ScrollViewer,而ScrollViewer里面有GraphCanvas。 GraphCanvas包含4个顶点和6条边。

What you see here is a simple Windows Forms form with a WPF Host control on it. That has a ScrollViewer in it, and the ScrollViewer has the GraphCanvas in it. The GraphCanvas contains 4 vertices and 6 edges.

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

The GraphCanvas is stretched to fill the ScrollViewer. But since some of the vertices are at negative coordinates, it has a RenderTransform applied which simply shifts everything to the right (TranslateTransform). It also has a white background brush.

请注意左侧的灰色区域。那仍然是GraphCanvas的一部分,但是背景画笔在某种程度上并没有消失。另外,如果我用鼠标左键单击那里(不在节点上,而是在灰色区域),我会得到事件。如果我在白色区域上单击鼠标左键,则将得到所有事件。

Note the gray area on the left. That's still a part of the GraphCanvas, but the background brush somehow doesn't exted there. Also, if I left-click there with my mouse (not on a node, but on the gray area), I do NOT get an event. If I left-click on the white area, I get all events just fine.

推荐答案

您可以附加可拖动行为每个元素。

You can attach a 'Draggable' behavior to each element.

这篇关于WPF-如何最好地实现具有可拖动/可缩放子项的面板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆