Как ответить на событие клика с GMap.net для WPF

Я пишу программу WPF, которая использует GMapControl. Я хотел бы позволить пользователю нажать на карту и добавить маркер, по которому пользователь щелкнул. Я не хочу использовать события "MouseUp" и "MouseDown", чтобы событие было перехвачено, только когда пользователь фактически щелкнет карту и проигнорирует перетаскивание. Кроме того, я хотел бы иметь возможность ловить стилус и касаться событий таким же образом. Я заметил, что нет события "щелчка". Есть ли другая лучшая практика, как это должно быть сделано?

Thnx,

3 ответа

Кажется, уже поздно, но способ, которым я это сделал, - создать коллекцию, которая будет обрабатывать рендеринг полигонов в MapControl и Events. Сначала нужно создать базовый класс наших полигонов, который можно расширить.

public abstract class BasePolygon : GMapPolygon
{
    public BasePolygon() : base(new List<PointLatLng>())
    {

    }

    public virtual void Render(Map map)
    {
        //code for displaying polygons on map goes here, basically
        map.Markers.Add(this);
    }

    public virtual void Derender(Map map)
    {
        //code for removing polygons on map goes here, basically
        map.Markers.Remove(this);
    }
}

А затем создайте коллекцию, которая будет действовать как слой, который обрабатывает наши полигоны и их события. Ведет себя как ListBox или же ListView который имел SelectedItem собственность и SelectionChanged событие.

public abstract class BasePolygonList : List<BasePolygon>
{
    private BasePolygon SelectedItem_;
    public BasePolygon SelectedItem 
    { 
        get
        {
            return this.SelectedItem_;
        }

        set
        {
            this.SelectedItem_ = value;

            //fire the event when a polygon is 'clicked'
            this.OnSelectionChanged();
        }
    }

    protected Map map;

    public BaseFactory(Map map)
    {
        this.map = map;
    }

    //The Event which will fire if a polygon is clicked
    public event EventHandler SelectionChanged = delegate { };
    public void OnSelectionChanged()
    {
        if (this.SelectionChanged == null) return;

        this.SelectionChanged(this, new EventArgs());
    }

    //Render our polygons on the Map Control
    public void Render()
    {
        foreach(BasePolygon poly in this)
        {
            //Draw the polygon on the map
            poly.Render(this.map);

            //Enable the HitTest of the polygon
            poly.Shape.IsHitTestVisible = true;

            //Attach the Click Event at the polygon
            ((FrameworkElement)poly.Shape).MouseDown += (sender, e) =>
            {
                //Make sure that the Left Mouse Button is the one clicked 
                if(e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
                    //Set the the current polygon on the foreach as the Selected item
                    //It will also fire the SelectionChanged event
                    this.SelectedItem = poly;
            };
        }
    }
}


Пример использования

BasePolygonList polygonCollection = new BasePolygonList(MapControl);

//add your polygons here
//add your polygons here
//add your polygons here

//Display the polygons on the MapControl
polygonCollection.Render();

//do something when a polygon is clicked
polygonCollection.SelectionChanged += (s,e) =>
{
  Console.WriteLine("A polygon is Clicked/Selected");
  //get the object instance of the selected polygon
  BasePolygon SelectedPoly = polygonCollection.SelectedItem;
};


Наследование базового класса

Вы также можете унаследовать BasePolygon класс, чтобы удовлетворить ваши потребности. Например

public class RealProperty : BasePolygon
{
    public string OwnerName { get; set; }
    public decimal Area { get; set; }
    public decimal MarketValue { get; set; }
}

Реализация детского класса

BasePolygonList RealPropertyCollection = new BasePolygonList(MapControl);

//create our polygon with data
//don't forget to add the vertices
RealProperty RealPropertyItem1 = new RealProperty()
{
   OwnerName = "Some Owner Name",
   Area = 1000,
   MarketValue = 650000
};

//Add the created polygon to the list
RealPropertyCollection.Add(RealPropertyItem1);

//Display the polygons on the MapControl
RealPropertyCollection.Render();

//do something when a polygon is clicked
RealPropertyCollection.SelectionChanged += (s,e) =>
{
  //get the object instance of the selected polygon
  RealProperty SelectedPoly = (RealProperty)RealPropertyCollection.SelectedItem;

  //Display the data
  Console.WriteLine("Owner Name: " + SelectedPoly.OwnerName);
  Console.WriteLine("Area: " + SelectedPoly.Area);
  Console.WriteLine("MarketValue : " + SelectedPoly.MarketValue );
};

Вы можете получить ответ по следующей ссылке

Нажмите [здесь] ( https://github.com/radioman/greatmaps)

Следите за CustomMarkerDemo.xaml.cs и добавьте это в свою программу. Этот пользовательский маркер имеет требуемое событие клика.

Ну если нет Click событие, вам придется справиться MouseDown + MouseUp обнаруживать щелчки. Просто храните e.Position в MouseDown, И в MouseUpсравните, чтобы убедиться, что мышь практически не двигается:

private Point downPoint;

private void OnMouseDown(object sender, MouseButtonEventArgs e)
{
    downPoint = e.Position;
}

private void OnMouseUp(Object sender, MouseButtonEventArgs e)
{
    if (Math.Abs(downPoint.X - e.Position.X) < SystemParameters.MinimumHorizontalDragDistance &&
        Math.Abs(downPoint.Y - e.Position.Y) < SystemParameters.MinimumVerticalDragDistance)
    {
        HandleClick(sender, e);
    }
}

Вам нужно сделать что-то подобное для поддержки стилуса и сенсорного ввода.

Другие вопросы по тегам