<?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>hinzufügen Archive - Robert Skibbe</title>
	<atom:link href="https://robbelroot.de/blog/tag/hinzufuegen/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>alias RobbelRoot – Freelance Full Stack Developer .NET</description>
	<lastBuildDate>Sat, 26 Feb 2022 10:52:24 +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>hinzufügen Archive - Robert Skibbe</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Ein VB NET DataGridView füllen</title>
		<link>https://robbelroot.de/blog/ein-vb-net-datagridview-fuellen/</link>
					<comments>https://robbelroot.de/blog/ein-vb-net-datagridview-fuellen/#comments</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Tue, 15 Feb 2022 18:00:58 +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[add]]></category>
		<category><![CDATA[bindinglist]]></category>
		<category><![CDATA[darstellen]]></category>
		<category><![CDATA[datagrid]]></category>
		<category><![CDATA[datagridview]]></category>
		<category><![CDATA[datasource]]></category>
		<category><![CDATA[daten]]></category>
		<category><![CDATA[datenquelle]]></category>
		<category><![CDATA[de]]></category>
		<category><![CDATA[deutsch]]></category>
		<category><![CDATA[füllen]]></category>
		<category><![CDATA[hinzufügen]]></category>
		<category><![CDATA[list]]></category>
		<category><![CDATA[quelle]]></category>
		<category><![CDATA[reihen]]></category>
		<category><![CDATA[rows]]></category>
		<category><![CDATA[tabellarisch]]></category>
		<category><![CDATA[tabelle]]></category>
		<category><![CDATA[vb]]></category>
		<category><![CDATA[vb.net]]></category>
		<category><![CDATA[vbnet]]></category>
		<category><![CDATA[visual basic]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=9159</guid>

					<description><![CDATA[<p>Daten in ein VB NET DataGridView füllen Willkommen zum heutigen Beitrag &#8222;VB NET DataGridView füllen&#8222;! Tja da sind wir am heutigen Tage wieder mit einer neuen Problemstellung, willkommen zurück &#x1f61b;! Du möchtest also in Visual Basic NET das typische Tabellen-Steuerelement namens DataGridView mit Daten füllen!? Dann lass uns auch gleich &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/ein-vb-net-datagridview-fuellen/">Ein VB NET DataGridView füllen</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/02/VB-NET-DataGridView-fuellen.jpg"><img fetchpriority="high" decoding="async" width="1200" height="628" src="https://robbelroot.de/wp-content/uploads/2022/02/VB-NET-DataGridView-fuellen.jpg" alt="VB NET DataGridView füllen" class="wp-image-9164" title="VB NET DataGridView füllen"/></a><figcaption>VB NET DataGridView füllen</figcaption></figure>






<h2 class="wp-block-heading" id="daten-in-ein-vb-net-datagridview-fullen">Daten in ein VB NET DataGridView füllen</h2>



<p>Willkommen zum heutigen Beitrag &#8222;<strong>VB NET DataGridView füllen</strong>&#8222;!</p>



<p>Tja da sind wir am <strong>heutigen Tage</strong> wieder mit einer <strong>neuen Problemstellung</strong>, willkommen zurück &#x1f61b;!</p>



<p>Du möchtest also in <strong>Visual Basic NET</strong> das typische <strong>Tabellen-Steuerelement</strong> namens <strong>DataGridView </strong>mit <strong>Daten füllen</strong>!?</p>



<p>Dann lass uns auch gleich schon <strong>direkt loslegen</strong>!</p>



<p>Die <strong>erste </strong>sich stellende <strong>Frage </strong>an dieser Stelle ist natürlich die <strong>goldene Frage </strong>Nr. 1.</p>



<p>Frage Dich also zurst: &#8222;<strong>Woher kommen </strong>meine <strong>Daten</strong>!?&#8220; – Aus einer <strong>Datenbank</strong>? Aus einer <strong>Textdatei</strong>!?</p>



<h3 class="wp-block-heading" id="nur-zur-darstellung">Nur zur Darstellung!</h3>



<p><strong>Wie </strong>eigentlich <strong>immer</strong>, sind die <strong>Steuerelemente </strong>natürlich <strong>nur </strong>zur letztendlichen <strong>visuellen Darstellung </strong>da.</p>



<p>Sie <strong>selbst </strong>sollten für gewöhnlich <strong>keine Daten </strong>&#8222;<strong>darstellen</strong>&#8220; – wenn Du verstehst was ich meine!</p>



<p><strong>Besonders in </strong>anderen Sprachen und &#8222;<strong>Stacks</strong>&#8220; <strong>wie </strong>z. B. <strong><a href="https://de.wikipedia.org/wiki/Windows_Presentation_Foundation" target="_blank" rel="noreferrer noopener">WPF</a></strong> wirst Du diese Herangehensweise kennen- und <strong>lieben lernen</strong>.</p>



<p>Denke an das <strong>Beispiel </strong>anhand einer <strong>simplen TextBox</strong>, Welche <strong>einen Vornamen </strong>verarbeitet:</p>



<p><strong>Wenn </strong>Du einen <strong>Vornamen </strong>in Deinem Programm <strong>verarbeitest</strong>, dann sollte <strong>nicht </strong>die <strong>TextBox diesen Vornamen </strong>widerspiegeln!</p>



<p><strong>Letztendlich </strong>wäre es gut, <strong>wenn </strong>Du eine <strong>dahinter </strong>geschaltete <strong>Eigenschaft </strong>hast, Welche <strong>dann </strong>den <strong>Vornamen </strong>beinhaltet.</p>



<p>Die <strong>TextBox wird </strong>lediglich <strong>angewiesen</strong>, diesen Vornamen visuell <strong>darzustellen</strong>.</p>



<p>Sie sagt praktisch: &#8222;Hey guck mal, das befindet sich im Hintergrund in den Daten&#8220;.</p>



<p>Was <strong>Sie </strong>allerdings <strong>nicht sagen </strong>sollte ist: &#8222;Ich &gt;<strong>bin</strong>&lt; die <strong>Daten</strong>&#8222;!</p>



<p>So <strong>sollte </strong>es auch <strong>bei fast allen </strong>anderen <strong>Steuerelementen </strong>und im Optimalfall <strong>auch </strong>dem <strong>DataGridView </strong>als Tabelle sein.</p>



<h2 class="wp-block-heading" id="der-gute-alte-weg-ein-vb-net-datagridview-fullen">Der gute alte Weg – Ein VB NET DataGridView füllen</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/02/VB-NET-DataGridView-fuellen-Der-gute-alte-Weg.jpg"><img decoding="async" width="1200" height="628" src="https://robbelroot.de/wp-content/uploads/2022/02/VB-NET-DataGridView-fuellen-Der-gute-alte-Weg.jpg" alt="VB NET DataGridView füllen - Der gute alte Weg" class="wp-image-9170" title="VB NET DataGridView füllen - Der gute alte Weg"/></a><figcaption>VB NET DataGridView füllen &#8211; Der gute alte Weg</figcaption></figure>



<p>Kommen wir im <strong>ersten Beispiel</strong> zum &#8222;guten <strong>alten Weg</strong>&#8222;, Welcher es eigentlich <strong>nicht </strong>ist, also <strong>gut</strong>..</p>



<p><strong>Warum </strong>&#8222;er&#8220; <strong>dennoch </strong>als &#8222;gut&#8220; bekannt ist? <strong>Naja</strong>, <strong>weil </strong>es wie immer die <strong>Routine </strong>der Menschen ist, Welche etwas <strong>als </strong>&#8222;<strong>gut</strong>&#8220; <strong>betitelt</strong>.</p>



<p>Man <strong>ist es</strong> durchaus <strong>als Anfänger gewohnt</strong>, dem DataGridView direkte Kommandos via &#8222;Items&#8220;-Auflistung zu geben.</p>



<p>Dies <strong>kommt </strong>– zu meinem Bedauern – <strong>viel zu häufig vor</strong>, leider ist es nicht so toll, wie es einfach erscheint.</p>



<h3 class="wp-block-heading" id="was-objekte-gemeinsam-haben">Was Objekte gemeinsam haben..</h3>



<p>Das <strong>funktioniert deshalb </strong>so einfach, weil die &#8222;Items&#8220;-Auflistung vom Typ &#8222;<strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.datagridviewrowcollection" target="_blank" rel="noreferrer noopener">DataGridViewRowCollection</a></strong>&#8220; ist.</p>



<p>Und naja was soll ich sagen, <strong>daher ist </strong>die <strong>Auflistung </strong>eine <strong>Zusammensetzung </strong>aus einzelnen &#8222;<strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.datagridviewrow" target="_blank" rel="noreferrer noopener">DataGridViewRows</a></strong>&#8222;.</p>



<p>Diese <strong>einzelnen Reihen sowie </strong>die <strong>Auflistung </strong>als solches <strong>haben </strong>somit wie jede Objekt-Instanz:</p>



<ul class="wp-block-list"><li><strong>Eigenschaften</strong></li><li><strong>Methoden </strong>(Funktionen, Subs)</li><li><strong>Ereignisse</strong></li><li>&#8230;</li></ul>



<p><strong>Schaue Dir </strong>also für das erste Beispiel die <strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.datagridviewrowcollection?view=windowsdesktop-6.0#methods" target="_blank" rel="noreferrer noopener">Methoden</a></strong> der &#8222;DataGridViewRowCollection&#8220;-Klasse an.</p>



<p><strong>Dort finden </strong>wir die verschiedenen &#8222;<strong>Add</strong>&#8222;-<strong>Methoden</strong>, Welche – wie der Name schon sagt – <strong>für </strong>das <strong>Hinzufügen zuständig </strong>ist.</p>



<h3 class="wp-block-heading" id="datagridview-zusammenbauen">DataGridView zusammenbauen</h3>



<p>Bevor wir im <strong>ersten Beispiel</strong> nun Daten einfügen können, müsstest Du <strong>zuerst </strong>noch ein <strong>DataGridView anlegen</strong>.</p>



<p><strong>Erstelle </strong>also <strong>nun </strong>im nächsten Schritt das <strong>DataGridView</strong>, Welches dann gleich mit Daten gefüllt wird.</p>



<p>Nimm <strong>gerne dieses </strong>hier als <strong>Beispiel</strong>:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/02/VB-NET-DataGridView-fuellen-Erstes-Beispiel-DataGridView.png"><img decoding="async" width="803" height="483" src="https://robbelroot.de/wp-content/uploads/2022/02/VB-NET-DataGridView-fuellen-Erstes-Beispiel-DataGridView.png" alt="VB NET DataGridView füllen - Erstes Beispiel DataGridView" class="wp-image-9180" title="VB NET DataGridView füllen - Erstes Beispiel DataGridView"/></a><figcaption>VB NET DataGridView füllen &#8211; Erstes Beispiel DataGridView</figcaption></figure>



<p><strong>Beachte </strong>jedoch, dass ich <strong>wie fast</strong> immer <strong>folgende Eigenschaften </strong>gesetzt habe.</p>



<p>Diese <strong>benötige </strong>ich persönlich <strong>fast in 95%</strong> der <strong>Projekte</strong>..</p>



<ul class="wp-block-list"><li>AllowUserToAddRows &#8211; False</li><li>AllowUserToDeleteRows &#8211; False</li><li>AllowUserToResizeRows &#8211; False</li><li>AlternatingRowsDefaultCellStyle &#8211; BackgroundColor auf LightGray</li><li>BackgroundColor &#8211; White</li><li>Dock &#8211; Fill</li><li>MultiSelect &#8211; False</li><li>ReadOnly &#8211; True</li><li>RowHeadersVisible &#8211; False</li><li>SelectionMode &#8211; FullRowSelect</li><li>..<strong>und </strong>dann noch die <strong>obigen Spalten</strong>!</li></ul>



<h3 class="wp-block-heading" id="daten-reihen-hinzufugen">Daten/Reihen hinzufügen</h3>



<p><strong>Schauen </strong>wir uns <strong>nun die </strong>verschiedenen <strong>Überladungen </strong>der &#8222;Add&#8220;-Methode <strong>an</strong>.</p>



<p>Ich <strong>werde </strong>hier <strong>natürlich nicht alle durchgehen</strong>, da Du Sie ja in der obigen Dokumentation ansehen kannst.</p>



<p><strong>Folgende </strong>ist <strong>allerdings </strong>die meiner Meinung nach für dich – im ersten Beispiel – die <strong>Interessanteste</strong> Überladung:</p>



<ul class="wp-block-list"><li><strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.datagridviewrowcollection.add?view=windowsdesktop-6.0#system-windows-forms-datagridviewrowcollection-add(system-object())" target="_blank" rel="noreferrer noopener">Add(Object[])</a></strong></li></ul>



<p><strong>Wie </strong>Du <strong>anhand </strong>der <strong>Signatur </strong>erkennen kannst, <strong>möchte </strong>diese Überladung ein (param) <strong>Array </strong>von <strong>Objekten</strong>.</p>



<p><strong>Durch </strong>die <strong>spezielle Definition </strong>müssen wir auch <strong>nicht erst </strong>ein <strong>Array erstellen </strong>und Werte einfügen.</p>



<p><strong>Stattdessen können </strong>wir die Werte direkt <strong>getrennt </strong>durch <strong>Kommas auflisten</strong>.</p>



<h4 class="wp-block-heading" id="hardcoded">Hardcoded</h4>



<p><strong>Passend </strong>zu unserem designten DataGridView <strong>würde </strong>das <strong>Hinzufügen </strong>von Daten also <strong>so aussehen</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="">dgvArticles.Rows.Add(1, "Article 1", "KG", 9.95, 16.49, 50)</pre>



<p><strong>Natürlich </strong>könnte man das <strong>auch in </strong>einer <strong>Schleife </strong>aufrufen.</p>



<p><strong>Obwohl </strong>das zumindest in diesem Beispiel <strong>nicht den größten Sinn</strong> macht, <strong>zeige </strong>ich es <strong>trotzdem </strong>mal.</p>



<p>Wir <strong>fügen einfach mal 5 Einträge</strong> durch eine zählergesteuerte Schleife <strong>hinzu</strong>.</p>



<p>Dabei <strong>benutze ich </strong>meine sehr gemochte &#8222;<strong>String</strong>&#8211;<strong>Interpolation</strong>&#8220; (mit dem Dollar-Zeichen).</p>



<p><strong>Damit </strong>kann ich die <strong>Strings </strong>ein wenig <strong>einfacher zusammenbauen</strong>, als ständig &#8222;&amp;&#8230;&#8220; zu benutzen.</p>



<h4 class="wp-block-heading" id="als-schleife-beispiel">Als Schleife – Beispiel</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="">For i = 1 To 5
    dgvArticles.Rows.Add(i, $"Article {i}", "KG", 9.95, 16.49, 50)
Next</pre>



<p>Ich meine <strong>normalerweise müssten </strong>die <strong>Einträge </strong>vermutlich sowieso <strong>von </strong>einer Art <strong>Datenquelle kommen</strong>.</p>



<p><strong>Ob </strong>man <strong>nun </strong>eine <strong>Datenbank</strong>, eine <strong>Textdatei</strong>, <strong>oder sonstige </strong>Dinge verwendet..</p>



<h4 class="wp-block-heading" id="aus-einem-dialog-heraus">Aus einem Dialog heraus</h4>



<p><strong>Nun </strong>wird es hier schon ein wenig <strong>interessanter</strong>, <strong>da </strong>wir nun einmal die <strong>Eingaben aus </strong>einem <strong>Dialog </strong>entgegennehmen.</p>



<p><strong>Füge </strong>dem Projekt nun eine <strong>neue Form hinzu </strong>und benenne Sie z. B. als &#8222;frmArticle&#8220;.</p>



<p><strong>Danach </strong>kannst Du Sie <strong>analog</strong> zu meinem Beispiel <strong>designen</strong> (<strong>lad </strong>Dir <strong>am besten</strong> das Beispiel <strong>herunter</strong>):</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/02/VB-NET-DataGridView-fuellen-Anhand-eines-Dialogs.png"><img loading="lazy" decoding="async" width="332" height="267" src="https://robbelroot.de/wp-content/uploads/2022/02/VB-NET-DataGridView-fuellen-Anhand-eines-Dialogs.png" alt="VB NET DataGridView füllen - Anhand eines Dialogs" class="wp-image-9201" title="VB NET DataGridView füllen - Anhand eines Dialogs"/></a><figcaption>VB NET DataGridView füllen &#8211; Anhand eines Dialogs</figcaption></figure>



<p><strong>Danach </strong>sorgen wir dafür, dass <strong>der Dialog</strong> auch wirklich angezeigt <strong>und </strong>dessen <strong>Ergebnis verarbeitet </strong>wird.</p>



<p>Gehe dazu in den &#8222;<strong>Form1</strong>&#8222;-Code und <strong>erstelle </strong>einen <strong>neuen Ereignishandler </strong>für den &#8222;Add row&#8220;-Button:</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 btnAddRow_Click(sender As Object, e As EventArgs) Handles btnAddRow.Click
        Dim dialog = New frmArticle()
        Dim result = dialog.ShowDialog(Me)
        If result &lt;> DialogResult.OK Then
            Return
        End If
        Dim id = Convert.ToInt32(dialog.nudId.Value)
        Dim name = dialog.tbName.Text.Trim()
        Dim unit = dialog.cbbUnit.Text
        Dim purchasingPrice = dialog.nudPurchasingPrice.Value
        Dim sellingPrice = dialog.nudSellingPrice.Value
        Dim stock = Convert.ToInt32(dialog.nudStock.Value)
        dgvArticles.Rows.Add(id, name, unit, purchasingPrice, sellingPrice, stock)
    End Sub</pre>



<p><strong>Zuerst instanziieren </strong>wir hier eine <strong>neue Dialog</strong>-Instanz.</p>



<p><strong>Danach zeigen </strong>wir diese Instanz <strong>an</strong>, indem wir die &#8222;<strong>ShowDialog</strong>&#8222;-Methode aufrufen <strong>und </strong>&#8222;<strong>Me</strong>&#8220; (also die aktuelle Form) als &#8222;Papa&#8220; mitgeben.</p>



<p>Den <strong>Rückgabewert </strong>der Funktion <strong>speichern wir in </strong>der Variable &#8222;<strong>result</strong>&#8222;, <strong>um </strong>dann zu <strong>checken</strong>, ob&#8217;s &#8222;OK&#8220; war.</p>



<p><strong>Falls nicht</strong>, <strong>verlassen </strong>wir den Ereignishandler mit einem <strong>Early-Return</strong>.</p>



<p><strong>Anschließend ziehen </strong>wir uns die <strong>einzelnen Daten </strong>aus den jeweiligen Steuerelementen.</p>



<p><strong>Auch hier </strong>könnte man <strong>mit Datenbindung </strong>arbeiten und <strong>so mit Eigenschaften </strong>arbeiten, aber das <strong>lassen wir </strong>hier erstmal..</p>



<p><strong>Zum Schluss fügen </strong>wir die <strong>Daten </strong>dem DataGridView wie oben bereits gezeigt <strong>hinzu</strong>.</p>



<p>Gehen wir aber noch einmal <strong>zurück zum Artikel-Dialog</strong> selbst.</p>



<p>Dort brauchen wir <strong>zuerst </strong>den <strong>Handler </strong>des <strong>Abbrechen</strong>-Buttons:</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 btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
        DialogResult = DialogResult.Cancel
    End Sub</pre>



<p>Der <strong>setzt</strong> das &#8222;<strong>DialogResult</strong>&#8220; der Form, <strong>woraufhin </strong>die <strong>Form </strong>dann mit diesem Ergebnis <strong>geschlossen wird</strong>.</p>



<p><strong>Danach </strong>legen wir den <strong>Code für </strong>den &#8222;<strong>Hinzufügen</strong>&#8222;-Knopf fest:</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 btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
        If Not ValidateInput() Then
            Return
        End If
        DialogResult = DialogResult.OK
    End Sub</pre>



<p>Dort <strong>prüfen </strong>wir den <strong>Rückgabewert </strong>der gleich noch folgenden Funktion und &#8222;<strong>early returnen</strong>&#8220; <strong>hier wieder</strong>, falls Sie &#8222;<strong>False</strong>&#8220; zurückgibt.</p>



<p><strong>Anschließend </strong>setzen wir das &#8222;<strong>DialogResult</strong>&#8220; auf &#8222;<strong>OK</strong>&#8222;, woraufhin auch hier die <strong>Form geschlossen </strong>wird.</p>



<p><strong>Zum Schluss </strong>kommt dann hier noch die kleine &#8222;<strong>ValidateInput</strong>&#8222;-Funktion:</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 Function ValidateInput() As Boolean
        ' dont care about id..

        Dim name = tbName.Text.Trim()
        If String.IsNullOrWhiteSpace(name) Then
            MessageBox.Show("Please provide an article name")
            Return False
        End If

        Dim unit = cbbUnit.Text
        If String.IsNullOrWhiteSpace(unit) Then
            MessageBox.Show("Please provide an article unit")
            Return False
        End If

        ' prices are handled by the numeric up downs..
        ' stock is handled by numeric up down

        Return True
    End Function</pre>



<p>Die <strong>Id </strong>wird <strong>hier erstmal nicht </strong>weiter geprüft, da das &#8222;NumericUpDown&#8220; schon <strong>notwendige </strong>Eigenschaften gesetzt hat.</p>



<p>Somit <strong>übernimmt </strong>es die <strong>Prüfung </strong>für &#8222;<strong>Min</strong>-&#8220; und &#8222;<strong>MaxValue</strong>&#8222;, <strong>sowie </strong>den <strong>Dezimalstellen</strong>.</p>



<p>Das <strong>gilt </strong>übrigens <strong>auch für </strong>die <strong>anderen </strong>&#8222;<strong>NumericUpDowns</strong>&#8220; auf der Form.</p>



<p>Die <strong>einzigen </strong>beiden zu <strong>prüfenden </strong>Werte wären der <strong>Name </strong>und die <strong>Einheit</strong>.</p>



<p>Dort <strong>checken </strong>wir <strong>einfach</strong>, <strong>dass </strong>die <strong>Werte nicht </strong>&#8222;<strong>leer</strong>&#8220; sind.</p>



<p><strong>Wenn alles okay </strong>war, kommen wir ans <strong>Ende </strong>der Funktion und <strong>geben </strong>&#8222;<strong>True</strong>&#8220; zurück.</p>



<h3 class="wp-block-heading" id="add-x-y-z-sieht-blod-aus-oder">Add(x, y, z) sieht blöd aus, oder!?</h3>



<p>Ich meine man <strong>muss kein Sherlock</strong> Holmes <strong>sein</strong>, <strong>um </strong>zu <strong>sehen</strong>, dass <strong>das </strong>irgendwie <strong>blöd aussieht</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="">dgvArticles.Rows.Add(1, "Article 1", "KG", 9.95, 16.49, 50)</pre>



<p><strong>Denkst Du </strong>z. B., dass Du <strong>auch </strong>noch <strong>in einem Jahr weißt</strong>, <strong>was </strong>die <strong>50 </strong>bedeutet?</p>



<p>Ist es vielleicht die <strong>Kilogramm</strong>-Anzahl, <strong>oder </strong>doch eine <strong>Mindestbestellmenge</strong>?</p>



<p><strong>Was passiert </strong>zum Beispiel, <strong>wenn </strong>sich die Spalten-<strong>Reihenfolge </strong>ändert?</p>



<p><strong>Möchtest </strong>Du <strong>dann </strong>viele <strong>einzelne Stellen </strong>im Code <strong>anpassen </strong>– ne, oder!?</p>



<p>Es <strong>muss </strong>natürlich auch <strong>nicht immer </strong>sein, dass Du der <strong>einzige Entwickler </strong>im Bunde bist.</p>



<p><strong>Denkst </strong>Du, dass <strong>dies besonders leserlich </strong>und einfach zu verstehen <strong>für andere </strong>Entwickler ist?</p>



<p><strong>Zusammengefasst würde </strong>ich mal <strong>behaupten</strong>, <strong>dass </strong>es folgendes <strong>nicht </strong>ist:</p>



<ul class="wp-block-list"><li>&#8222;<strong>sauber</strong>&#8222;</li><li><strong>leserlich</strong></li><li>einfach zu <strong>verstehen</strong></li><li>gut zu <strong>behalten</strong></li></ul>



<h3 class="wp-block-heading" id="ja-aber">Ja aber..</h3>



<p><strong>Klar</strong>, <strong>jetzt </strong>wirst Du mir ggf. mit der <strong>Ausrede </strong>kommen:</p>



<p>&#8222;Ja, aber ein <strong>Objekt-Konstruktor kann</strong> doch <strong>auch lang sein </strong>und durch Kommas getrennt sein&#8220;.</p>



<p>Da <strong>hast Du </strong>natürlich <strong>recht</strong>, <strong>weshalb </strong>das natürlich auch <strong>ebenso </strong>der <strong>Grund </strong>ist, weshalb man &#8222;<strong>lange</strong>&#8220; <strong>Konstruktoren vermeiden </strong>sollte.</p>



<p>Die <strong>schmerzende Länge </strong>definiert hier mit Sicherheit <strong>jedes Entwickler-Team</strong> in dessen Konventionen selbst.</p>



<p>Aber <strong>zum Glück </strong>gibt es <strong>genug Beiträge </strong>und <strong>Bücher </strong>darüber, weshalb die <strong>relativ einfache </strong>Antwort: &#8222;<strong>Zwischen 2-3 Parametern</strong>&#8220; sein <strong>kann</strong>.</p>



<p><strong>Besonders bei </strong>einem <strong>Model</strong>, <strong>oder </strong>einer <strong>Entität namens </strong>&#8222;<strong>Artikel</strong>&#8220; <strong>muss </strong>man aber wirklich <strong>von vielen Eigenschaften </strong>ausgehen.</p>



<p><strong>Daher </strong>würde ich hier <strong>allgemein nicht </strong>großartig <strong>anfangen </strong>einen <strong>Konstruktor aufzublähen</strong>..</p>



<h2 class="wp-block-heading" id="der-modernere-weg-das-vb-net-datagridview-fullen">Der modernere Weg – Das VB NET DataGridView füllen</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/02/VB-NET-DataGridView-fuellen-Die-moderne-Variante.jpg"><img loading="lazy" decoding="async" width="1200" height="628" src="https://robbelroot.de/wp-content/uploads/2022/02/VB-NET-DataGridView-fuellen-Die-moderne-Variante.jpg" alt="VB NET DataGridView füllen - Die moderne Variante" class="wp-image-9229" title="VB NET DataGridView füllen - Die moderne Variante"/></a><figcaption>VB NET DataGridView füllen &#8211; Die moderne Variante</figcaption></figure>



<p>Kommen wir <strong>im nächsten Szenario </strong>zu einer etwas <strong>moderneren Herangehensweise</strong>.</p>



<p>Ich würde diese Weise auch <strong>durchaus </strong>als <strong>wesentlich sauberer </strong>bezeichnen, warum – siehst Du gleich.</p>



<p>Du kannst auch <strong>hierfür </strong>die <strong>grafische Oberfläche </strong>aus dem Beispiel <strong>von oben </strong>verwenden.</p>



<p>Ggf. <strong>kopierst </strong>Du das <strong>Projekt </strong>einmal, <strong>um </strong>beide <strong>Varianten </strong>separat <strong>vorliegen </strong>zu haben.</p>



<p>Im <strong>nächsten Beispiel </strong>werden wir nun eine <strong>datengebundene Variante </strong>verwenden.</p>



<p>Das verbessert <strong>neben </strong>dem oben <strong>angesprochenen </strong>&#8222;Spalten-Reihenfolgen-<strong>Problem</strong>&#8220; <strong>auch </strong>noch <strong>andere Aspekte</strong>.</p>



<h3 class="wp-block-heading" id="sauber-er-es-feeling">Sauber(er)es Feeling</h3>



<p><strong>Insgesamt fühlt </strong>es <strong>sich </strong>– jedenfalls für mich und viele andere Entwickler – einfach <strong>sauberer an</strong>.</p>



<p>Das mag vom Empfinden her vermutlich <strong>daran </strong>liegen, dass man eine <strong>klare Trennung zwischen Daten und Oberfläche </strong>hat.</p>



<p>Im <strong>vorherigen Beispiel </strong>haben wir stattdessen die <strong>GUI </strong>sozusagen <strong>mit </strong>den <strong>Daten vermischt </strong>– ihh!</p>



<p><strong>Auch wenn </strong>das &#8222;DataGridView&#8220; <strong>viele Methoden </strong>zur <strong>Befüllung </strong>mit <strong>Daten </strong>unterstützt, ist Diese die <strong>von mir am meisten Genutzte</strong>.</p>



<p>Lass uns also im <strong>nächsten Schritt </strong>die <strong>Vorbereitungen dazu </strong>treffen!</p>



<h3 class="wp-block-heading" id="klasse-erstellen">Klasse erstellen</h3>



<p><strong>Yay</strong>, <strong>endlich </strong>ist es soweit und wir können <strong>zu dem Punkt </strong>kommen, <strong>der </strong>die <strong>Objektorientierung </strong>wohl <strong>am meisten prägt</strong>.</p>



<p>Ich <strong>spreche dabei </strong>selbstverständlich <strong>vom Thema Klassen</strong>, <strong>Welche </strong>die <strong>Baupläne </strong>von Objekten darstellen.</p>



<p><strong>Erst wenn </strong>man diese Pläne &#8222;<strong>umsetzt</strong>&#8222;, <strong>entstehen </strong>daraus <strong>konkrete Objekte</strong>, mit denen man dann arbeiten kann.</p>



<p>Diese <strong>Objekte kann </strong>man – wie Du gleich sehen wirst – <strong>auch für </strong>unser &#8222;<strong>DataGridView</strong>&#8220; <strong>verwenden</strong>.</p>



<p><strong>In Kombination brauchen </strong>wir natürlich noch irgendetwas, <strong>was </strong>diese Instanzen/Objekte der Klassen dann <strong>auflisten kann</strong>.</p>



<h3 class="wp-block-heading" id="eine-liste-muss-her">Eine Liste muss her</h3>



<p><strong>Wenn </strong>man so <strong>an Auflistungen denkt</strong>, <strong>kommen </strong>einem vermutlich zuerst <strong>Dinge wie </strong>das ganz rudimentäre <strong><a href="https://de.wikipedia.org/wiki/Feld_(Datentyp)" target="_blank" rel="noreferrer noopener">Array </a></strong>in den Sinn.</p>



<p><strong>Als nächstes </strong>macht man sich ggf. <strong>Gedanken über Listen</strong>, bzw. deren generische <strong>Variante</strong>.</p>



<p><strong>Leider reichen </strong>die sehr (auch meinerseits) <strong>beliebten <a href="https://docs.microsoft.com/de-de/dotnet/visual-basic/programming-guide/concepts/collections" target="_blank" rel="noreferrer noopener">Listen</a></strong> <strong>nicht </strong>aus, da ein entscheidender <strong>Faktor fehlt</strong>.</p>



<p><strong>Häufig arbeiten </strong>wir in solchen Szenarien <strong>mit Aktionen</strong>, <strong>Welche </strong>dann Einträge <strong>hinzufügen</strong>, oder eben auch <strong>löschen</strong>.</p>



<p><strong>Dabei </strong>ist es <strong>natürlich von Relevanz</strong>, dass die Liste z. B. eine <strong>Entfernung </strong>eines Elements auch &#8222;nach außen <strong>kommuniziert</strong>&#8222;.</p>



<p>Das sollte Sie <strong>deshalb </strong>im Optimalfall tun, <strong>damit andere </strong>(vor allem grafische) <strong>Elemente</strong>, eine Chance haben zu <strong>reagieren</strong>.</p>



<p>Im <strong>konkreten Fall </strong>unserer kleinen tabellarischen Darstellung, <strong>könnte </strong>die <strong>Tabelle </strong>somit <strong>neu gezeichnet </strong>werden.</p>



<p>Das <strong>geht nur </strong>eben <strong>schlecht</strong>, <strong>wenn </strong>unsere <strong>Tabelle </strong>(also das DataGridView) davon gar <strong>nichts</strong> <strong>mitbekommt</strong>.</p>



<h3 class="wp-block-heading" id="die-alternative-zur-list-of">Die Alternative zur List Of</h3>



<p><strong>Wie </strong>bereits <strong>erwähnt benötigen </strong>wir eine <strong>andere </strong>Art <strong>Liste</strong>, um unsere Arbeit zu erledigen.</p>



<p><strong>Wenn </strong>wir ein <strong>wenig </strong>im NET Framework <strong>graben</strong>, <strong>kommen </strong>wir <strong>auf </strong>die sogenannte &#8222;<strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.componentmodel.bindinglist-1" target="_blank" rel="noreferrer noopener">BindingList</a></strong>&#8222;.</p>



<p>Diese ist <strong>wie </strong>der <strong>Name </strong>schon <strong>suggeriert</strong>, <strong>für </strong>die <strong>Bindung </strong>von Daten <strong>geeignet</strong>.</p>



<p>Durch Ihre <strong>generische Art</strong>, können wir die &#8222;BindingList&#8220; für alle <strong>möglichen</strong> <strong>Arten </strong>von <strong>Objekten </strong>verwenden.</p>



<h3 class="wp-block-heading" id="eine-artikel-klasse-unseren-bauplan-erstellen">Eine Artikel-Klasse – unseren Bauplan erstellen</h3>



<p><strong>Zunächst </strong>gehen wir hin und <strong>erstellen </strong>im nächsten Schritt den <strong>Bauplan für </strong>unsere <strong>Objekte</strong>, also eine <strong>Klasse</strong>.</p>



<p><strong>Analog </strong>zum <strong>oben </strong>bereits veranschaulichten Beispiel, könnte die <strong>Artikel</strong>&#8211;<strong>Klasse so </strong>aussehen:</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="">Public Class Article

    Public Property Id As Integer

    Public Property Name As String

    Public Property Unit As String

    Public Property PurchasingPrice As Decimal

    Public Property SellingPrice As Decimal

    Public Property Stock As Integer

    Sub New()

    End Sub

End Class</pre>



<p><strong>Danach müssen </strong>wir die definierte <strong>Klasse </strong>natürlich <strong>noch </strong>in Kombination <strong>mit </strong>der &#8222;<strong>BindingList</strong>&#8220; verwenden.</p>



<h3 class="wp-block-heading" id="eine-eigenschaft-fur-die-auflistung-liste">Eine Eigenschaft für die Auflistung/Liste</h3>



<p>Gehe also <strong>im nächsten Schritt </strong>in die <strong>Form</strong>-Klasse und <strong>lege </strong>dort eine neue <strong>Eigenschaft </strong>namens &#8222;Articles&#8220; <strong>an</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="">Public Property Articles As BindingList(Of Article)</pre>



<p><strong>Anschließend instanziieren </strong>wir diese Eigenschaft <strong>im Konstruktor </strong>der Form.</p>



<p><strong>Ansonsten würden </strong>wir natürlich eine <strong>Nullverweisausnahme bekommen</strong>, sprich ein Objekt verwenden, Welches (noch) &#8222;nicht existiert&#8220;.</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="">    Sub New()
        InitializeComponent()
        Articles = New BindingList(Of Article)
    End Sub</pre>



<p><strong>Danach </strong>können wir <strong>im Load</strong>-Ereignishandler dem &#8222;DataGridView&#8220; die <strong>Datenquelle zuordnen</strong>.</p>



<p><strong>Anschließend laden </strong>wir <strong>mit </strong>der gleich folgenden <strong>Methode </strong>ein paar <strong>Testdaten</strong>.</p>



<p>Diese würde im <strong>Normalfall </strong>eventuell <strong>aus </strong>einer <strong>Datenbank</strong>, <strong>Textdatei</strong>, oder <strong>woher auch immer </strong>kommen.</p>



<p><strong>Für unser Beispiel lade </strong>ich die <strong>Daten </strong>allerdings bewusst <strong>aus </strong>einer <strong>Methode </strong>heraus..</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_Load(sender As Object, e As EventArgs) Handles Me.Load
        dgvArticles.DataSource = Articles
        LoadArticleTestData()
    End Sub

    Private Sub LoadArticleTestData()
        Articles.Add(New Article() With {
            .Id = 1,
            .Name = "Article 1",
            .Unit = "KG",
            .PurchasingPrice = 9.95,
            .SellingPrice = 12.99,
            .Stock = 50
        })
        Articles.Add(New Article() With {
            .Id = 2,
            .Name = "Article 2",
            .Unit = "l",
            .PurchasingPrice = 13.95,
            .SellingPrice = 19.99,
            .Stock = 0
        })
        Articles.Add(New Article() With {
            .Id = 3,
            .Name = "Article 3",
            .Unit = "ml",
            .PurchasingPrice = 3.49,
            .SellingPrice = 6.99,
            .Stock = 20
        })
    End Sub</pre>



<p><strong>Beachte bitte</strong>, dass die Liste <strong>für jeden </strong>&#8222;Add-<strong>Vorgang</strong>&#8220; ein getrenntes <strong>Ereignis </strong>auslöst.</p>



<p>Die <strong>Liste sagt also </strong>sowas wie &#8222;<strong>Hey</strong>, hier ist <strong>was hinzugekommen</strong>&#8222;.</p>



<p><strong>Wenn </strong>Du natürlich <strong>nun Daten </strong>aus einer Datenbank <strong>lädst </strong>(30, 300, oder gar 30000 Einträge), <strong>spielt </strong>dieser <strong>Aspekt </strong>eine <strong>Rolle</strong>.</p>



<p><strong>Für mich persönlich </strong>ist diese Rolle sogar ganz und gar <strong>nicht zu unterschätzen</strong>.</p>



<p><strong>Wenn </strong>die <strong>Auflistung 3000 </strong>mal das &#8222;ItemAdded&#8220; (oder ähnlich) auslöst, <strong>ist </strong>das für mich eher <strong>weniger effizient</strong>.</p>



<p><strong>Stattdessen </strong>wäre es ja <strong>sinnvoll</strong>, <strong>wenn </strong>die <strong>Liste ein einziges Mal</strong> nach Abschluss des Ladevorgangs <strong>sagt</strong>:</p>



<p>&#8222;<strong>So </strong>liebe zuhörenden Steuerelemente, bitte <strong>nun neu zeichnen</strong>, da ich mich verändert habe&#8220;.</p>



<p><strong>Leider</strong> <strong>besitzt </strong>die &#8222;BindingList&#8220; von Haus aus <strong>keine </strong>&#8222;<strong>AddRange</strong>&#8222;-Methode.</p>



<p><strong>Zum Glück </strong>können wir diese aber relativ <strong>einfach und zügig</strong> mit einer Extension <strong>nacharbeiten</strong>.</p>



<h3 class="wp-block-heading" id="bindinglist-addrange-extension">BindingList AddRange-Extension</h3>



<p><strong>Lege </strong>hierzu einen <strong>neuen Ordner </strong>im Projekt an, den Du dann z. B. &#8222;<strong>Utils</strong>&#8220; nennen kannst.</p>



<p><strong>Erstelle </strong>darin ein <strong>Modul namens &#8222;BindingListExtensions&#8220; und </strong>füge folgenden <strong>Code </strong>ein:</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="">Imports System.ComponentModel
Imports System.Runtime.CompilerServices

Namespace Utils

    Module BindingListExtensions

        &lt;Extension()>
        Public Sub AddRange(Of T)(bindingList As BindingList(Of T), collection As IEnumerable(Of T))
            Dim oldRaiseEvents = bindingList.RaiseListChangedEvents
            bindingList.RaiseListChangedEvents = False
            Try
                For Each item In collection
                    bindingList.Add(item)
                Next
            Finally
                bindingList.RaiseListChangedEvents = oldRaiseEvents
                If bindingList.RaiseListChangedEvents Then
                    bindingList.ResetBindings()
                End If
            End Try
        End Sub

    End Module

End Namespace</pre>



<p>Die &#8222;<strong>BindingList</strong>&#8222;-Klasse <strong>wird </strong>hiermit dann <strong>um </strong>die &#8222;<strong>AddRange</strong>&#8222;-Methode <strong>erweitert</strong>.</p>



<p><strong>In </strong>der <strong>Methode </strong>selbst <strong>merken </strong>wir <strong>uns </strong>oben den aktuellen <strong>Wert </strong>der &#8222;<strong>RaiseListChangedEvents</strong>&#8222;-Eigenschaft.</p>



<p>Diese <strong>bestimmt</strong>, <strong>ob </strong>für gewisse <strong>Vorgänge </strong>dann ein &#8222;Ich habe mich <strong>verändert</strong>&#8222;-<strong>Ereignis ausgelöst </strong>werden soll.</p>



<p>Anschließend <strong>deaktivieren </strong>wir diesen <strong>Benachrichtigungs-Mechanismus</strong>, damit Dieser pausiert.</p>



<p><strong>Danach fügen </strong>wir die <strong>einzelnen Elemente </strong>in die Auflistung <strong>ein</strong>, wobei man sich theoretisch das Try-Catch sparen könnte.</p>



<p>Eigentlich <strong>kann </strong>in diesem Fall <strong>nicht viel falsch </strong>gehen..</p>



<p><strong>Nachdem </strong>wir alle <strong>Elemente hinzugefügt </strong>haben, <strong>setzen </strong>wir die &#8222;<strong>RaiseListChangedEvents</strong>&#8222;-Eigenschaft wieder auf den <strong>vorherigen Wert</strong>.</p>



<p><strong>Danach setzen </strong>wir die <strong>Datenbindungen </strong>mit Hilfe der &#8222;<strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.bindingsource.resetbindings" target="_blank" rel="noreferrer noopener">ResetBindings</a></strong>&#8222;-Methode <strong>zurück</strong>.</p>



<h3 class="wp-block-heading" id="elemente-artikel-mit-addrange-hinzufugen">Elemente/Artikel mit AddRange hinzufügen</h3>



<p><strong>Final konnten </strong>wir so dann das <strong>zigfache Auslösen</strong> der Ereignisse <strong>unterbinden </strong>und ein <strong>effizienteres Hinzufügen </strong>umsetzen.</p>



<p><strong>Schauen </strong>wir uns <strong>nun </strong>einmal an, wie ein <strong>beispielhafter Aufruf </strong>der Methode aussehen könnte.</p>



<p>Wir <strong>haben </strong>also <strong>nach wie vor</strong> unsere <strong>instanziierte </strong>&#8222;<strong>Articles</strong>&#8222;-Eigenschaft.</p>



<p><strong>Ebenso rufen im Load</strong>-Ereignishandler immer noch <strong>die </strong>&#8222;<strong>LoadArticleTestData</strong>&#8222;-Methode auf.</p>



<p>Diese <strong>Methode könnte </strong>dann <strong>so aussehen</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 LoadArticleTestData()
        Dim myArticles = New List(Of Article)
        myArticles.Add(New Article() With {
            .Id = 1,
            .Name = "Article 1",
            .Unit = "KG",
            .PurchasingPrice = 9.95,
            .SellingPrice = 12.99,
            .Stock = 50
        })
        myArticles.Add(New Article() With {
            .Id = 2,
            .Name = "Article 2",
            .Unit = "l",
            .PurchasingPrice = 13.95,
            .SellingPrice = 19.99,
            .Stock = 0
        })
        myArticles.Add(New Article() With {
            .Id = 3,
            .Name = "Article 3",
            .Unit = "ml",
            .PurchasingPrice = 3.49,
            .SellingPrice = 6.99,
            .Stock = 20
        })
        Articles.AddRange(myArticles)
    End Sub</pre>



<p>Wir <strong>erstellen </strong>hier also erstmal eine <strong>lokale Liste </strong>für die Sub, Welche eine normale Liste darstellt.</p>



<p><strong>Danach fügen </strong>wir die <strong>einzelnen Artikel </strong>hinzu und verwenden <strong>zum Schluss </strong>die <strong>definierte </strong>&#8222;<strong>AddRange</strong>&#8222;-Methode.</p>



<p><strong>Vergiss </strong>hier <strong>nicht </strong>die <strong>notwendigen Imports </strong>oberhalb der Form <strong>hinzuzufü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="">Imports System.ComponentModel
Imports VBDataGridViewFillExample.Utils

Public Class Form1

' ...

End Class</pre>



<h2 class="wp-block-heading" id="downloads">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="https://bit.ly/vbnet-datagridview-füllen-download" target="_blank" rel="noreferrer noopener">VBDataGridViewFillExample.zip</a></div>
</div>



<h2 class="wp-block-heading" id="weiterfuhrende-links">Weiterführende Links</h2>



<ul class="wp-block-list"><li><strong><a href="https://robbelroot.de/blog/dein-vb-net-plugin-system-im-eigenbau-das-ultimative-beispiel/" target="_blank" rel="noreferrer noopener">Dein eigenes VB NET Plugin-System</a></strong></li><li><strong><a href="https://robbelroot.de/blog/das-wpf-datagrid-zur-darstellung-tabellarischer-daten/" target="_blank" rel="noreferrer noopener">Das WPF DataGrid als moderne DataGridView-Alternative</a></strong></li><li><strong><a href="https://robbelroot.de/blog/vb-net-webbrowser-alternative/" target="_blank" rel="noreferrer noopener">Eine Alternative für das Webbrowser-Steuerelement</a></strong></li></ul>
<p>Der Beitrag <a href="https://robbelroot.de/blog/ein-vb-net-datagridview-fuellen/">Ein VB NET DataGridView füllen</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/ein-vb-net-datagridview-fuellen/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>VB NET ImageSearch – Bilder in Spielen, Desktop und Co. suchen</title>
		<link>https://robbelroot.de/blog/vb-net-imagesearch-bilder-in-spielen-desktop-und-co-suchen/</link>
					<comments>https://robbelroot.de/blog/vb-net-imagesearch-bilder-in-spielen-desktop-und-co-suchen/#comments</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Sat, 02 Oct 2021 00:36:32 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Visual Basic .NET]]></category>
		<category><![CDATA[Visual Basic .NET Problemlösungen]]></category>
		<category><![CDATA[au3]]></category>
		<category><![CDATA[autoclick]]></category>
		<category><![CDATA[autoclicker]]></category>
		<category><![CDATA[autoit]]></category>
		<category><![CDATA[autoit3]]></category>
		<category><![CDATA[autoklick]]></category>
		<category><![CDATA[autoklicker]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[automatisieren]]></category>
		<category><![CDATA[benutzen]]></category>
		<category><![CDATA[bibliotheken]]></category>
		<category><![CDATA[bild]]></category>
		<category><![CDATA[bilder suchen]]></category>
		<category><![CDATA[bildsuche]]></category>
		<category><![CDATA[dll]]></category>
		<category><![CDATA[einbetten]]></category>
		<category><![CDATA[embed]]></category>
		<category><![CDATA[help]]></category>
		<category><![CDATA[hilfe]]></category>
		<category><![CDATA[hinzufügen]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[imagesearch]]></category>
		<category><![CDATA[libraries]]></category>
		<category><![CDATA[net]]></category>
		<category><![CDATA[nutzen]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[use]]></category>
		<category><![CDATA[vb.net]]></category>
		<category><![CDATA[vbnet]]></category>
		<category><![CDATA[verweis]]></category>
		<category><![CDATA[visual basic]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=6322</guid>

					<description><![CDATA[<p>VB.NET ImageSearch – Bilder in Spielen, Desktop und Co. suchen Eine VB NET ImageSearch, also eine Bildersuche wollte vermutlich jeder Entwickler im NET Umfeld einmal realisieren. Ach Gott wie präsent mir diese Momente noch im Gedächtnis sind, kleines Beispiel gefällig? Kein Problem! Egal ob beim Ingame-Angeln, wo man praktisch immer &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vb-net-imagesearch-bilder-in-spielen-desktop-und-co-suchen/">VB NET ImageSearch – Bilder in Spielen, Desktop und Co. suchen</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/10/VB.NET-Image-Search.png"><img loading="lazy" decoding="async" width="1200" height="675" src="https://robbelroot.de/wp-content/uploads/2021/10/VB.NET-Image-Search.png" alt="" class="wp-image-6324"/></a></figure>






<h2 class="wp-block-heading">VB.NET ImageSearch – Bilder in Spielen, Desktop und Co. suchen</h2>



<p>Eine <strong>VB NET ImageSearch</strong>, also eine <strong>Bildersuche </strong>wollte vermutlich <strong>jeder </strong>Entwickler im NET Umfeld <strong>einmal </strong>realisieren.</p>



<p>Ach Gott <strong>wie präsent </strong>mir diese Momente <strong>noch im Gedächtnis </strong>sind, kleines Beispiel gefällig? Kein Problem!</p>



<p><strong>Egal ob </strong>beim Ingame-<strong>Angeln</strong>, wo man praktisch <strong>immer </strong>wieder die exakt <strong>gleichen Aktionen </strong>durchführt, <strong>oder </strong>beim &#8222;<strong>craften</strong>&#8220; von Gegenständen..</p>



<p><strong>Auch wenn </strong>diese Beispiele <strong>eher </strong>mit dem <strong>Gaming</strong>-Sektor zu tun haben, gibt es <strong>mit Sicherheit </strong>genug <strong>Einsatzmöglichkeiten im Büro</strong>.</p>



<p><strong>So oder so </strong>hat man sicherlich<strong> nicht immer Lust</strong> <strong>und </strong>vor allem die <strong>Zeit,</strong> diese Art von &#8222;Monkey-Work&#8220;, also praktisch die Arbeit für &#8222;Blöde&#8220; zu erledigen.</p>



<h2 class="wp-block-heading">Auf YouTube ansehen –  VB NET ImageSearch</h2>



<iframe loading="lazy" width="560" height="315" src="https://www.youtube-nocookie.com/embed/ZrNPF36GA3g" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>



<p class="margin-after-video-block"><strong>Falls </strong>Du die <strong>visuelle Darstellung</strong>, bzw. Erklärung des Beitrages <strong>bevorzugst</strong>, <strong>kannst </strong>Du natürlich auch das dementsprechende <strong>Video anschauen</strong>.</p>



<p><strong>Ich habe </strong>allerdings in diesem Beitrag einige <strong>Neben-Themen</strong> <strong>eingebracht </strong>und kann mir <strong>auch </strong>hier die <strong>Zeit nehmen</strong>, ein wenig <strong>drum rum </strong>zu erklären.</p>



<p><strong>Dieser Beitrag </strong>hier ist daher etwas länger und <strong>ausführlicher </strong>als das Video – just sayin&#8216;.</p>



<style>
.margin-after-video-block {
  margin-top: 1em;
}
</style>



<h2 class="wp-block-heading">Ursprung und Idee zum Beitrag &#8211; VB NET ImageSearch</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/09/Button-–-eine-kleine-Wiederholung.jpg"><img loading="lazy" decoding="async" width="640" height="361" src="https://robbelroot.de/wp-content/uploads/2021/09/Button-–-eine-kleine-Wiederholung.jpg" alt="VB NET ImageSearch – Die Idee zum Beitrag" class="wp-image-6047" title="VB NET ImageSearch – Die Idee zum Beitrag"/></a><figcaption>VB NET ImageSearch – Die Idee zum Beitrag</figcaption></figure>



<p><strong>In solchen </strong>häufig wiederkehrenden <strong>Momenten hat </strong>man sicherlich das <strong>Bedürfnis</strong> nach Hilfe.</p>



<p>Man <strong>möchte </strong>seinem <strong>Hausroboter </strong>einfach sagen können: &#8222;Hey, <strong>mach </strong>Du <strong>das bitte </strong>mal, ich habe keine Lust&#8220;.</p>



<p><strong>Schnell wird </strong>man allerdings <strong>feststellen</strong>, <strong>dass </strong>das <strong>zu oft </strong>einfach <strong>nicht geht</strong>, bis auf in bestimmten Fällen.</p>



<p><strong>Als Entwickler </strong>haben wir natürlich <strong>glücklicherweise </strong>die <strong>Möglichkeit </strong>uns <strong>verschiedene </strong>Hilfsmittel zu <strong>bauen</strong>.</p>



<p>Ob <strong>privat</strong>, <strong>beruflich</strong>, oder für&#8217;s <strong>Spielen </strong>diverser Spiele, können wir uns viele <strong>Hilfsmittel programmieren</strong>.</p>



<p><strong>Vom </strong>einfachen <strong>Angel-Bot</strong>, Welcher eine bestimmte Abfolge immer wieder abarbeitet, <strong>bis </strong>hin <strong>zu komplexeren </strong>Bereichen.</p>



<p><strong>Darunter könnte </strong>ich mir z. B. einen &#8222;<strong>Crafter-Bot</strong>&#8220; vorstellen, <strong>Welcher nach </strong>gewissen <strong>Commands </strong>wie &#8222;Strg+Alt+&lt;XY&gt;&#8220; komplexe <strong>Gegenstände erstellen </strong>kann.</p>



<h2 class="wp-block-heading">Hilfsmittel zur Hand</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/10/VB.NET-ImageSearch-mit-Hilfe-von-AutoIt.png"><img loading="lazy" decoding="async" width="1200" height="675" src="https://robbelroot.de/wp-content/uploads/2021/10/VB.NET-ImageSearch-mit-Hilfe-von-AutoIt.png" alt="VB.NET ImageSearch mit Hilfe von AutoIt" class="wp-image-6341" title="VB.NET ImageSearch mit Hilfe von AutoIt"/></a><figcaption>VB.NET ImageSearch mit Hilfe von AutoIt</figcaption></figure>



<p>Wir <strong>arbeiten </strong>in diesem Beitrag <strong>nicht ohne </strong>weitere <strong>Hilfsmittel</strong>, warum sollte man auch darauf verzichten.</p>



<p><strong>Viele </strong>nützliche <strong>Funktionalitäten </strong>wurden <strong>bereits erfunden und </strong>erfolgreich über lange Zeit <strong>getestet</strong>.</p>



<p><strong>Für </strong>viele <strong>Entwickler spielt </strong>natürlich die <strong>Größe </strong>der jeweiligen Hilfsmittel eine <strong>Rolle</strong>, man <strong>möchte</strong> natürlich <strong>keine </strong>2GB <strong>großen Tools </strong>installieren.</p>



<p><strong>Viele sehen </strong>allerdings schon <strong>rot</strong>, <strong>wenn </strong>die einzelnen Helfer <strong>bereits </strong>an eine <strong>Größe von </strong>1-2 Megabyte rangehen.</p>



<p><strong>In </strong>einer <strong>Zeit wo </strong>man X <strong>Terrabyte </strong>große <strong>Festplatten </strong>schon zum Preis von den damaligen 80GB-Kloppern bekommt, <strong>sehe ich </strong>es allerdings <strong>halb </strong>so <strong>schlimm</strong>.</p>



<p><strong>Ich denke </strong>man muss <strong>letztendlich immer </strong>den <strong>Mehrwert gegenüber </strong>der <strong>Eigenarbeit </strong>in Relation sehen und der Mehrwert lohnt sich hier definitiv.</p>



<p><strong>Wenn </strong>man sein <strong>Programm intelligent entwickelt</strong>, hält einen nachher auch nichts davon ab, <strong>gewisse Parts </strong>isoliert <strong>auszutauschen</strong>.</p>



<p><strong>Letztendlich </strong>verwenden wir <strong>dieses Mal </strong>einige <strong>Funktionalitäten </strong>der <strong><a href="https://www.autoitscript.com/site/" target="_blank" rel="noreferrer noopener">AutoIt3</a></strong> Scriptsprache zu Nutze.</p>



<h2 class="wp-block-heading">Vorbereitungen des Visual Studio Projekts</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/10/Neues-Visual-Studio-Projekt-anlegen.png"><img loading="lazy" decoding="async" width="640" height="380" src="https://robbelroot.de/wp-content/uploads/2021/10/Neues-Visual-Studio-Projekt-anlegen.png" alt="Neues Visual Studio Projekt anlegen" class="wp-image-6352" title="Neues Visual Studio Projekt anlegen"/></a><figcaption>Neues Visual Studio Projekt anlegen</figcaption></figure>



<p><strong>Lade </strong>Dir <strong>nun </strong>am besten die <strong><a href="/downloads/tools/AutoItPackage.zip" target="_blank" rel="noreferrer noopener">von mir bereitgestellten Bibliotheken</a></strong> herunter, oder suche Diese alternativ im Netz.</p>



<p><strong>Erstelle</strong> im nächsten Schritt <strong>nun </strong>wie gewohnt ein <strong>neues </strong>Windows Forms-, oder z. B. ein neues WPF-<strong>Projekt</strong>.</p>



<p><strong>Füge </strong>die <strong>heruntergeladene </strong>&#8222;AutoItX3.Assembly.dll&#8220;-<strong>Datei </strong>nun <strong>als Verweis </strong>in dein Projekt <strong>ein </strong>– die anderen Dateien werden nicht funktionieren.</p>



<p>Einen <strong>Verweis </strong>kannst Du <strong>über </strong>den <strong>Projektmappen</strong>&#8211;<strong>Explorer </strong>rechts außen im Visual Studio <strong>hinzufügen</strong>.</p>



<p><strong>Klicke </strong>dazu <strong>einfach </strong>mit der <strong>rechten Maustaste auf </strong>&#8222;<strong>Verweise</strong>&#8220; und <strong>suche nach </strong>der <strong>Datei</strong>, wähle alternativ einen anderen Weg.</p>



<p>Du musst <strong>danach </strong>auch <strong>sämtliche anderen Dateien in </strong>das <strong>Debug</strong>&#8211;<strong>Verzeichnis </strong>deines Projekts <strong>legen</strong>.</p>



<p>Die <strong>oben Genannte </strong>ist <strong>bereits </strong>durch den vorhin geschehenen Import <strong>vorhanden</strong>.</p>



<h2 class="wp-block-heading">Ran an den Code –  VB NET ImageSearch </h2>



<p><strong>Die Funktion </strong>um die sich hier so gut wie alles drehen wird ist die <strong>&#8222;ImageSearch&#8220;-Funktion</strong> <strong>aus </strong>der &#8222;ImageSearchDLL.dll&#8220;.</p>



<p>Man <strong>beachte </strong>hier <strong>die komische Schreibweise</strong>, Welche trotz &#8222;doppelt-gemoppelt&#8220; tatsächlich richtig ist..</p>



<p><strong>Diese</strong> Funktion muss erst einmal wie folgt aus der passenden Library <strong>importiert werden</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="">    &lt;DllImport("ImageSearchDLL.dll")>
    Private Shared Function ImageSearch(
                                 x As Integer,
                                 y As Integer,
                                 right As Integer,
                                 bottom As Integer,
                                 imagePath As String) As IntPtr
    End Function</pre>



<p><strong>Vergiss </strong>hier auch <strong>nicht </strong>den <strong>Import des </strong>&#8222;DllImport&#8220;-<strong>Attributs</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="">Imports System.Runtime.InteropServices</pre>



<p>Ich denke, dass die <strong>Parameter der Funktion </strong>zwar relativ einleuchtend sind, <strong>gehe </strong>aber dennoch gerne <strong>darauf ein</strong>.</p>



<p><strong>Dabei </strong>wird Dir denke ich das <strong>folgende Bild </strong>noch ein wenig unter die Arme greifen:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/10/VB.NET-ImageSearch-Searching-Area.png"><img loading="lazy" decoding="async" width="640" height="380" src="https://robbelroot.de/wp-content/uploads/2021/10/VB.NET-ImageSearch-Searching-Area.png" alt="VB.NET ImageSearch Searching Area" class="wp-image-6367" title="VB.NET ImageSearch Searching Area"/></a><figcaption>VB.NET ImageSearch Searching Area</figcaption></figure>



<p><strong>Je kleiner </strong>der <strong>durchsuchte Bereich </strong>ist und <strong>je weniger Bildfläche </strong>somit durchsucht werden muss, <strong>desto schneller </strong>ist die Bildsuche natürlich.</p>



<h3 class="wp-block-heading">Parameter</h3>



<h4 class="wp-block-heading">x As Integer</h4>



<p>Der X-Parameter gibt an, auf welcher <strong>Position der X-Achse</strong> die Funktion <strong>anfangen </strong>soll zu suchen.</p>



<h4 class="wp-block-heading">y As Integer</h4>



<p><strong>Als nächstes </strong>wird der Y-Parameter übergeben, um zu <strong>definieren</strong>, <strong>ab</strong> <strong>welcher Position</strong> auf der vertikalen Achse des Bildschirms gesucht werden soll. <strong>Achtung</strong>: Von <strong>oben nach unten </strong>gesehen = <strong>je größer </strong>der Wert, <strong>desto weiter unten </strong>auf dem Bildschirm.</p>



<h4 class="wp-block-heading">right As Integer</h4>



<p>Gibt an, <strong>bis </strong>zu <strong>welchem Punkt </strong>auf der <strong>X</strong>-Achse gesucht werden soll.</p>



<h4 class="wp-block-heading">bottom As Integer</h4>



<p>Legt fest, <strong>bis </strong>zu <strong>welchem vertikalen Punkt </strong>auf der Y-Achse gesucht wird.</p>



<h4 class="wp-block-heading">imagePath As String</h4>



<p><strong>Hier </strong>kannst Du den <strong>Pfad zum Bild </strong>angeben (z. B. &#8222;my_button.png&#8220;). <strong>Achtung</strong>: <strong>Wenn </strong>Du eine gewisse <strong>Toleranz </strong>für die Suche angeben möchtest, kannst Du dies <strong>mit </strong>einem <strong>voranstehenden Leerzeichen und </strong>dem <strong>einem Wert von 0-255 </strong>machen. Das sieht dann wie folgt aus: &#8222;50 my_button.png&#8220;. Wenn Du meine Wrapper-Klasse verwendest, macht Diese das für Dich.</p>



<h2 class="wp-block-heading">Ein einfacher Aufruf –  VB NET ImageSearch </h2>



<p><strong>Schaue </strong>Dir <strong>hier </strong>einen <strong>einfachen</strong>, beispielhaften <strong>Aufruf </strong>der rohen &#8222;ImageSearch&#8220;-Funktion <strong>an</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="">' dont forget the import..
' Imports AutoIt

Dim x = 0
Dim y = 0
Dim right = 1920 ' full screen width, adjust..
Dim bottom = 1080 ' full screen height, adjust..
Dim tolerance = 50 ' a tolerance value between 0 and 255
Dim imagePath = "my_button.png"
Dim finalImagePath = $"{tolerance} {imagePath}"

Dim result = ImageSearch(x, y, right, bottom, finalImagePath)
Dim res = Marshal.PtrToStringAnsi(result)

Dim imageFound = res(0) = "1"
If Not imageFound Then
    MessageBox.Show("Image not found")
    Return
End If

Dim data = res.Split("|")

x = Integer.Parse(data(1))
y = Integer.Parse(data(2))

' optional, getting image dimensions
' Dim width = Integer.Parse(data(3))
' Dim height = Integer.Parse(data(4))

' do something with the coordinates, like moving to it
AutoItX.MouseMove(x, y)</pre>



<h2 class="wp-block-heading">Meine kleinen Hilfsklassen</h2>



<p><strong>Hier </strong>zeige ich Dir <strong>beiden </strong>(wirklich) <strong>kleinen Hilfsklassen</strong>, Welche die Arbeit mit der &#8222;ImageSearch&#8220;-Funktion ein wenig vereinfachen soll.</p>



<h3 class="wp-block-heading">ImageSearchResult-Klasse</h3>



<p>Die <strong>einfachere Klasse </strong>von beiden kommt dabei <strong>zuerst</strong>, einfach nur ein <strong>Zwischenspeicher für </strong>die <strong>Werte </strong>(alternativ könnte man eine <a href="https://docs.microsoft.com/de-de/dotnet/visual-basic/programming-guide/language-features/data-types/how-to-declare-a-structure" target="_blank" rel="noreferrer noopener"><strong>Structure </strong></a>verwenden).</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="">Public Class ImageSearchResult

    Public Property Found As Boolean

    Public Property X As Integer

    Public Property Y As Integer

    Public Property Width As Integer

    Public Property Height As Integer

    Sub New(found As Boolean)
        Me.Found = found
    End Sub

End Class</pre>



<h3 class="wp-block-heading">ImageSearch-Klasse</h3>



<p><strong>Hier </strong>wäre die <strong>Klasse</strong>, <strong>Welche </strong>Dir die <strong>Aufrufe </strong>der &#8222;ImageSearch&#8220;-Funktion ein wenig <strong>vereinfachen </strong>könnte:</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="">Imports System.Runtime.InteropServices

Public NotInheritable Class ImageSearch

    &lt;DllImport("ImageSearchDLL.dll")>
    Private Shared Function ImageSearch(
                                 x As Integer,
                                 y As Integer,
                                 right As Integer,
                                 bottom As Integer,
                                 imagePath As String) As IntPtr
    End Function

    Public Shared Function Execute(imagePath As String, Optional tolerance As Integer = 0) As ImageSearchResult
        Dim workingArea = Screen.PrimaryScreen.WorkingArea
        Dim result = DoSearch(0, 0, workingArea.Width, workingArea.Height, imagePath, tolerance)
        Return result
    End Function

    Public Shared Function Execute(x As Integer, y As Integer, right As Integer, bottom As Integer, imagePath As String, Optional tolerance As Integer = 0) As ImageSearchResult
        Dim result = DoSearch(x, y, right, bottom, tolerance, imagePath)
        Return result
    End Function

    Public Shared Function Execute(location As Point, rightBottom As Point, imagePath As String, Optional tolerance As Integer = 0) As ImageSearchResult
        Dim result = DoSearch(location.X, location.Y, rightBottom.X, rightBottom.Y, tolerance, imagePath)
        Return result
    End Function

    Private Shared Function DoSearch(x As Integer, y As Integer, right As Integer, bottom As Integer, imagePath As String, Optional tolerance As Integer = 0) As ImageSearchResult
        imagePath = $"*{tolerance} {imagePath}"

        Dim result = ImageSearch(x, y, right, bottom, imagePath)
        Dim res = Marshal.PtrToStringAnsi(result)

        Dim imageSearchResult = New ImageSearchResult(res(0) &lt;> "0")
        If Not imageSearchResult.Found Then
            Return imageSearchResult
        End If

        Dim data = res.Split("|")

        imageSearchResult.X = Integer.Parse(data(1))
        imageSearchResult.Y = Integer.Parse(data(2))

        imageSearchResult.Width = Integer.Parse(data(3))
        imageSearchResult.Height = Integer.Parse(data(4))

        Return imageSearchResult
    End Function

End Class</pre>



<h3 class="wp-block-heading">Ein Beispiel mit den Hilfsklassen</h3>



<p><strong>Hier </strong>folgt nun das <strong>Beispiel mit </strong>Hilfe der <strong>Hilfsklassen</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="">Dim result = ImageSearch.Execute("stop_button.png")
' providing a tolerance
' ImageSearch.Execute("stop_button.png", 50)
' and more overloads..
If Not result.Found Then
    MessageBox.Show("Image not found")
    ' if inside a sub, etc..
    Return
End If
' move to the found coordinates
AutoItX.MouseMove(result.X, result.Y)</pre>



<p><strong>Besonders interessant </strong>dabei sind die <strong>verschiedenen Überladungen</strong>, <strong>Welche </strong>Dir den <strong>Aufruf </strong>vermutlich <strong>verkürzen </strong>werden.</p>



<h2 class="wp-block-heading">Weiterführende Links</h2>



<ul class="wp-block-list"><li><strong><a href="https://robbelroot.de/blog/vb-net-mouseclick-simulieren-mit-autoit3/" target="_blank" rel="noreferrer noopener">VB NET MouseClick simulieren – mit AutoIt3</a></strong></li><li><strong><a href="https://robbelroot.de/blog/vb-net-web-api-waehrungskurs-service-konsum-von-grund-auf-erklaert/" target="_blank" rel="noreferrer noopener">VB NET Web API &#8211; Währungskurs Service Konsum von Grund auf erklärt</a></strong></li></ul>



<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/tools/AutoItPackage.zip" target="_blank" rel="noreferrer noopener">AutoIt Library Package.zip</a></div>



<div class="wp-block-button"><a class="wp-block-button__link" href="/downloads/vbnet/ImageSearchExample.zip" target="_blank" rel="noreferrer noopener">ImageSearchExample.zip</a></div>
</div>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vb-net-imagesearch-bilder-in-spielen-desktop-und-co-suchen/">VB NET ImageSearch – Bilder in Spielen, Desktop und Co. suchen</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vb-net-imagesearch-bilder-in-spielen-desktop-und-co-suchen/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
	</channel>
</rss>
