使用内部计时器

时间:2018-01-18 13:45:03

标签: c# winforms gmap.net

我有一个自定义的GMapMarker类绘制一个简单的图像来映射...如何使该图像在500毫秒的间隔内改变其属性(假设闪烁)?

使用GMapControl.Invalidate()将重绘我的标记和整个地图!这将导致不受管制的闪烁,因为每次更改map属性时都会调用OnRedraw()方法! (当地图处于空闲状态时,不会调用此方法!)

我的解决方案需要在我的示例中使用内部Timer,但不知道如何从Timer经过时间的功能中重绘我的图像。

namespace GMap.NET.WindowsForms.Markers {
public class GMarkerNode : GMapMarker {

    public Image Image { get; set; }
    private Timer Timer;

    public GMarkerNode(PointLatLng p) : base(p)
    {
        Timer = new Timer()
        {
            AutoReset = true,
            Interval = 500
        };
        Timer.Elapsed += Timer_Elapsed;
        Timer.Start();
    }

    private void Timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        // How to triger OnRender or invalidate marker graphics?
    }

    public override void OnRender(Graphics g)
    {
        g.DrawImage(Image, LocalPosition);
    }

    public override void Dispose()
    {
        base.Dispose();
    }
}

}

1 个答案:

答案 0 :(得分:0)

您不需要在Marker类中直接使用计时器,因为它处理GDI,它在每次地图交互时从OnRender方法渲染标记图像。

因此,您可以从Marker类中删除计时器,并从放置GMapControl的Main表单中设置标记的image属性。

我为您创建了一个演示项目,演示了我的答案: 注意:使用的图像是我从谷歌获得的,所以你可以使用任何图像,或者你可以使用2张图像(黑色,白色)并在它们之间交换以产生闪烁效果。

您可以从以下链接免费下载演示项目:

<强> Download Demo Project

**The final result:**

<强> GMarkerNode.vb:

Imports GMap.NET
Imports GMap.NET.WindowsForms

Public Class GMarkerNode
    Inherits GMapMarker

    Public Property Image() As Image

    Public Sub New(ByVal p As PointLatLng, ByVal image1  As Image)
        MyBase.New(p)
        Me.Image=image1
    End Sub

    Public Overrides Sub OnRender(ByVal g As Graphics)
        if me.Image IsNot Nothing Then
            g.DrawImage(me.Image, LocalPosition)
        End If          
    End Sub

    Public Overrides Sub Dispose()
        MyBase.Dispose()
    End Sub
End Class

<强> Form1.vb的:

Imports System.IO
Imports GMap.NET
Imports GMap.NET.MapProviders
Imports GMap.NET.WindowsForms

Public Class Form1
    Private m_Index As Integer=1
    Private m_ImagePath As String=""
    Private m_ActiveMarker As GMarkerNode
    Private m_ActiveImage As Image
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        with GMapControl1
            .Manager.Mode = AccessMode.ServerAndCache
            .CacheLocation = Path.Combine(Application.StartupPath,"cache")
            .MapProvider = GMapProviders.OpenStreetMap
            .Position = new PointLatLng(30.050578, 31.223027)
            .Zoom = 15
            .Overlays.Add(new GMapOverlay("markersOverlay"))
            .Overlays(0).Markers.Add(new GMarkerNode(.Position,Pic.Image))
        End With
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Timer1.Enabled=Not Timer1.Enabled
        Timer1.Interval= Math.Abs(CInt(IIf(IsNumeric(txtInterval.Text), txtInterval.Text,500)))
        If Timer1.Enabled Then
            Button1.Text="Stop"
        else    
            Button1.Text="Start"
        End If
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        m_ImagePath = Path.Combine(Application.StartupPath,"images",String.Format("black{0:D2}.png",m_Index))
        if File.Exists(m_ImagePath) Then
            m_ActiveImage = Image.FromFile(m_ImagePath)
            Pic.Image =m_ActiveImage

            '   Update the marker image
            m_ActiveMarker = GMapControl1.Overlays(0).Markers(0)
            m_ActiveMarker.Image = Pic.Image

            '   Update the marker in the overlay
            GMapControl1.Overlays(0).Markers(0) = m_ActiveMarker 
        End If
        If m_Index<100 Then
            m_Index += 1
        Else 
            m_Index = 1
        End If
    End Sub

End Class

<强> Form1.Designer.vb:

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class Form1
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container()
        Me.GMapControl1 = New GMap.NET.WindowsForms.GMapControl()
        Me.SplitContainer1 = New System.Windows.Forms.SplitContainer()
        Me.Label2 = New System.Windows.Forms.Label()
        Me.Pic = New System.Windows.Forms.PictureBox()
        Me.Label1 = New System.Windows.Forms.Label()
        Me.txtInterval = New System.Windows.Forms.TextBox()
        Me.Button1 = New System.Windows.Forms.Button()
        Me.Timer1 = New System.Windows.Forms.Timer(Me.components)
        CType(Me.SplitContainer1,System.ComponentModel.ISupportInitialize).BeginInit
        Me.SplitContainer1.Panel1.SuspendLayout
        Me.SplitContainer1.Panel2.SuspendLayout
        Me.SplitContainer1.SuspendLayout
        CType(Me.Pic,System.ComponentModel.ISupportInitialize).BeginInit
        Me.SuspendLayout
        '
        'GMapControl1
        '
        Me.GMapControl1.Bearing = 0!
        Me.GMapControl1.CanDragMap = true
        Me.GMapControl1.Dock = System.Windows.Forms.DockStyle.Fill
        Me.GMapControl1.EmptyTileColor = System.Drawing.Color.Navy
        Me.GMapControl1.GrayScaleMode = false
        Me.GMapControl1.HelperLineOption = GMap.NET.WindowsForms.HelperLineOptions.DontShow
        Me.GMapControl1.LevelsKeepInMemmory = 5
        Me.GMapControl1.Location = New System.Drawing.Point(0, 0)
        Me.GMapControl1.MarkersEnabled = true
        Me.GMapControl1.MaxZoom = 20
        Me.GMapControl1.MinZoom = 2
        Me.GMapControl1.MouseWheelZoomEnabled = true
        Me.GMapControl1.MouseWheelZoomType = GMap.NET.MouseWheelZoomType.MousePositionAndCenter
        Me.GMapControl1.Name = "GMapControl1"
        Me.GMapControl1.NegativeMode = false
        Me.GMapControl1.PolygonsEnabled = true
        Me.GMapControl1.RetryLoadTile = 0
        Me.GMapControl1.RoutesEnabled = true
        Me.GMapControl1.ScaleMode = GMap.NET.WindowsForms.ScaleModes.[Integer]
        Me.GMapControl1.SelectedAreaFillColor = System.Drawing.Color.FromArgb(CType(CType(33,Byte),Integer), CType(CType(65,Byte),Integer), CType(CType(105,Byte),Integer), CType(CType(225,Byte),Integer))
        Me.GMapControl1.ShowTileGridLines = false
        Me.GMapControl1.Size = New System.Drawing.Size(639, 556)
        Me.GMapControl1.TabIndex = 0
        Me.GMapControl1.Zoom = 0R
        '
        'SplitContainer1
        '
        Me.SplitContainer1.Dock = System.Windows.Forms.DockStyle.Fill
        Me.SplitContainer1.Location = New System.Drawing.Point(0, 0)
        Me.SplitContainer1.Name = "SplitContainer1"
        '
        'SplitContainer1.Panel1
        '
        Me.SplitContainer1.Panel1.Controls.Add(Me.Label2)
        Me.SplitContainer1.Panel1.Controls.Add(Me.Pic)
        Me.SplitContainer1.Panel1.Controls.Add(Me.Label1)
        Me.SplitContainer1.Panel1.Controls.Add(Me.txtInterval)
        Me.SplitContainer1.Panel1.Controls.Add(Me.Button1)
        '
        'SplitContainer1.Panel2
        '
        Me.SplitContainer1.Panel2.Controls.Add(Me.GMapControl1)
        Me.SplitContainer1.Size = New System.Drawing.Size(816, 556)
        Me.SplitContainer1.SplitterDistance = 173
        Me.SplitContainer1.TabIndex = 1
        '
        'Label2
        '
        Me.Label2.AutoSize = true
        Me.Label2.Location = New System.Drawing.Point(54, 31)
        Me.Label2.Name = "Label2"
        Me.Label2.Size = New System.Drawing.Size(70, 13)
        Me.Label2.TabIndex = 4
        Me.Label2.Text = "Active Image"
        '
        'Pic
        '
        Me.Pic.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle
        Me.Pic.Location = New System.Drawing.Point(52, 54)
        Me.Pic.Name = "Pic"
        Me.Pic.Size = New System.Drawing.Size(72, 65)
        Me.Pic.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage
        Me.Pic.TabIndex = 3
        Me.Pic.TabStop = false
        '
        'Label1
        '
        Me.Label1.AutoSize = true
        Me.Label1.Location = New System.Drawing.Point(21, 154)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(134, 13)
        Me.Label1.TabIndex = 2
        Me.Label1.Text = "Time Interval (miliseconds)"
        '
        'txtInterval
        '
        Me.txtInterval.Location = New System.Drawing.Point(45, 172)
        Me.txtInterval.Name = "txtInterval"
        Me.txtInterval.Size = New System.Drawing.Size(83, 20)
        Me.txtInterval.TabIndex = 1
        Me.txtInterval.Text = "500"
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(33, 211)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(107, 29)
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Start"
        Me.Button1.UseVisualStyleBackColor = true
        '
        'Timer1
        '
        Me.Timer1.Interval = 1000
        '
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6!, 13!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(816, 556)
        Me.Controls.Add(Me.SplitContainer1)
        Me.Name = "Form1"
        Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
        Me.Text = "Form1"
        Me.SplitContainer1.Panel1.ResumeLayout(false)
        Me.SplitContainer1.Panel1.PerformLayout
        Me.SplitContainer1.Panel2.ResumeLayout(false)
        CType(Me.SplitContainer1,System.ComponentModel.ISupportInitialize).EndInit
        Me.SplitContainer1.ResumeLayout(false)
        CType(Me.Pic,System.ComponentModel.ISupportInitialize).EndInit
        Me.ResumeLayout(false)

End Sub

    Friend WithEvents GMapControl1 As GMap.NET.WindowsForms.GMapControl
    Friend WithEvents SplitContainer1 As SplitContainer
    Friend WithEvents Label2 As Label
    Friend WithEvents Pic As PictureBox
    Friend WithEvents Label1 As Label
    Friend WithEvents txtInterval As TextBox
    Friend WithEvents Button1 As Button
    Friend WithEvents Timer1 As Timer
End Class