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

2017-04-10 11:09:10来源:CSDN作者:xiudou_123人点击




需求:

  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,然后通过控制鼠标的位置实现在拓扑图的范围内拖动。详细请看下一节【节点拖动时带动滚动条的实现】。

问题二的解决方法(从网上参考来的): 

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

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

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台