拓扑图节点拖动的实现(学习笔记)

来源:互联网 发布:解剖学软件 编辑:程序博客网 时间:2024/06/03 19:17

需求:

  1. 拓扑图的节点可以拖动

  2. 当有警报时,在节点上需要提示,直至警报解除

  3. 拓扑图所在的窗口可以变动大小。当缩小主窗口,拓扑图显示不下时,需要出现滚动条,此时拖动icon到拓扑图边缘,滚动可以跟随移动。

  4. 拓扑图节点的位置保存导出,以便下次打开拓扑图时可以实现复原

拖动的实现

利用WPFMouseDragElementBehavior实现拓扑图的各个节点的拖动。使用MouseDragElementBehavior需要添加两个ReferenceMicrosoft.Expression.InteractionsSystem.Windows.Interactivity

    publicpartialclassDragIcon :UserControl    {        MouseDragElementBehavior dragBehavior = null;         public DragIcon()        {            InitializeComponent();        }         privatevoidInitializedragBehavior()        {            dragBehavior = newMouseDragElementBehavior();            dragBehavior.Attach(this);        }    }

 

报警的实现:

节点的拖动,为了在拓扑图(TopologicalView)的范围内拖动,于是将MouseDragElementBehaviorConstrainToParentBounds设置为true,然后alert的实现,就自然想通过Popup来实现。但是Popup有两个问题,一是不会跟随节点拖动,二是总显示在所有窗体的前面(包括别的软件)。针对问题一,可以通过将GetMethod访问Popup的私有函数UpdatePosition,重新指定Popup的位置。问题二,虽然通过user32.dllSetWindowPos的方法将Popup的设置为NotTopmost,可以不显示在别的软件前面,但是拖动到拓扑图的边缘时,节点会被边缘遮挡,但是Popup不会,感觉比较奇怪。于是最终放弃Popup,直接通过添加一个image来实现。但是这样节点的整个的大小就变大了,为了使节点可以拖动到拓扑图的边缘,又将ConstrainToParentBounds设置为false,然后通过控制鼠标的位置实现在拓扑图的范围内拖动。详细请看下一节【节点拖动时带动滚动条的实现】。

问题一的解决方法(来源http://www.cnblogs.com/xiaokang088/archive/2011/07/06/2099489.html

 

    var mi = typeof(Popup).GetMethod("UpdatePosition", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);    mi.Invoke(popBottom, null);

 

问题二的解决方法(来源http://www.cnblogs.com/Leaco/p/3164394.html):

 

{CSDN:CODE:2322488

 

 

节点拖动时带动滚动条的实现:

TopologicalView中各个节点是否处在拖动中的状态进行MultiBinding,绑定到TopologicalView的一个附加属性IconDragging中,然后在主窗口的MouseMove的事件响应函数中,当TopologicalViewIconDraggingtrue时,对鼠标位置进行判断,看是否超出显示范围,如果超出显示范围,对鼠标位置进行重新设定,并设定滚动条的位置。

前三节的具体的代码请参看http://download.csdn.net/detail/xiudou_123/9806342

 

节点位置保存的实现:

DragIcon中定义附加属性DragBehaviorXDragBehaviorY,然后和MouseDragElementBehaviorXY的进行绑定,就能够实时取到拖动节点的位置信息,但是MouseDragElementBehaviorXY是相对于窗口的绝对位置,所以需要转换成TopologicalView的相对信息,这就需要知道TopologicalView的左上角相对于窗口的位置。另外MouseDragElementBehaviorXYDragIcon的左上角的位置,为了定位到DragIcon的中心点,所以还需要进行转换,这里的计算不难,但是位置的转换稍微有些绕,需要小心。进行了所有这些计算后,将值保存到另外两个附加属性LocationXLocationY。父窗口可以直接对LocationXLocationY进行取值,也可以通过绑定实现取值。

具体请看例子http://download.csdn.net/detail/xiudou_123/9808949

例子是通过绑定的形式,将LocationXLocationY绑定到一个IconLocation的类中,所以可以直接对IconLocation进行保存或取值实现自己需要的功能。

 

节点位置复原的实现:

新建一个DragIcon,需要指定其位置时,通过设置MouseDragElementBehaviorXY是不行的,但是可以通过在Loaded事件中设置DragIconRenderTransform来实现。

RenderTransform =newTranslateTransform(Point.X, Point.Y);

 

具体也请看例子http://download.csdn.net/detail/xiudou_123/9808949

 

0 0
原创粉丝点击