【问题标题】:How to respond to click event with GMap.net for WPF如何使用 GMap.net for WPF 响应点击事件
【发布时间】:2013-07-09 13:45:36
【问题描述】:

我正在编写一个使用 GMapControl 的 WPF 程序。我想允许用户点击地图并在用户点击的地方添加一个标记。我不想使用“MouseUp”和“MouseDown”事件,这样事件只会在用户实际单击地图并忽略拖放时被捕获。另外,我希望能够以同样的方式捕捉手写笔和触摸事件。我注意到没有“点击”事件。对于如何做到这一点,还有其他最佳做法吗?

谢谢,

【问题讨论】:

    标签: wpf c#-4.0 gmap.net


    【解决方案1】:

    似乎已经晚了,但我这样做的方式是创建一个集合,该集合将处理多边形到 MapControl 和事件的渲染。首先是创建一个可以扩展的多边形基类。

    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);
        }
    }
    

    然后创建一个集合,作为一个层来处理我们的多边形和它的事件。它的行为类似于具有SelectedItem 属性和SelectionChanged 事件的ListBoxListView

    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 BasePolygonList(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 );
    };
    

    【讨论】:

      【解决方案2】:

      您可以从以下链接获得答案

      点击[这里] (https://github.com/radioman/greatmaps)

      注意 CustomMarkerDemo.xaml.cs 并将其添加到您的程序中。此自定义标记具有您需要的点击事件。

      【讨论】:

        【解决方案3】:

        好吧,如果没有Click 事件,您将不得不处理MouseDown + MouseUp 来检测点击。只需将e.Position 存储在MouseDownMouseUp 中,进行比较以确保鼠标没有移动太多:

        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);
            }
        }
        

        您需要为触控笔和触控支持做类似的事情。

        【讨论】:

        • 谢谢,安倍。当然我可以实现我自己的某种点击,问题是试图避免在如此简单的任务中编写如此多的逻辑。一个按钮,有一个简单的点击(最近也被点击)事件,我想也许地图控件有同样的东西,因为它对地图控件非常有用。用户需要在地图上选择一个点的每一种情况都需要这样的事件,每个开发者都希望自己开发这样的事件似乎有点奇怪......
        • 嗯,它是一个开源项目......也许你可以将代码提交给项目,这样你就不必在代码中维护它了?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-30
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多