2012-04-12 122 views
1

我正在使用wpf和vb.net在canvas上创建工作流设计器。我已经可以在具有很好功能的对象之间绘制线条(关系)。现在我想实现一种删除关系的方法。我在形状上添加了一个onclick处理程序,但该行非常薄且难以点击。我听说绘制2行1的行程厚度较厚,但这是不可能的,因为drawline方法在cpu上很重。工作流设计器行onclick太薄

谢谢你帮

大卫

回答

3

你可以鼠标按下事件处理程序添加到画布上,而不是形状的物体,然后再做Hit Testing in the Visual Layer(虽然API是有点怪)与hit test geometry,例如椭圆形。画布需要设置其Background(例如到Transparent)来接收鼠标事件。

对不起,这是C#,但我不会说VB:

private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    Canvas canvas = sender as Canvas; 
    EllipseGeometry hitTestGeometry = 
     new EllipseGeometry(e.GetPosition(canvas), 10d, 10d); 
    Shape hitShape = null; 

    HitTestResultCallback hitTestCallback = 
     result => 
     { 
      hitShape = result.VisualHit as Shape; 
      return hitShape != null ? HitTestResultBehavior.Stop : HitTestResultBehavior.Continue; 
     }; 

    VisualTreeHelper.HitTest(canvas, null, hitTestCallback, new GeometryHitTestParameters(hitTestGeometry)); 

    if (hitShape != null) 
    { 
     System.Diagnostics.Trace.TraceInformation("hit shape: {0}", hitShape); 
    } 
} 

编辑:

下面是对应的VB代码。 VB不支持多行lambda表达式所以点击测试回调有明确声明

Private Function htCallback(ByVal result As HitTestResult) _ 
As HitTestResultBehavior 
    Dim hitShape As Shape = Nothing 
    hitShape = TryCast(result.VisualHit, Shape) 
    If hitShape IsNot Nothing Then 
     'do something 
    End If 
    Return If(hitShape IsNot Nothing, HitTestResultBehavior.[Stop], _ 
     HitTestResultBehavior.[Continue]) 
End Function 


Private Sub Canvas_MouseLeftButtonDown(ByVal sender As Object, _ 
    ByVal e As MouseButtonEventArgs) Handles Canvas1.MouseRightButtonDown 
    Dim canvas As Canvas = TryCast(sender, Canvas) 
    Dim hitTestGeometry As New EllipseGeometry(e.GetPosition(canvas), 10.0, 10.0) 
    Dim hitTestCallback As HitTestResultCallback = _ 
     New HitTestResultCallback(AddressOf htCallback) 
    VisualTreeHelper.HitTest(canvas, Nothing, hitTestCallback, _ 
     New GeometryHitTestParameters(hitTestGeometry)) 
End Sub 
+1

编辑添加VB代码,针对上述情况,等待批准;) – 2012-04-12 13:13:56

+0

是否击中测试已经比使用下面所描述的方法更好的性能? – DavidVdd 2012-04-12 13:14:04

+0

@DavidVdd - 通过命中测试,您可以指定鼠标周围需要查找线条的区域(这里是一个10x10椭圆),因此您可以有更大的容差区域,而不会使线条变得更大。他们都是快速/轻松的操作,无论如何,我认为你不应该感受到他们的性能问题。 – 2012-04-12 13:16:05

2

也许一个简单的答案,但是当你添加新线到画布上,你可以不喜欢

AddHandler myLine.MouseEnter, AddressOf lineHover 
AddHandler myLine.MouseLeave, AddressOf lineLeave 
AddHandler myLine.MouseDown, AddressOf lineDelete 
Canvas1.Children.Add(myLine) 

其中

Private Sub lineHover(ByVal sender As Object, ByVal e As MouseEventArgs) 
    CType(sender, Line).StrokeThickness = 3 
End Sub 

Private Sub lineLeave(ByVal sender As Object, ByVal e As MouseEventArgs) 
    CType(sender, Line).StrokeThickness = 1 
End Sub 

Private Sub lineDelete(ByVal sender As Object, ByVal e As MouseEventArgs) 
    Canvas1.Children.Remove(CType(sender, Line)) 
End Sub 

通过这种方式,当鼠标悬停在一条线上时,其笔划厚度增加。这使得该行更易于点击,并且可以为用户提供有关他们删除的行的一些很好的反馈。

相关问题