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

需求:

  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)的范围内拖动,于是将MouseDragElementBehavior ConstrainToParentBounds设置为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 = new TranslateTransform(Point.X, Point.Y);

 

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

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值