ArcGIS for Silverlight API中實現可拖動的bubble

  ArcGIS for Silverlight API中沒有像ArcGIS Engine中的BalloonCallout。最近花了兩天時間在Silverlight中實現了類似的效果。雖然比較粗糙,不過基本能滿座需求吧,後續急需完善。現將實現思路介紹如下。

1、bubble容器的兩條對角線將bubble容器分爲4個象限。當鼠標拖動該容器移動時,錨點會落到其中的一個象限中,從而改變箭頭的方向。

2、繪製bubble,從A點(起點)順時針繪製。

代碼如下:

  GeneralTransform gt = _ContentContainer.TransformToVisual(Application.Current.RootVisual as UIElement);
  Point offset = gt.Transform(new Point());
  Point ArrowHead = new Point(Anchor.X - offset.X, Anchor.Y - offset.Y);
  PathGeometry geometry = new PathGeometry();
  PathFigure figure = new PathFigure { IsClosed = true };
  geometry.Figures.Add(figure);
  figure.StartPoint = new Point(source.X, source.Y + CornerRadius);
  figure.Segments.Add(new ArcSegment { Point = new Point { X = source.X + CornerRadius, Y = source.Y }, SweepDirection = SweepDirection.Clockwise, Size = new Size { Width = CornerRadius, Height = CornerRadius } });
  figure.Segments.Add(new LineSegment { Point = new Point { X = source.X + ContentWidth / 2 - Leaderwidth / 2, Y = source.Y } });
  figure.Segments.Add(new LineSegment { Point = ArrowHead });
  figure.Segments.Add(new LineSegment { Point = new Point { X = source.X + ContentWidth / 2 + Leaderwidth / 2, Y = source.Y } });
  figure.Segments.Add(new LineSegment { Point = new Point { X = source.X + ContentWidth - CornerRadius, Y = source.Y } });
  figure.Segments.Add(new ArcSegment { Point = new Point { X = source.X + ContentWidth, Y = source.Y + CornerRadius }, SweepDirection = SweepDirection.Clockwise, Size = new Size { Width = CornerRadius, Height = CornerRadius } });
  figure.Segments.Add(new LineSegment { Point = new Point { X = source.X + ContentWidth, Y = source.Y + ContentHeight - CornerRadius } });
  figure.Segments.Add(new ArcSegment { Point = new Point { X = source.X + ContentWidth - CornerRadius, Y = source.Y + ContentHeight }, SweepDirection = SweepDirection.Clockwise, Size = new Size { Width = CornerRadius, Height = CornerRadius } });
  figure.Segments.Add(new LineSegment { Point = new Point { X = source.X + CornerRadius, Y = source.Y + ContentHeight } });
  figure.Segments.Add(new ArcSegment { Point = new Point { X = source.X, Y = source.Y + ContentHeight - CornerRadius }, SweepDirection = SweepDirection.Clockwise, Size = new Size { Width = CornerRadius, Height = CornerRadius } });
  figure.Segments.Add(new LineSegment { Point = new Point(source.X, source.Y + CornerRadius) });

3、拖動bubble容器,比較簡單,廢話不多講。代碼是沒有二義性的,看代碼就能明白。直接上代碼吧。

void Bubble_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            ContentControl item = sender as ContentControl;
            if (isMouseCaptured)
            {

                // Calculate the current position of the object.
                double deltaV = e.GetPosition(null).Y - mouseVerticalPosition;
                double deltaH = e.GetPosition(null).X - mouseHorizontalPosition;
                double newTop = deltaV + (double)item.GetValue(Canvas.TopProperty);
                double newLeft = deltaH + (double)item.GetValue(Canvas.LeftProperty);

                // Set new position of object.
                item.SetValue(Canvas.TopProperty, newTop);
                item.SetValue(Canvas.LeftProperty, newLeft);

                // Update position global variables.
                mouseVerticalPosition = e.GetPosition(null).Y;
                mouseHorizontalPosition = e.GetPosition(null).X;
                Render(deltaH, deltaV);
            }
        }

        void Bubble_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            ContentControl item = sender as ContentControl;
            isMouseCaptured = false;
            item.ReleaseMouseCapture();
            mouseVerticalPosition = -1;
            mouseHorizontalPosition = -1;
        }

        void Bubble_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            ContentControl item = sender as ContentControl;
            mouseVerticalPosition = e.GetPosition(null).Y;
            mouseHorizontalPosition = e.GetPosition(null).X;
            isMouseCaptured = true;
            item.CaptureMouse();
        }

4、最終效果

下一篇介紹在ArcGIS for Silverlight API中集成該功能,實現地圖上的扯旗標註。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章