<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>draw Archive - Robert Skibbe</title>
	<atom:link href="https://robbelroot.de/blog/tag/draw/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>alias RobbelRoot – Freelance Full Stack Developer .NET</description>
	<lastBuildDate>Mon, 28 Jun 2021 01:52:42 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://robbelroot.de/wp-content/uploads/2020/12/cropped-favicon-32x32.png</url>
	<title>draw Archive - Robert Skibbe</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>VB.NET Timer Countdown</title>
		<link>https://robbelroot.de/blog/vbnet-timer-countdown/</link>
					<comments>https://robbelroot.de/blog/vbnet-timer-countdown/#comments</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Mon, 28 Jun 2021 01:20:02 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Visual Basic .NET]]></category>
		<category><![CDATA[Visual Basic .NET Problemlösungen]]></category>
		<category><![CDATA[animieren]]></category>
		<category><![CDATA[cinema]]></category>
		<category><![CDATA[count]]></category>
		<category><![CDATA[countdown]]></category>
		<category><![CDATA[down]]></category>
		<category><![CDATA[draw]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[gdi]]></category>
		<category><![CDATA[gdi plus]]></category>
		<category><![CDATA[gdi+]]></category>
		<category><![CDATA[herunterzählen]]></category>
		<category><![CDATA[paint]]></category>
		<category><![CDATA[runterzählen]]></category>
		<category><![CDATA[timer]]></category>
		<category><![CDATA[vb.net]]></category>
		<category><![CDATA[wiederholen]]></category>
		<category><![CDATA[zählen]]></category>
		<category><![CDATA[zahlen]]></category>
		<category><![CDATA[zeichnen]]></category>
		<category><![CDATA[zeitgeber]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=2361</guid>

					<description><![CDATA[<p>VB.NET Timer Countdown Du fragst Dich, wie Du in VB.NET einen Timer Countdown erstellen kannst? Lerne in diesem Beitrag wie! Falls Du noch gar nichts über das Timer-Control weißt, empfehle ich Dir, meinen allgemeinen Beitrag über das VB.NET Timer Steuerlement anzusehen. Ergänzend dazu habe ich auch noch einen weiteren Beitrag &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-timer-countdown/">VB.NET Timer Countdown</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><a href="https://robbelroot.de/wp-content/uploads/2021/06/VB.NET-Timer-countdown.png"><img fetchpriority="high" decoding="async" width="1024" height="536" src="https://robbelroot.de/wp-content/uploads/2021/06/VB.NET-Timer-countdown-1024x536.png" alt="VB.NET Timer Countdown" class="wp-image-2362" srcset="https://robbelroot.de/wp-content/uploads/2021/06/VB.NET-Timer-countdown-1024x536.png 1024w, https://robbelroot.de/wp-content/uploads/2021/06/VB.NET-Timer-countdown-300x157.png 300w, https://robbelroot.de/wp-content/uploads/2021/06/VB.NET-Timer-countdown-768x402.png 768w, https://robbelroot.de/wp-content/uploads/2021/06/VB.NET-Timer-countdown-700x366.png 700w, https://robbelroot.de/wp-content/uploads/2021/06/VB.NET-Timer-countdown-332x174.png 332w, https://robbelroot.de/wp-content/uploads/2021/06/VB.NET-Timer-countdown.png 1200w" sizes="(max-width: 1024px) 100vw, 1024px" /></a><figcaption>VB.NET Timer Countdown</figcaption></figure>






<h2 class="wp-block-heading">VB.NET Timer Countdown</h2>



<p>Du fragst Dich, wie Du in <strong>VB.NET einen Timer Countdown</strong> erstellen kannst? Lerne <strong>in diesem Beitrag</strong> wie!</p>



<p><strong>Falls Du</strong> <strong>noch </strong>gar <strong>nichts </strong>über das <strong>Timer-Control</strong> weißt, <strong>empfehle </strong>ich Dir, meinen allgemeinen <a href="https://robbelroot.de/blog/vbnet-timer-beispiel-code-im-intervall-ausfuehren/" target="_blank" rel="noreferrer noopener"><strong>Beitrag über das VB.NET Timer Steuerlement</strong></a> anzusehen.</p>



<p><strong>Ergänzend</strong> dazu habe ich auch noch einen <strong>weiteren </strong><a href="https://robbelroot.de/blog/vb-net-timer-zur-laufzeit-erstellen/" target="_blank" rel="noreferrer noopener"><strong>Beitrag über die dynamische Erstellung eines Timers</strong></a> zur <strong>Laufzeit </strong>geschrieben.</p>



<h2 class="wp-block-heading">Vorschau – VB.NET Timer Countdown</h2>



<p>Hier drunter siehst Du, wie <strong>die Umsetzung eines Countdowns</strong> zum Beispiel aussehen könnte.</p>



<figure class="wp-block-image size-large"><a href="https://robbelroot.de/wp-content/uploads/2021/06/VB.NET-Timer-Countdown.gif"><img decoding="async" width="297" height="215" src="https://robbelroot.de/wp-content/uploads/2021/06/VB.NET-Timer-Countdown.gif" alt="VB.NET Timer Countdown gif" class="wp-image-2368"/></a><figcaption>VB.NET Timer Countdown gif</figcaption></figure>



<h2 class="wp-block-heading">Das erste Beispiel – auf einer Form mit Label</h2>



<p>Ich denke <strong>als erstes</strong> und beliebtestes <strong>Beispiel</strong>, kommt einem die <strong>Umsetzung auf einer Form</strong> in den Sinn.</p>



<p>Daher <strong>machen </strong>wir es uns <strong>einfach </strong>und <strong>beginnen </strong>direkt damit &#x1f60a;!</p>



<p><strong>Alles was Du</strong> dafür letztendlich <strong>brauchst</strong>, hast du <strong>mit wenigen Handgriffen</strong> zusammengeklickt!</p>



<h3 class="wp-block-heading" id="beispiel-1-steuerelemente">Benötigte Steuerelemente</h3>



<h4 class="wp-block-heading">Form</h4>



<p>Wir haben uns hierbei entschieden, den <strong>Countdown auf einer Form darzustellen</strong>, <strong>daher brauchen </strong>wir natürlich <strong>eine Form</strong>.</p>



<h4 class="wp-block-heading">Timer</h4>



<p>Für <strong>dieses Beispiel</strong> brauchen wir selbstverständlich <strong>einen Timer</strong>, wer hätte das gedacht.. Zack, rauf <strong>auf die Form</strong>, <strong>oder im Code der Klasse</strong> als <strong>WithEvents Variable</strong>/<strong>Eigenschaft </strong>deklariert – wie Du möchtest.</p>



<p>Hier habe ich den <strong>Timer </strong>übrigens <strong>tmrCountdown genannt</strong>, Du solltest natürlich <strong>auch </strong>einen <strong>vernünftigeren Namen</strong> als &#8222;Timer1&#8220; <strong>wählen </strong>&#x1f609;!</p>



<h4 class="wp-block-heading">Label</h4>



<p><strong>Zu guter Letzt</strong> hatten wir geplant, den <strong>Countdown </strong>selbst – also die <strong>Zahlen </strong>– <strong>in </strong>einem <strong>Label darzustellen</strong>. <strong>Ziehe </strong>daher ein <strong>Label auf die Form</strong>.</p>



<p><strong>Auch </strong>dem <strong>Label </strong>wurde ein <strong>aussagekräftigerer Name</strong> als &#8222;Label1&#8220; <strong>verpasst</strong>. Hier <strong>habe </strong>ich das <strong>Label </strong>&#8222;<strong>lblNumber</strong>&#8220; <strong>genannt</strong>.</p>



<h3 class="wp-block-heading" id="beispiel-1-styling-der-komponenten">Styling der Komponenten</h3>



<p>Im <strong>folgenden Schritt</strong> kümmern wir uns ein wenig um das <strong>Styling der Controls</strong>, auch wenn wir hier natürlich keine Spiel-like-Grafik haben werden, kann es ja <strong>zumindest ein wenig &#8222;schöner&#8220;</strong> werden.</p>



<h4 class="wp-block-heading">Die Form stylen</h4>



<p>Um <strong>das Ganze </strong>ein wenig <strong>sichtbarer </strong>zu <strong>gestalten</strong>, nehmen wir uns zuerst die <strong>Eigenschaften der Form</strong> vor.</p>



<p>Ich würde vorschlagen, die <strong>Eigenschaft </strong>&#8222;<strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.form.startposition?view=net-5.0" target="_blank" rel="noreferrer noopener">StartPosition</a></strong>&#8220; der Form auf &#8222;<strong>CenterScreen</strong>&#8220; zu stellen.</p>



<p>Wie der Name schon sagt, wird die <strong>Form </strong>so <strong>standardmäßig zentriert auf dem Bildschirm</strong> angezeigt.</p>



<p>Die <strong>Hintergrundfarbe der Form</strong>, also die &#8222;<strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.form.backcolor?view=net-5.0" target="_blank" rel="noreferrer noopener">BackColor</a></strong>&#8220; habe ich <strong>auf </strong>&#8222;<strong>Black</strong>&#8220; gestellt. So haben wir einen <strong>guten Kontrast</strong>, <strong>Welcher </strong>irgendwie <strong>an ein Kino erinnert</strong>.</p>



<p>Für die <strong><a href="https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.form.size?view=net-5.0" target="_blank" rel="noreferrer noopener">Größe der Form</a></strong> habe ich <strong>189&#215;253</strong> gewählt, ist natürlich auch Dir überlassen!</p>



<h4 class="wp-block-heading">Die Anzeige in einem Label</h4>



<p>Wir <strong>verpassen </strong>dem <strong>Label </strong>eine <strong>ausreichende Größe</strong>, also so ungefähr eine <strong>Font-Größe von 120</strong>.</p>



<p>Anschließend habe ich mich für die <strong>Schriftart Consolas</strong> entschieden, Welche übrigens die <strong>Standard-Schrift von Visual Studio</strong> ist.</p>



<p><strong>Zuletzt </strong>bekommt das <strong>Label </strong>die <strong><a href="https://docs.microsoft.com/de-de/office/vba/api/access.label.forecolor" target="_blank" rel="noreferrer noopener">Schriftfarbe</a> </strong>&#8222;White&#8220;, um den oben angesprochenen <strong>Kontrast </strong>zu bekommen.</p>



<h3 class="wp-block-heading">Der Code</h3>



<p>Im n<strong>ächsten Abschnitt</strong> kommen wir <strong>zu dem Code</strong>, den wir benötigen um das <strong>VB.NET Timer Countdown Beispiel</strong> zum Laufen zu bekommen.</p>



<h4 class="wp-block-heading">Das Timer Tick-Ereignis</h4>



<p><strong>Zuerst </strong>nehmen wir das <strong>Tick-Ereignis des Timers</strong> – <strong>klicke </strong>z. B. <strong>doppelt auf </strong>den <strong>Timer</strong>, <strong>oder wähle </strong>das <strong>Ereignis über Designer </strong>und Co. aus:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Sub tmrCountdown_Tick(sender As Object, e As EventArgs) Handles tmrCountdown.Tick
    Dim currentNumber = Convert.ToInt32(lblNumber.Text)
    Dim countDownFinished = currentNumber = 0
    If countDownFinished Then
        tmrCountdown.Stop()
        MessageBox.Show("Countdown finished")
        Return
    End If
    currentNumber -= 1
    lblNumber.Text = currentNumber.ToString()
End Sub</pre>



<h4 class="wp-block-heading">FormClosing-Ereignis – sauber schließen</h4>



<p>Um die <strong>Form sauber zu schließen</strong>, sprich die <strong>Arbeit vorher korrekt zu beenden</strong>, fügen wir <strong>folgenden Ereignishandler hinzu</strong>.</p>



<p>Dieser <strong>sorgt dafür</strong>, <strong>dass </strong>der <strong>Timer </strong>beim Schließen der Form <strong>gestoppt </strong>wird.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        tmrCountdown.Stop()
    End Sub</pre>



<p><strong>Auch wenn</strong> der <strong>Timer </strong>vermutlich <strong>durch </strong>die <strong>Assoziation </strong>zur Form (wenn man Ihn per Drag &amp; Drop auf die Form zieht) <strong>automatisch disposed </strong>wird, ist <strong>ein Gedanke daran nicht verkehrt</strong>.</p>



<p>Denn <strong>auch in Zukunft</strong> sollte man <strong>solche Sachen</strong> nach Möglichkeit <strong>bedenken</strong>, um z. B. potentielle <strong><a href="https://de.wikipedia.org/wiki/Speicherleck" target="_blank" rel="noreferrer noopener">Memory-Leaks</a></strong>, etc. <strong>zu vermeiden</strong>.</p>



<h4 class="wp-block-heading">Den Countdown starten</h4>



<p>Ich habe mich dazu entschieden, den <strong>Timer durch </strong>einen <strong>Klick auf</strong> das <strong>Label starten </strong>zu lassen.</p>



<p><strong>Auch hierzu </strong>kann man einen <strong>Doppelklick auf </strong>das <strong>Label </strong>machen, <strong>oder über</strong> den <strong>Designer arbeiten</strong>.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Sub lblNumber_Click(sender As Object, e As EventArgs) Handles lblNumber.Click
    tmrCountdown.Start()
End Sub</pre>



<p><strong>Wenn </strong>man <strong>möchte</strong>, <strong>dass </strong>der <strong>Timer </strong>beim Start des Programms <strong>sofort loslegt</strong>, <strong>kann </strong>statt dem vorherigen Code natürlich auch <strong>die <a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.timer.enabled?view=net-5.0" target="_blank" rel="noreferrer noopener">Enabled-Eigenschaft</a></strong> des Timers bereits <strong>im Designer auf True</strong> <strong>stellen</strong>.</p>



<h2 class="wp-block-heading">VB.NET Timer Countdown die Zweite – auf einer Form mit GDI+</h2>



<p><strong>Im zweiten</strong> zwar etwas <strong>schwierigeren</strong>, <strong>jedoch interessanteren Beispiel</strong>, schauen wir uns <strong>das Zeichnen des Countdowns mit GDI+</strong> an.</p>



<p>Dies <strong>wäre zum Beispiel nützlich</strong>, <strong>wenn Du </strong>vorhast ein <strong>eigenes kleines Spiel</strong> mit VB.NET zu <strong>entwickeln</strong>.</p>



<p><strong>Hier kümmern </strong>wir uns <strong>nun selbst</strong> um <strong>das Zeichnen</strong> des <strong>Countdowns</strong>, <strong>statt </strong>Ihn <strong>durch </strong>ein <strong>Label </strong>darzustellen.</p>



<h3 class="wp-block-heading">Benötigte Steuerelemente</h3>



<p><strong>Statt </strong>wie bei den <strong><a href="#beispiel-1-steuerelemente">Steuerelementen des ersten Beispiels</a></strong> ein <strong>Label </strong>zu verwenden, <strong>verzichten</strong> wir hier <strong>darauf</strong>. Wir <strong>übernehmen </strong>die <strong>Darstellung </strong>des <strong>Countdowns </strong>mit GDI+ und zeichnen <strong>selbst</strong>.</p>



<h3 class="wp-block-heading">Styling der Komponenten</h3>



<p>Hier verfahren wir ähnlich <a href="#beispiel-1-styling-der-komponenten">wie oben</a>, <strong>daher </strong>ist es <strong>kein </strong>großer <strong>Mehraufwand</strong>.</p>



<h3 class="wp-block-heading">Der Code</h3>



<h4 class="wp-block-heading">3 Eigenschaften kommen in der Form hinzu</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Public Property CurrentNumber As Integer
Public Property CountdownFont As Font
Public Property CountdownBrush As Brush</pre>



<p>Mir <strong>ist an dieser Stelle wichtig</strong>, die <strong>Eigenschaften</strong> <strong>im Konstruktor</strong> nur <strong>ein einziges Mal zuzuweisen</strong> und <strong>anschließend nur noch abrufen</strong> zu müssen.</p>



<p>Bei <strong>vielerlei Code</strong> der so im Netz tummelt, stellt man fest, dass <strong>vor Allem Anfänger</strong>, &#8222;<strong>faulere </strong>Leute&#8220; und die &#8222;<strong>Copy &amp; Paster</strong>&#8220; in <strong>jedem Durchlauf </strong>z. B. die <strong>Instanz des Fonts, usw.</strong> immer wieder <strong>neu erstellen </strong>– ein Graus..</p>



<p>Ein <strong>ressourceneffizientes arbeiten</strong> ist <strong>für mich</strong> persönlich <strong>sehr wichtig</strong>, <strong>auch wenn </strong>man freilich <strong>nicht immer</strong> an <strong>alles denken </strong>kann..</p>



<h5 class="wp-block-heading">CurrentNumber</h5>



<p>Die <strong>CurrentNumber stellt </strong>wie der Name schon sagt unsere <strong>aktuelle Countdown-Zahl</strong> dar.</p>



<p><strong>Da wir</strong> in diesem Beispiel ja <strong>nicht mehr</strong> den <strong>Inhalt des Labels</strong> als Zwischenspeicher der Zahl <strong>missbrauchen</strong> können, ist <strong>dies</strong> eine der <strong>richtigen Alternativen</strong>.</p>



<p><strong>Zum einen</strong> <strong>erleichtert </strong>die <strong>klassenweite Deklaration </strong>den <strong>Zugriff aus</strong> verschiedenen <strong>Methoden </strong>und <strong>zum anderen</strong> <strong>fühlt </strong>sich die <strong>Assoziation zur Form </strong>hier <strong>richtig an</strong>.</p>



<h5 class="wp-block-heading">CountdownFont</h5>



<p>Mit <strong>dieser Eigenschaft</strong> bestimmen wir den <strong>Font des Countdowns</strong>.</p>



<p><strong>Hier </strong>gilt es zu <strong>beachten</strong>, <strong>dass </strong>ein <strong>Font nicht </strong>schlichtweg <strong>nur </strong>den <strong>Namen </strong>des Fonts, <strong>sondern </strong>auch <strong>Styling-Informationen</strong> wie <strong>Größe </strong>und <strong>Stärke</strong>/Dicke enthält.</p>



<p><strong>Wie im vorherigen Beispiel</strong> habe ich die <strong>Schriftart </strong>bei <strong>Consolas </strong>und die <strong>Größe </strong>bei <strong>120 </strong>belassen.</p>



<p><strong>Hier </strong>habe ich <strong>auch wie oben</strong> den &#8222;<strong>FontStyle</strong>&#8220; auf dick, also auf &#8222;<strong>Bold</strong>&#8220; gesetzt.</p>



<h5 class="wp-block-heading">CountdownBrush</h5>



<p>Der <strong>Brush ist </strong>sozusagen die <strong>Farbe </strong>die wir <strong>für </strong>den <strong>selbst gezeichneten Countdown</strong> verwenden.</p>



<p>Wir <strong>verwenden </strong>auch hier die <strong>Farbe &#8222;White&#8220;</strong>, indem wir auf <strong>Brushes.White</strong> zugreifen.</p>



<h4 class="wp-block-heading">Konstruktor</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Sub New()
    InitializeComponent()
    DoubleBuffered = True
    CurrentNumber = 5
    CountdownFont = New Font("Consolas", 120, FontStyle.Bold)
    CountdownBrush = Brushes.White
End Sub</pre>



<p><strong>Im Konstruktor</strong> <strong>weisen </strong>wir <strong>einmalig alles </strong>zu, <strong>was </strong>wir <strong>für unsere Arbeit brauchen</strong>.</p>



<p><strong>Natürlich </strong>ist die <strong>CurrentNumber </strong>hier eine <strong>Ausnahme</strong>, da <strong>diese </strong>sich ja <strong>durch </strong>den <strong>Countdown verändern </strong>wird.</p>



<p><strong>Neu könnte</strong> für Dich hier ggf. die Eigenschaft namens <a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.control.doublebuffered?view=net-5.0" target="_blank" rel="noreferrer noopener"><strong>DoubleBuffered</strong></a> <strong>sein</strong>.</p>



<p><strong>An dieser Stelle reicht</strong> denke ich die <strong>Erklärung</strong>, <strong>dass </strong>die Eigenschaft das eventuelle <strong>Flackern der Form</strong> beim Zeichnen <strong>ein wenig besser</strong> in den Griff bekommt.</p>



<h4 class="wp-block-heading">Das Zeichnen des Countdowns mit GDI+</h4>



<p>&#8222;Das <strong>Beste kommt zum Schluss</strong>&#8222;, heißt es doch immer so schön!</p>



<p><strong>Nun </strong>kommen wir zum <strong>Code</strong>, der <strong>für das Zeichnen des Countdowns</strong> verantwortlich ist.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    Dim numberString = CurrentNumber.ToString()
    Dim numberStringSize = e.Graphics.MeasureString(numberString, CountdownFont)
    Dim centerX = (ClientRectangle.Width / 2) - (numberStringSize.Width / 2)
    Dim centerY = (ClientRectangle.Height / 2) - (numberStringSize.Height / 2)
    Dim centerOfForm = New Point(centerX, centerY)
    e.Graphics.DrawString(numberString, CountdownFont, CountdownBrush, centerOfForm)
End Sub</pre>



<p><strong>Statt </strong>hier &#8222;<strong>Schlampi-Pampi</strong>&#8220; mit der Nummer – also dem Integer – zu hantieren, <strong>wandeln wir </strong>Diese <strong>natürlich</strong> vor Gebrauch <strong>in einen String</strong> namens &#8222;numberString&#8220; <strong>um</strong>.</p>



<p><strong>Danach </strong>können wir <strong>durch das Graphics-Objekt</strong>, Welches uns <strong>durch die PaintEventArgs</strong> <strong>bereitgestellt </strong>wird, die <strong>Größe des </strong>resultierenden <strong>Strings messen</strong>.</p>



<p>Im <strong>darauffolgenden Schritt</strong> <strong>bestimmen </strong>wir jeweils die <strong>horizontale und die vertikale Mitte der Form</strong> und <strong>erstellen </strong>eine neue <strong>Instanz </strong>des <strong>Point-Datentyps</strong> – praktisch unsere <strong>2D-Koordinaten</strong>.</p>



<p><strong>Final </strong>können wir <strong>die Zahl</strong> auf die Form bringen, <strong>indem </strong>wir die &#8222;<strong>DrawString</strong>&#8222;-<strong>Methode </strong>des <strong>e.Graphics Objekts</strong> aufrufen.</p>



<p><strong>Diese möchte </strong>natürlich alle vorher bestimmten <strong>Daten wie </strong>den <strong>zu zeichnenden String</strong>, den <strong>Font</strong>, einen <strong>Brush </strong>und <strong>letztendlich </strong>die <strong>Koordinaten </strong>wo das Ganze landen soll haben.</p>



<h4 class="wp-block-heading">Der erste Startversuch</h4>



<p><strong>Wenn </strong>Du <strong>nun </strong>einmal <strong>F5 drückst</strong>, <strong>oder </strong>das <strong>Programm via </strong>Visual Studios &#8222;<strong>Play Knopf</strong>&#8220; <strong>ins Debugging</strong> schickst, <strong>siehst </strong>Du unsere <strong>Zahl &#8222;5&#8220;</strong>.</p>



<p><strong>Leider geht </strong>es aber <strong>nicht weiter</strong>.. Warum? Naja <strong>der Timer</strong>, Welcher unsere Zahl runterzählt <strong>fehlt </strong>&#x1f609;.</p>



<p>Auch haben wir <strong>aktuell das Problem</strong>, <strong>dass </strong>die <strong>Zahl verschwindet</strong>, <strong>wenn </strong>Du die <strong>Größe der Form</strong> beim Debugging <strong>veränderst </strong>– probiere es ruhig mal aus!</p>



<figure class="wp-block-image size-large" id="gezeichnete-zahl-verschwindet"><a href="https://robbelroot.de/wp-content/uploads/2021/06/VB.NET-Timer-Countdown-verschwindet-GDI.gif"><img decoding="async" width="316" height="278" src="https://robbelroot.de/wp-content/uploads/2021/06/VB.NET-Timer-Countdown-verschwindet-GDI.gif" alt="VB.NET Timer Countdown verschwindet GDI" class="wp-image-2425"/></a><figcaption>VB.NET Timer Countdown verschwindet GDI</figcaption></figure>



<h4 class="wp-block-heading">Die verlorene Zahl</h4>



<p>Unsere <strong>Zahl verschwindet</strong> einem <strong>aus </strong>einem besonders für Anfänger <strong>nicht direkt ersichtlichen Grund</strong>.</p>



<p><strong>Aktuell zeichnen wir </strong>die Zahl <strong>nur </strong>dann (neu), <strong>wenn </strong>die <strong>Form </strong>ihr <strong>Paint-Ereignis</strong> ausgibt.</p>



<p><strong>Am Anfang</strong> ist die Zahl klar <strong>sichtbar</strong>, <strong>weil </strong>die <strong>Form </strong>dieses <strong>Ereignis </strong>ein Mal <strong>bei Start </strong>der Anwendung <strong>ausgibt</strong>.</p>



<p><strong>Um </strong>das <strong>zu prüfen</strong>, <strong>könntest </strong>Du <strong>ja </strong>zum Beispiel eine <strong>kleine Ausgabe</strong>, <strong>oder </strong>einen <strong>Debug-Schritt</strong> hinzufügen:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Debug.WriteLine("PAINT")</pre>



<h4 class="wp-block-heading">Invalidate zur Rettung</h4>



<p>Wir <strong>müssen nun</strong> also irgendwie <strong>dafür sorgen</strong>, <strong>dass </strong>die <strong>Form </strong>ihr <strong>Paint-Ereignis</strong> <strong>öfter ausgibt</strong> und <strong>somit </strong>das <strong>Zeichnen </strong>der Zahl <strong>anweisen</strong>.</p>



<p>Man <strong>könnte jetzt</strong> natürlich <strong>mit </strong>der <strong>Brechstange kommen </strong>und <strong>sowas wie</strong> eine <strong><a href="https://de.wikipedia.org/wiki/Game_Loop" target="_blank" rel="noreferrer noopener">Game Loop</a></strong> hinzufügen.</p>



<p><strong>Anderweitig</strong>, jedoch genauso heavy <strong>könnte man </strong>auch einen <strong>Timer verwenden</strong> <strong>und </strong>der <strong>Form im </strong>geringen <strong>Intervall sagen</strong>: &#8222;Hey, <strong>zeichne dich neu</strong>!&#8220;.</p>



<p><strong>Um </strong>der <strong>Form mitzuteilen</strong>, <strong>dass </strong>Sie <strong>sich</strong>, <strong>oder </strong>zumindest gewisse <strong>Bereiche neu zeichnen</strong> – also <strong>invalidieren </strong>– soll, können wir <strong>mit </strong>der <strong>Methode </strong>&#8222;<strong>Invalidate</strong>&#8220; erreichen.</p>



<h4 class="wp-block-heading">Wenn nicht jetzt, wann dann – löl?</h4>



<p><strong>Auch hier bitte</strong> ich wieder um den Schritt zurück, um <strong>zu überlegen</strong>: &#8222;<strong>Wann </strong>genau <strong>brauche ich </strong>denn eine <strong>Aktualisierung </strong>der Zeichnung&#8220;.</p>



<p><a href="#gezeichnete-zahl-verschwindet">Oben im Gif-Bild</a> <strong>konnten </strong>wir <strong>erkennen</strong>, dass es offensichtlich <strong>nach </strong>einer <strong>Größenveränderung </strong>der Form von Nöten wäre.</p>



<p><strong>Somit </strong>hätten wir <strong>auch direkt </strong>die <strong>Maximierung der Form</strong> mit <strong>abgearbeitet</strong>, denn <strong>auch da verändert</strong> Sie ihre <strong>Größe</strong>.</p>



<p><strong>Fügen </strong>wir also folgenden &#8222;Resize&#8220;-<strong>Ereignishandler hinzu</strong>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles Me.Resize
    Invalidate()
End Sub</pre>



<p><strong>Schon </strong>ist unser <strong>Problem behoben</strong>:</p>



<figure class="wp-block-image size-large"><a href="https://robbelroot.de/wp-content/uploads/2021/06/VB.NET-Timer-Countdown-GDI-bleibt.gif"><img loading="lazy" decoding="async" width="316" height="278" src="https://robbelroot.de/wp-content/uploads/2021/06/VB.NET-Timer-Countdown-GDI-bleibt.gif" alt="VB.NET Timer Countdown GDI bleibt" class="wp-image-2436"/></a><figcaption>VB.NET Timer Countdown GDI bleibt</figcaption></figure>



<h4 class="wp-block-heading">Der Countdown</h4>



<p><strong>Zu guter Letzt</strong> kommen wir zum <strong>Timer </strong>selbst, Welcher dafür <strong>verantwortlich </strong>ist, <strong>die Zahl herunterzuzählen</strong>.</p>



<p>Den <strong>Startschuss </strong>geben wir auch hier mit einem <strong>Klick-Ereignis</strong>, nur dieses mal das Ereignis <strong>der Form</strong>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Sub Form1_Click(sender As Object, e As EventArgs) Handles Me.Click
    tmrCountdown.Start()
End Sub</pre>



<p>Nun <strong>noch </strong>die paar <strong>Zeilen </strong>des Timer <strong>Tick-Ereignisses</strong> – nur<strong> dieses Mal ohne Label-Code</strong> – <strong>hinzufügen</strong>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Sub tmrCountdown_Tick(sender As Object, e As EventArgs) Handles tmrCountdown.Tick
    Dim countDownFinished = CurrentNumber = 0
    If countDownFinished Then
        tmrCountdown.Stop()
        MessageBox.Show("Countdown finished")
        Return
    End If
    CurrentNumber -= 1
    Invalidate()
End Sub</pre>



<p>Hier <strong>daran denken</strong>, dass <strong>auch nach </strong>der <strong>Änderung </strong>der &#8222;<strong>CurrentNumber</strong>&#8220; ein &#8222;<strong>Invalidate</strong>&#8220; passieren sollte, <strong>damit </strong>unsere <strong>gezeichnete Zahl aktualisiert </strong>wird.</p>



<p><strong>Fertig </strong>&#x1f604;!</p>



<h2 class="wp-block-heading">Downloads</h2>



<div class="wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button"><a class="wp-block-button__link" href="/downloads/vbnet/TimerCountdown.zip" target="_blank" rel="noreferrer noopener">Example 1 – on Form with Label</a></div>



<div class="wp-block-button"><a class="wp-block-button__link" href="/downloads/vbnet/TimerCountdownGdi.zip" target="_blank" rel="noreferrer noopener">Example 2 – on Form with GDI+</a></div>
</div>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-timer-countdown/">VB.NET Timer Countdown</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vbnet-timer-countdown/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
