<?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>visual Archive - Robert Skibbe</title>
	<atom:link href="https://robbelroot.de/blog/tag/visual/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>alias RobbelRoot – Freelance Full Stack Developer .NET</description>
	<lastBuildDate>Wed, 25 Mar 2026 12:45:11 +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>visual Archive - Robert Skibbe</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Creating easy UML diagrams with Visual Studio</title>
		<link>https://robbelroot.de/blog/creating-easy-uml-diagrams-with-visual-studio/</link>
					<comments>https://robbelroot.de/blog/creating-easy-uml-diagrams-with-visual-studio/#respond</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Thu, 28 Sep 2023 11:45:48 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[auto]]></category>
		<category><![CDATA[automatic]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[class diagram]]></category>
		<category><![CDATA[diagram]]></category>
		<category><![CDATA[generate]]></category>
		<category><![CDATA[generation]]></category>
		<category><![CDATA[language]]></category>
		<category><![CDATA[modeling]]></category>
		<category><![CDATA[planning]]></category>
		<category><![CDATA[studio]]></category>
		<category><![CDATA[uml]]></category>
		<category><![CDATA[unified]]></category>
		<category><![CDATA[unified modeling language]]></category>
		<category><![CDATA[visual]]></category>
		<category><![CDATA[visual studio]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=16204</guid>

					<description><![CDATA[<p>Improved project management with UML diagrams When managing big or a bit more complex software you will sometimes find yourself overwhelmed by the sheer amount of code and or classes. For sure, intelligent design like using neat programming patterns and structuring your app optimized in terms of &#8211; for example &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/creating-easy-uml-diagrams-with-visual-studio/">Creating easy UML diagrams with Visual Studio</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/2023/09/Creating-UML-diagrams-with-Visual-Studio-Class-Designer-Component-1.png"><img fetchpriority="high" decoding="async" width="640" height="360" src="https://robbelroot.de/wp-content/uploads/2023/09/Creating-UML-diagrams-with-Visual-Studio-Class-Designer-Component-1.png" alt="Creating UML diagrams with Visual Studio Class Designer Component" class="wp-image-16238" title="Creating UML diagrams with Visual Studio Class Designer Component"/></a><figcaption class="wp-element-caption">Creating UML diagrams with Visual Studio Class Designer Component</figcaption></figure>






<h2 class="wp-block-heading">Improved project management with UML diagrams</h2>



<p>When managing big or a bit more complex software you will sometimes find yourself overwhelmed by the sheer amount of code and or classes. For sure, intelligent design like using neat programming patterns and structuring your app optimized in terms of &#8211; for example &#8211; a flat hierarchy can help. When your project gets bigger and more feature rich, it will almost always grow in complexity as well. Wouldn&#8217;t it be great to have some sort of common denominator where you can come back to and take your developer brain to some sort of a little pause for thought?</p>


<p class="rr-alert info" style="background:#e3f7fc;"><img decoding="async" alt="Info notice" src="https://robbelroot.de/wp-content/themes/pinboard-child/imgs/info.png"><span style="color:black;align-self: center;">In a hurry? No problem, I got you covered! If you just want to know, how to <a href="#visual-studio-approach">create a UML diagram inside of Visual Studio</a>, just jump to the corresponding section using the link.</span></p>



<p>One of my favourite personal tools for this is a UML diagram. UML is an acronym standing for the words &#8222;Unified Modeling Language&#8220; which is &#8211; as the name already suggests &#8211; a language for describing common modeling aspects of relating objects. This way we can express things like &#8222;a customer has a first and a last name&#8220; or &#8222;one customer has one or more residences&#8220;. There can even be more complex expressions as well like &#8222;a ViewModel implements an IViewModel interface&#8220;.</p>


<p class="rr-alert warning" style="background:#fff8c4;"><img decoding="async" alt="Warning notice" src="https://robbelroot.de/wp-content/themes/pinboard-child/imgs/warning.png"><span style="color:black;align-self: center;">Keep (sadly) in mind though, that &#8222;strict&#8220; UML diagrams aren&#8217;t really possible without extensions, etc. Out of the box you can pretty much just create class diagrams.</span></p>



<p>I mean sure, &#8222;a little pause for thought&#8220; is a bit over the top, because you need to read through the diagram anyways, but believe me, it&#8217;s a lot easier than building up relations in your head without any help. There&#8217;s almost nothing worse than a cold dive into some random or even kinda known project without any serious documentation – and a UML diagram is one of my preferred parts of a good documentation.</p>



<h2 class="wp-block-heading">Creating a UML diagram the old fashioned way</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/09/Creating-UML-diagrams-the-old-fashioned-way-with-paper-and-pencil-2.png"><img decoding="async" width="640" height="360" src="https://robbelroot.de/wp-content/uploads/2023/09/Creating-UML-diagrams-the-old-fashioned-way-with-paper-and-pencil-2.png" alt="Creating UML diagrams the old fashioned way with paper and pencil" class="wp-image-16241" title="Creating UML diagrams the old fashioned way with paper and pencil"/></a><figcaption class="wp-element-caption">Creating UML diagrams the old fashioned way with paper and pencil</figcaption></figure>



<p>Creating a UML diagram isn&#8217;t pretty hard itself, it&#8217;s just like taking a pencil and a piece of paper and letting your thoughts flow. I mean you of course have to move within some sort of &#8222;rule based boundaries&#8220; if you want to be compliant with typical UML design rules – which you actually should. However, this way other developers can easily read and interpret your drawn models and the overall diagram which will save a lot of time considering the projects development and progression.</p>



<p>Let&#8217;s start with a quick and simple example on how to create a (manual – pencil and paper based) UML diagram. We will model a &#8222;x implements y&#8220; relation which is pretty typical in terms of pattern based programming – but let&#8217;s not dive too deep into that. I mean, in &#8222;the real world&#8220; or in a real job scenario, you would have <strong>a lot</strong> more classes and you could even divide a UML diagram into seperate sections or create multiple diagrams existing on their own. Nobody forces you to represent your whole application through one diagram.</p>



<style>
.manually-sketched-uml-diagram a img {
  background-color: #1b1d1e !important;
}
</style>



<figure class="wp-block-image size-full manually-sketched-uml-diagram wp-duotone-unset-1"><a href="https://robbelroot.de/wp-content/uploads/2023/09/Manually-sketched-UML-diagram.png"><img decoding="async" width="384" height="166" src="https://robbelroot.de/wp-content/uploads/2023/09/Manually-sketched-UML-diagram.png" alt="Manually sketched UML diagram" class="wp-image-16284" title="Manually sketched UML diagram"/></a><figcaption class="wp-element-caption">Manually sketched UML diagram</figcaption></figure>



<p>The example represents a relation between a class called &#8222;Customer&#8220; which implements an interface called &#8222;ICanGiveFeedback&#8220; providing the &#8222;GiveFeedback&#8220; method. The customer therefore is something, which is able to give feedback doing it its own way. To be honest – as you might already saw – this isn&#8217;t really drawn, only looks alike, hehe.</p>



<p>For sure we could start with things like abstract blabla, but let&#8217;s keep it easy like this for our example. I have excluded things like parameters and return types as well, to keep it as easy as possible as well.</p>



<h3 class="wp-block-heading">The problem with this approach</h3>



<p>As you – being potentially working in the software industry *wink* – might already know, systems and software will change. This means, you would have to adjust your diagrams and documentation over and over. Now imagine, you would need to change your diagrams – manually! This would pretty much suck, right!? This is where Visual Studio comes into play, helping us being more productive and fast considering UML diagrams with auto generation of those.</p>



<h2 class="wp-block-heading" id="visual-studio-approach">Using Visual Studio to create a UML diagram</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/09/Creating-UML-diagrams-with-Visual-Studio.png"><img loading="lazy" decoding="async" width="640" height="360" src="https://robbelroot.de/wp-content/uploads/2023/09/Creating-UML-diagrams-with-Visual-Studio.png" alt="Creating UML diagrams with Visual Studio" class="wp-image-16306" title="Creating UML diagrams with Visual Studio"/></a><figcaption class="wp-element-caption">Creating UML diagrams with Visual Studio</figcaption></figure>



<p>Now we can go to the good part, which involves the automatic generation of UML diagrams through the usage of our Visual Studio IDE. Not only does this make everything easier in the first step, it will help us keeping our diagrams up to date as well.</p>



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



<p>Make sure, that you now have an open project ready and at least 1-2 classes / interfaces inside, otherwise it wouldn&#8217;t be pretty much possible or boring. If not, take those to classes and add them to your project:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="C#" data-enlighter-group="example-class-interface">public interface ICanGiveFeedback
{

    void GiveFeedback();

}

public class Customer : ICanGiveFeedback
{

    public void GiveFeedback()
    {
        // usually you would have some sort
        // of product or service to give feedback
        // on but this is only an example, so...
    }

}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="VB.NET" data-enlighter-group="example-class-interface">Public Interface ICanGiveFeedback

    Sub GiveFeedback()

End Interface

Public Class Customer
    Implements ICanGiveFeedback

    Public Sub GiveFeedback() Implements ICanGiveFeedback.GiveFeedback
        ' usually you would have some sort
        ' of product or service to give feedback
        ' on but this is only an example, so...
    End Sub

End Class</pre>



<h3 class="wp-block-heading">Having the component installed via Visual Studio installer</h3>



<p>Before you can use the following method, make sure that you actually have enabled / installed the corresponding component via the Visual Studio installer executable. Otherwise you wouldn&#8217;t be able to use the shown method / it wouldn&#8217;t be shown to you at all.</p>


<p class="rr-alert info" style="background:#e3f7fc;"><img decoding="async" alt="Info notice" src="https://robbelroot.de/wp-content/themes/pinboard-child/imgs/info.png"><span style="color:black;align-self: center;">Keep in mind, that you need to save your currently open Visual Studio projects, or you won&#8217;t be able to make changes to your installation.</span></p>



<style>
.smaller-margin {
  margin-bottom: 0.2em !important;
}
</style>



<h4 class="wp-block-heading smaller-margin">1. Download the Visual Studio installer</h4>



<p>If you don&#8217;t already have the Visual Studio installer parked on your systems download folder, go ahead and download it again.</p>



<h4 class="wp-block-heading smaller-margin">2. Open the Installer executable</h4>



<p>After downloading (or already having) the Visual Studio installer file, open it and confirm eventual admin prompts. Keep in mind to choose the right one corresponding to your overall used Visual Studio version. I myself never had problems with just using the latest.</p>



<h4 class="wp-block-heading smaller-margin">3. Click the &#8222;modify&#8220; button</h4>



<p>Search for the right version of your Visual Studio installation an click the &#8222;modify&#8220; button on the right side. You will then be able to modify your existing Visual Studio IDE configuration.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/09/Modifying-Visual-Studio-through-the-installer.png"><img loading="lazy" decoding="async" width="816" height="351" src="https://robbelroot.de/wp-content/uploads/2023/09/Modifying-Visual-Studio-through-the-installer.png" alt="Modifying Visual Studio through the installer" class="wp-image-16352" title="Modifying Visual Studio through the installer"/></a><figcaption class="wp-element-caption">Modifying Visual Studio through the installer</figcaption></figure>



<h4 class="wp-block-heading smaller-margin">4. Search for &#8222;class designer&#8220;</h4>



<p>Inside of the &#8222;individual components&#8220; tab, search for the &#8222;class designer&#8220; component and mark it, so it will be a part of our changes. Confirm your selection with the button on the bottom right – this will trigger the change process for your VS installation. If it&#8217;s already installed you will only see a &#8222;close&#8220; button.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/09/Adding-the-Class-Designer-Component-to-the-Visual-Studio-installation.png"><img loading="lazy" decoding="async" width="1195" height="598" src="https://robbelroot.de/wp-content/uploads/2023/09/Adding-the-Class-Designer-Component-to-the-Visual-Studio-installation.png" alt="Adding the Class Designer Component to the Visual Studio installation" class="wp-image-16354" title="Adding the Class Designer Component to the Visual Studio installation"/></a><figcaption class="wp-element-caption">Adding the Class Designer Component to the Visual Studio installation</figcaption></figure>



<h3 class="wp-block-heading">Creating the UML diagram</h3>



<p>If you have finished every previous step, you can now start with the actual process of creating your UML diagram automatically through Visual Studio.</p>



<p><strong>Follow these steps</strong>:</p>



<ol class="wp-block-list">
<li>Right click on your project (or a folder inside of it)</li>



<li>Choose &#8222;Add&#8220;</li>



<li>Select &#8222;New Item&#8230;&#8220;</li>



<li>Search for &#8222;Class Diagram&#8220; and select it</li>



<li>Confirm</li>
</ol>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/09/Adding-a-new-item-to-your-Visual-Studio-project.png"><img loading="lazy" decoding="async" width="783" height="574" src="https://robbelroot.de/wp-content/uploads/2023/09/Adding-a-new-item-to-your-Visual-Studio-project.png" alt="Adding a new item to your Visual Studio project" class="wp-image-16339" title="Adding a new item to your Visual Studio project"/></a><figcaption class="wp-element-caption">Adding a new item to your Visual Studio project</figcaption></figure>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/09/Searching-for-class-diagram-file-inside-of-add-new-item-dialog.png"><img loading="lazy" decoding="async" width="780" height="447" src="https://robbelroot.de/wp-content/uploads/2023/09/Searching-for-class-diagram-file-inside-of-add-new-item-dialog.png" alt="Searching for class diagram file inside of add new item dialog" class="wp-image-16340" title="Searching for class diagram file inside of add new item dialog"/></a><figcaption class="wp-element-caption">Searching for class diagram file inside of add new item dialog</figcaption></figure>



<h3 class="wp-block-heading">Filling the diagram with life</h3>



<p>As you have created your class diagram now, it should look pretty empty, right? No problem! It&#8217;s not a bug, it&#8217;s an actual feature. You can decide which classes, etc. should actually be a part of this specific class diagram! Just play around by dragging and dropping some classes and interfaces on the class diagram &#8222;surface&#8220; like in the image below:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/09/Dragging-and-dropping-classes-and-interfaces-on-the-visual-studio-class-diagram.png"><img loading="lazy" decoding="async" width="845" height="583" src="https://robbelroot.de/wp-content/uploads/2023/09/Dragging-and-dropping-classes-and-interfaces-on-the-visual-studio-class-diagram.png" alt="Dragging and dropping classes and interfaces on the visual studio class diagram" class="wp-image-16349" title="Dragging and dropping classes and interfaces on the visual studio class diagram"/></a><figcaption class="wp-element-caption">Dragging and dropping classes and interfaces on the visual studio class diagram</figcaption></figure>



<h4 class="wp-block-heading">The final result</h4>



<p>In the last step you can take a look at my generated class diagram containing the class and the interface of the example from above. Please don&#8217;t get confused as I used an example project from my mentoring activity:</p>



<figure class="wp-block-image size-full is-resized"><a href="https://robbelroot.de/wp-content/uploads/2023/09/UML-diagram-automatically-generated-by-Visual-Studio.png"><img loading="lazy" decoding="async" src="https://robbelroot.de/wp-content/uploads/2023/09/UML-diagram-automatically-generated-by-Visual-Studio.png" alt="UML diagram automatically generated by Visual Studio" class="wp-image-16360" style="width:446px;height:281px" width="446" height="281" title="UML diagram automatically generated by Visual Studio"/></a><figcaption class="wp-element-caption">UML diagram automatically generated by Visual Studio</figcaption></figure>



<p>As you can see this is quite different from an actual UML diagram – but I think this is the closest you can get with Visual Studio without extensions.</p>



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



<p>See the following posts for more .NET related stuff:</p>



<ul class="wp-block-list">
<li><a href="https://robbelroot.de/blog/rskibbe-core-composition-building-better-and-more-flexible-objects/"><strong>Building better objects with rskibbe.Core.Composition</strong></a></li>



<li><strong><a href="https://robbelroot.de/blog/csharp-bluetooth-example-searching-listing-devices/">Searching and listing bluetooth devices in .NET</a></strong></li>



<li><strong><a href="https://robbelroot.de/blog/the-wpf-listview-control-the-complete-guide/">The WPF ListView Control</a></strong></li>
</ul>
<p>Der Beitrag <a href="https://robbelroot.de/blog/creating-easy-uml-diagrams-with-visual-studio/">Creating easy UML diagrams with Visual Studio</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/creating-easy-uml-diagrams-with-visual-studio/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>The WPF ListView Control – the complete Guide in 2026</title>
		<link>https://robbelroot.de/blog/the-wpf-listview-control-the-complete-guide/</link>
					<comments>https://robbelroot.de/blog/the-wpf-listview-control-the-complete-guide/#comments</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Sun, 08 Jan 2023 22:20:21 +0000</pubDate>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Visual Basic .NET (EN)]]></category>
		<category><![CDATA[basic]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[control]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[foundation]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[item]]></category>
		<category><![CDATA[items]]></category>
		<category><![CDATA[list]]></category>
		<category><![CDATA[listing]]></category>
		<category><![CDATA[listview]]></category>
		<category><![CDATA[mvvm]]></category>
		<category><![CDATA[presentation]]></category>
		<category><![CDATA[repeat]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[vb]]></category>
		<category><![CDATA[vb.net]]></category>
		<category><![CDATA[vbnet]]></category>
		<category><![CDATA[view]]></category>
		<category><![CDATA[visual]]></category>
		<category><![CDATA[visual basic]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[wpf]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=14035</guid>

					<description><![CDATA[<p>The WPF ListView – listing items / things In today&#8217;s post, we are going to talk about one of the most basic controls: The WPF ListView. We will take a look at the different use cases of the ListView and we will try out some of the architectural styles. As &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/the-wpf-listview-control-the-complete-guide/">The WPF ListView Control – the complete Guide in 2026</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/2023/01/WPF-ListView-Control-the-complete-Guide-640px.png"><img loading="lazy" decoding="async" width="640" height="360" src="https://robbelroot.de/wp-content/uploads/2023/01/WPF-ListView-Control-the-complete-Guide-640px.png" alt="WPF ListView Control - the complete Guide" class="wp-image-14042" title="WPF ListView Control - the complete Guide"/></a><figcaption class="wp-element-caption">WPF ListView Control &#8211; the complete Guide</figcaption></figure>






<h2 class="wp-block-heading">The WPF ListView – listing items / things</h2>



<p>In today&#8217;s post, we are going to talk about one of the most basic controls: The WPF ListView. We will take a look at the different use cases of the ListView and we will try out some of the architectural styles. As MVVM is like the &#8222;way to go&#8220; in WPF, I will definitely examine this, but we won&#8217;t forget the &#8222;old way&#8220;. Like always, I will provide different source code examples in the two most used .NET languages, being C# and VB.NET.</p>



<p>This guide and all examples are compatible with .NET 8 and .NET 9.</p>



<p>Speaking of languages: Make sure Visual Studio is set up correctly → <strong><a href="https://robbelroot.de/blog/how-to-change-the-visual-studio-installer-language/" type="post" id="16369">Change VS Installer Language</a></strong>.</p>


<p class="rr-alert info" style="background:#e3f7fc;"><img decoding="async" alt="Info notice" src="https://robbelroot.de/wp-content/themes/pinboard-child/imgs/info.png"><span style="color:black;align-self: center;">Need quick help? Jump to the corresponding sections by using the <a href="#toc_container">table of contents</a>. When you are using the <a href="#code-behind-approach">code behind based approach</a>, jump there. If you are more the MVVM guy, you could jump and start with the <a href="#working-with-real-data">&#8222;MVVM approach&#8220; section</a>.</span></p>



<h2 class="wp-block-heading">What is a WPF ListView?</h2>



<p>When stumbling upon this control, the first question coming to your mind could be: &#8222;Well, what is a ListView – in the Windows Presentation Foundation – in the first place?&#8220;. I mean, by the name, you could just assume, that it&#8217;s something for displaying like a &#8222;list&#8220; of something, right? I mean, you are pretty much on the right side, but what makes it different from like a DataGrid, or even a ListBox? Don&#8217;t worry, we will cover this is a few minutes, further down below.</p>



<h3 class="wp-block-heading">The definition, I guess?</h3>



<p>Let&#8217;s first define, what a ListView really is by like definition:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>A WPF ListView provides the basic tools needed, to help you displaying a set of data items. This can be easily done in like different views or layouts, depending on your usecase. Each item of those ListViews are displayed, using something called ListViewItem. A ListViewItem iteself  is – more or less – just another template-ish element, being a ContentControl.</em></p>
</blockquote>



<h3 class="wp-block-heading">Examining the ListView</h3>



<p>Let&#8217;s take a quick sneak peek into the inheritance-tree, of the WPF ListView Control, by pressing F12, while being on one of those with your mouse cursor. There you can see, that it actually inherits from the class ListBox.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/01/WPF-ListView-Control-Class-inheriting-from-ListBox.png"><img loading="lazy" decoding="async" width="809" height="363" src="https://robbelroot.de/wp-content/uploads/2023/01/WPF-ListView-Control-Class-inheriting-from-ListBox.png" alt="WPF ListView Control Class - inheriting from ListBox" class="wp-image-14056" title="WPF ListView Control Class - inheriting from ListBox"/></a><figcaption class="wp-element-caption">WPF ListView Control Class &#8211; inheriting from ListBox</figcaption></figure>



<h3 class="wp-block-heading">Inheritance tree</h3>



<p>Going further down, there are some other classes in the inheritance tree as well, like the Selector &amp; the ItemsControl class. I think, for most persons, it&#8217;s actually a surprise / a &#8222;good to know&#8220;-thing, that the ListView actually inherits from the ListBox class.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/01/WPF-ListView-Inheritance-Tree-640px.png"><img loading="lazy" decoding="async" width="640" height="360" src="https://robbelroot.de/wp-content/uploads/2023/01/WPF-ListView-Inheritance-Tree-640px.png" alt="WPF ListView Inheritance Tree" class="wp-image-14088" title="WPF ListView Inheritance Tree"/></a><figcaption class="wp-element-caption">WPF ListView Inheritance Tree</figcaption></figure>



<p>At this point, you can see, that there&#8217;s pretty much going on in the background. The ListView itself is actually derived from a few levels of control hierarchy and is therefore bringing a lot &#8222;to the table&#8220;. For sure, we can&#8217;t go to every level in detail, but I think the most important ones for you are beginning at the ItemsControl.</p>



<p>I mean, in a real application scenario, you would most likely fetch some data like the &#8222;charts&#8220; or something like that. Those could then be displayed inside your ListView by specifying what should actually appear. The chart object could be composed from many different objects and therefore you would need to specify a bit further. </p>



<h2 class="wp-block-heading" id="code-behind-approach">A first example – with XAML &amp; code behind</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/01/A-first-WPF-ListView-example-–-hardcoded-in-XAML-640px.png"><img loading="lazy" decoding="async" width="640" height="360" src="https://robbelroot.de/wp-content/uploads/2023/01/A-first-WPF-ListView-example-–-hardcoded-in-XAML-640px.png" alt="A first WPF ListView example – hardcoded in XAML" class="wp-image-14094" title="A first WPF ListView example – hardcoded in XAML"/></a><figcaption class="wp-element-caption">A first WPF ListView example – hardcoded in XAML</figcaption></figure>



<p>Let&#8217;s now focus on creating an actual first example of the ListView Control. To do so, we usually need to first have some kind of data to display. At this point, we will just create some hardcoded items, to see, how the ListView and its ListViewItems are created in the first place. Keep in mind, that we will do this and more in an MVVM manner, later – which is the preferred way for me personally.</p>



<p>We will surround the ListView by a GroupBox Control, to have some kind of labelling, etc. So go ahead and create a GroupBox XAML markup inside your MainWindow.xaml (inside the root Grid). You can write something like &#8222;Music stars&#8220;, etc. inside the Header Property of that GroupBox, like this, we have some kind of heading for our list.</p>



<p>After that, we can add some sort of styling like padding, a width and alignments to that GroupBox, to make it look less bruised. The final, but first testing XAML code could therefore look like this:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    &lt;Grid>
        &lt;GroupBox Header="Some items" Padding="8" Width="200" VerticalAlignment="Center" HorizontalAlignment="Center">
            &lt;ListView>
                &lt;ListView.Items>
                    &lt;ListViewItem Content="Jimmy Hendrix" />
                    &lt;ListViewItem Content="Michael Jackson" />
                    &lt;ListViewItem Content="The Beatles" />
                &lt;/ListView.Items>
            &lt;/ListView>
        &lt;/GroupBox>
    &lt;/Grid></pre>



<p>The visual representation of that XAML code from above, will just look as simple as this.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/01/WPF-ListView-–-Displaying-Music-stars-as-simple-list.png"><img loading="lazy" decoding="async" width="789" height="449" src="https://robbelroot.de/wp-content/uploads/2023/01/WPF-ListView-–-Displaying-Music-stars-as-simple-list.png" alt="ListView – Displaying Music stars as simple list" class="wp-image-14099" title="ListView – Displaying Music stars as simple list"/></a><figcaption class="wp-element-caption">WPF ListView – Displaying Music stars as simple list</figcaption></figure>



<h3 class="wp-block-heading">How to add items to the WPF ListView?</h3>



<p>To add some items to the ListView in a &#8222;code behind&#8220;-manner, we need to specify a usual handler for like the click event, of for example a button. We can then react to that click inside of the handler and actually add a new item to the ListView. Go ahead and add a button inside of your MainWindow (Grid) and specify the &#8222;Click&#8220;-Property.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;Button Click="Button_Click" /></pre>



<p>It will suggest, to create an actual handler, you can confirm this and press F12 while being on the &#8222;Button_Click&#8220; text. After that, it will automatically jump to the corresponding part in your code – the code behind file. Feel free to rename that handler (in XAML &amp; code) to pick a better name, like &#8222;btnAddItem_Click&#8220;.</p>



<p>Inside of the click handler, we need to somehow say: &#8222;Hey, ListView, please remove an item!&#8220;. And we are only able to do so, if we have something to talk to. Currently, the ListView doesn&#8217;t have a name, so you should go back and specify a name for it:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;ListView x:Name="MusicArtistList" ....>
    &lt;!-- .... -->
&lt;/ListView></pre>



<p>The button click handler itself could just look like the following. We are just telling the property of the &#8222;MusicArtistList&#8220;, called &#8222;Items&#8220;: &#8222;Hey, please add another entry to yourself, thanks!&#8220;.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="C#" data-enlighter-group="btn-add-item-code-behind">    private void Button_Click(object sender, RoutedEventArgs e)
    {
        MusicArtistList.Items.Add("Sam Smith");
    }</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="VB.NET" data-enlighter-group="btn-add-item-code-behind">    Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
        MusicArtistList.Items.Add("Sam Smith")
    End Sub</pre>



<h3 class="wp-block-heading">How to remove items from the ListView again?</h3>



<p>If you have followed the above steps to actually add an item inside of our ListView, then you could be ready to remove it again. Keep in mind, that you should have like the click handler ready (by specifying the Buttons click property with like &#8222;btnRemove_Click&#8220;) and that the ListView needs a name. Otherwise, we wouldn&#8217;t be able to target it from the code behind file.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="C#" data-enlighter-group="btn-remove-item-code-behind">    private void btnRemove_Click(object sender, RoutedEventArgs e)
    {
        // this only works that easy due to our current "strings" example
        MusicArtistList.Items.Remove("Sam Smith");
    }</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="VB.NET" data-enlighter-group="btn-remove-item-code-behind">    Private Sub btnRemove_Click(sender As Object, e As RoutedEventArgs)
        ' this only works that easy due to our current "strings" example
        MusicArtistList.Items.Remove("Sam Smith")
    End Sub</pre>



<h3 class="wp-block-heading">How to delete the selected item in the ListView?</h3>



<p>This one here is a bit different, because we can&#8217;t know at compile time, which one of the items, the user will select. We can&#8217;t therefore hardcode like a specific string thing, to be deleted later. We need a possibility, to get the currently selected item and delete it somehow.</p>



<p>This is actually pretty easy, as we get everything we need to know, from the ListView itself. We will first check, if there&#8217;s an actual selection and if so, we will delete that item by providing its index.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="C#" data-enlighter-group="btn-remove-selecteditem-code-behind">    private void btnRemoveSelectedItem_Click(object sender, RoutedEventArgs e)
    {
        bool noItemSelected = MusicArtistList.SelectedIndex == -1;
        if (noItemSelected)
            return;
        MusicArtistList.Items.RemoveAt(MusicArtistList.SelectedIndex);
    }</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="VB.NET" data-enlighter-group="btn-remove-selecteditem-code-behind">Private Sub btnRemoveSelectedItem_Click(sender As Object, e As RoutedEventArgs)
    Dim noItemSelected As Boolean = MusicArtistList.SelectedIndex = -1
    If noItemSelected Then
        Return
    End If
    MusicArtistList.Items.RemoveAt(MusicArtistList.SelectedIndex)
End Sub</pre>



<h3 class="wp-block-heading">Okay, but not flexible, nor practical – imo</h3>



<p>So in the end, we just created a small ListView representation with like 3 entries for our music stars / artists. Currently, this isn&#8217;t really good, as it&#8217;s not dynamic or based on &#8222;real data&#8220;. We just hardcoded those ListViewItems inside the ListView and this isn&#8217;t pretty much practical.</p>



<p>The other problem with our current example is, that it&#8217;s not pretty flexible, currently we are having only like &#8222;1 Column&#8220;. With that, we can only display one &#8222;thing&#8220; per item and we are not really different from a ListBox. What if we wanted to publish some sort of &#8222;year of birth&#8220; information? I mean sure, we could just pump it into one string, but nah, that doesn&#8217;t feel right.</p>



<p>What we really need are some sort of columns and guess what, the ListView supports this out of the box, by just specifying the View property.</p>



<div style="box-sizing:border-box;margin:36px 0;border-radius:12px;overflow:hidden;background:#1a1a2e;position:relative;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;">
  <div style="position:absolute;inset:0;background-image:linear-gradient(rgba(255,255,255,0.03) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,0.03) 1px,transparent 1px);background-size:40px 40px;pointer-events:none;"></div>
  <div style="position:absolute;top:-60px;right:-60px;width:240px;height:240px;background:radial-gradient(circle,rgba(230,126,34,0.18) 0%,transparent 70%);pointer-events:none;"></div>
  <div style="position:relative;padding:32px 28px;">
    <div style="display:inline-block;font-size:11px;font-weight:700;letter-spacing:2.5px;text-transform:uppercase;color:#e67e22;margin-bottom:14px;border:1px solid rgba(230,126,34,0.35);border-radius:4px;padding:3px 10px;">Need a WPF developer?</div>
    <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Got a WPF project that needs professional hands?</p>
    <p style="margin:0 0 24px 0;font-size:14px;color:rgba(255,255,255,0.65);line-height:1.7;max-width:540px;">I build WPF applications with clean MVVM architecture in C# and VB.NET — professionally and efficiently. Just send me a message.</p>
    <div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;">
      <a href="https://robbelroot.de/contact/" style="display:inline-block;padding:12px 24px;background:#e67e22;color:#ffffff;font-size:14px;font-weight:700;text-decoration:none;border-radius:7px;white-space:nowrap;" onmouseover="this.style.background='#cf6d17'" onmouseout="this.style.background='#e67e22'">→ Get in touch</a>
    </div>
  </div>
</div>



<h2 class="wp-block-heading" id="working-with-real-data">Working with &#8222;real data&#8220; – MVVM approach</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/01/Working-with-a-databound-ListView-–-dynamic-data-640px.png"><img loading="lazy" decoding="async" width="640" height="360" src="https://robbelroot.de/wp-content/uploads/2023/01/Working-with-a-databound-ListView-–-dynamic-data-640px.png" alt="Working with a databound ListView – dynamic data" class="wp-image-14110" title="Working with a databound ListView – dynamic data"/></a><figcaption class="wp-element-caption">Working with a databound ListView – dynamic data</figcaption></figure>



<p>Moving away from that unpractical non-databased &#8222;stringish&#8220; approach from above, we will now start a newer, clean version of our ListView Control. But first, we need to actually define &#8222;what&#8220; to display, I mean, we need some sort of a so called &#8222;Model&#8220; (or even a ViewModel – but I&#8217;ll leave it at that for now). As we wanted to display some sort of &#8222;music star&#8220;-overview, we could think of a better term in the first place. I will call it list of artists, so let&#8217;s now <strong>create a new class called &#8222;MusicArtist&#8220;</strong> inside a matching folder.</p>



<p>Go ahead and <strong>create the corresponding folder</strong> inside your WPF project, first. We will call that folder like &#8222;<strong>Models</strong>&#8220; – remember, I don&#8217;t want to go too deep into the MVVM cosmos. I would encourage you to <strong><a href="https://robbelroot.de/blog/mvvm-csharp/" target="_blank" rel="noreferrer noopener">refer to my C# MVVM post</a></strong> for that and don&#8217;t be confused, it will for work VB.NET as well. I mean the characteristics of Model-View-ViewModel are in the focus, not the language itself :).</p>



<h3 class="wp-block-heading">The &#8222;MusicArtist&#8220; model class</h3>



<p>Thinking about the class itself and keeping our example from above in mind, we could say, that a music artist has the following properties. For sure, it&#8217;s just for our example and I&#8217;m trying to stay as easy as possible, so feel free to change anything you would like to.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MusicArtist.cs" data-enlighter-group="artist-class">using System;

namespace WpfListViewExampleCs.Models;

public class MusicArtist
{

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public DateTime Birthday { get; set; }

    public MusicArtist(string firstName, string lastName, DateTime birthday)
    {
        FirstName = firstName;
        LastName = lastName;
        Birthday = birthday;
    }
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MusicArtist.vb" data-enlighter-group="artist-class">Imports System

Namespace WpfListViewExampleCs.Models

    Public Class MusicArtist

        Public Property FirstName As String

        Public Property LastName As String

        Public Property Birthday As DateTime

        Public Sub New(firstName As String, lastName As String, birthday As DateTime)
            Me.FirstName = firstName
            Me.LastName = lastName
            Me.Birthday = birthday
        End Sub

    End Class

End Namespace</pre>



<p>In my example here, the music artist has two properties for the name, meaning a first- and a lastname. I don&#8217;t like the &#8222;name&#8220; only approach, as you can&#8217;t easily separate the names in some situations. Well, I mean yeah, before you mention it: &#8222;The Beatles&#8220; isn&#8217;t really nicely separatable in this manner, but, welcome to the world of software development. I would say, this isn&#8217;t the right moment to argue about this, so feel free – again – to change that as you wish. Additionally I thought about using the birthday property, to show some sort of formatting in the XAML as well.</p>



<h2 class="wp-block-heading">Displaying bound data inside the WPF ListView</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/01/Displaying-bound-data-inside-the-WPF-ListView-640px.png"><img loading="lazy" decoding="async" width="640" height="360" src="https://robbelroot.de/wp-content/uploads/2023/01/Displaying-bound-data-inside-the-WPF-ListView-640px.png" alt="Displaying bound data inside the ListView" class="wp-image-14135" title="Displaying bound data inside the ListView"/></a><figcaption class="wp-element-caption">Displaying bound data inside the WPF ListView</figcaption></figure>



<p>After specifying some kind of model to actually display inside the ListView, we now go ahead and tell the ListView about its datasource. The ListView will then know: &#8222;Where can I fetch my data from? What is my data?&#8220;.</p>



<h3 class="wp-block-heading">Preventing a known error</h3>



<p>But before, we need to clean up the old code, otherwise we could run into an error like this:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>System.InvalidOperationException: &#8222;The items collection must be empty before using itemssource&#8220;</em></p>
</blockquote>



<p>To avoid this error, you need to remove the manually added items inside our XAML code. You can&#8217;t like say: &#8222;Hey, fetch the items from this datasource here&#8220; AND put them in manually by XAML. Please go ahead and remove this marked area from the XAML code:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/01/Removing-the-hardcoded-XAML-Items-from-the-ListView.png"><img loading="lazy" decoding="async" width="526" height="201" src="https://robbelroot.de/wp-content/uploads/2023/01/Removing-the-hardcoded-XAML-Items-from-the-ListView.png" alt="Removing the hardcoded XAML Items from the ListView" class="wp-image-14130" title="Removing the hardcoded XAML Items from the ListView"/></a><figcaption class="wp-element-caption">Removing the hardcoded XAML Items from the ListView</figcaption></figure>



<h3 class="wp-block-heading">Giving the ListView its datasource</h3>



<p>In the next step, we will actually care for some items being displayed. For this, we will <strong>use the DataSource property of the ListView</strong> and bind to some property from our ViewModel. Don&#8217;t be scared, if you don&#8217;t know what a ViewModel is! Maybe this is another chance, to refer to <strong><a href="https://robbelroot.de/blog/mvvm-csharp/" target="_blank" rel="noreferrer noopener">my blog post considering the MVVM pattern</a></strong>.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;ListView ItemsSource="{Binding MusicArtists}">
&lt;!-- rest of the listview.. -->
&lt;/ListView></pre>



<p>We won&#8217;t create a separate ViewModel right now, for this simple example, we will use the MainWindow itself. This is pretty much easier at this point and it won&#8217;t push you too far away from the actual topic. Never the less, we still need a bindable property inside our MainWindow, which we are going to create, now.</p>



<h3 class="wp-block-heading">Creating a bindable property</h3>



<p>To create the announced property, just build some normal property inside your MainWindow (for example) called &#8222;MusicArtists&#8220;. This could look like the following code, keep in mind, that we should use something which implements the &#8222;INotifyCollectionChanged&#8220; interface. But yes, I hear you, this should be a topic for another blog post, so just take it like that for now.</p>



<p>Next, create that property called &#8222;MusicArtists&#8220; of type of &#8222;ObservableCollection&#8220;, with the generic type argument &#8222;MusicArtist&#8220;. We could also just make it like readonly, but those are fine tuning things, which aren&#8217;t necessary right now.</p>



<p>The last important step is, to say: &#8222;Hey, MainWindow, your DataContext is actually.. you!&#8220;. Then the MainWindow will know where to find the corresponding &#8222;MusicArtists&#8220;, which we are going to bind very soon from the XAML side. Take a look at the following example XAML code:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MainWindow.xaml.cs" data-enlighter-group="datasource-init">using System;
using System.Collections.ObjectModel;
using System.Windows;
using WpfListViewExampleCs.Models;

namespace WpfListViewExampleCs;

/// &lt;summary>
/// Interaction logic for MainWindow.xaml
/// &lt;/summary>
public partial class MainWindow : Window
{

    public ObservableCollection&lt;MusicArtist> MusicArtists { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        MusicArtists = new ObservableCollection&lt;MusicArtist>();
        DataContext = this;
    }
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MainWindow.xaml.vb" data-enlighter-group="datasource-init">Imports System
Imports System.Collections.ObjectModel
Imports System.Windows
Imports WpfListViewExampleCs.Models

Namespace WpfListViewExampleCs

    Public Partial Class MainWindow
        Inherits Window

        Public Property MusicArtists As ObservableCollection(Of MusicArtist)

        Public Sub New()
            InitializeComponent()
            MusicArtists = New ObservableCollection(Of MusicArtist)()
            DataContext = Me
        End Sub

    End Class

End Namespace</pre>



<h3 class="wp-block-heading">Filling up some data</h3>



<p>Currently, the ListView wouldn&#8217;t be able to display much, because there just aren&#8217;t no items inside the &#8222;MusicArtists&#8220;, yet. So in the next step we are going to fill up some items, to make the ListView be able to display those. This is the reason, why we added a quick constructor inside the &#8222;MusicArtist&#8220; class: Creating quick example artists.</p>



<p>Let&#8217;s re-create the MainWindow constructor for this:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MainWindow.xaml.cs" data-enlighter-group="filling-data">// rest of the MainWindow code behind file

    public MainWindow()
    {
        InitializeComponent();
        MusicArtists = new ObservableCollection&lt;MusicArtist>();
        MusicArtists.Add(new MusicArtist("Jimmy", "Hendrix", new DateTime(1942, 11, 27)));
        MusicArtists.Add(new MusicArtist("Michael", "Jackson", new DateTime(1958, 8, 29)));
        MusicArtists.Add(new MusicArtist("The", "Beatles", new DateTime(1960, 1, 1)));
        DataContext = this;
    }

// rest of the MainWindow code behind file</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MainWindow.xaml.vb" data-enlighter-group="filling-data">' rest of the MainWindow code behind file

Public Sub New()
    InitializeComponent()
    MusicArtists = New ObservableCollection(Of MusicArtist)()
    MusicArtists.Add(New MusicArtist("Jimmy", "Hendrix", New DateTime(1942, 11, 27)))
    MusicArtists.Add(New MusicArtist("Michael", "Jackson", New DateTime(1958, 8, 29)))
    MusicArtists.Add(New MusicArtist("The", "Beatles", New DateTime(1960, 1, 1)))
    DataContext = Me
End Sub

' rest of the MainWindow code behind file</pre>



<h3 class="wp-block-heading">But it&#8217;s displaying rubbish now?</h3>



<p>If you are looking at the current results, you would pretty much only see rubbish. If you didn&#8217;t look until now, please watch the following screenshot, then you probably will. The items are more or less being displayed, but there&#8217;s only something like &#8222;Blabla.Bla.MusicArtist&#8220; written.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/01/Bound-ListView-Items-without-Column-Bindings-1.png"><img loading="lazy" decoding="async" width="454" height="178" src="https://robbelroot.de/wp-content/uploads/2023/01/Bound-ListView-Items-without-Column-Bindings-1.png" alt="Bound ListView Items displaying rubbish without Column Bindings" class="wp-image-14159" title="Bound ListView Items displaying rubbish without Column Bindings"/></a><figcaption class="wp-element-caption">Bound ListView Items displaying rubbish without Column Bindings</figcaption></figure>



<p>The reason for that is, that the corresponding ListViewItem actually knows: &#8222;Hey, there is something called MusicArtist&#8220;. But it&#8217;s also asking itself: &#8222;well, how am I supposed to display this? Property A, B, C, WHAT!?&#8220;. In the end it thinks: &#8222;You know what, dev? I&#8217;m just going to display THAT over here&#8220;.</p>



<p>By &#8222;that&#8220; I&#8217;m meaning the complete path to the corresponding class instance type. We are having a class called &#8222;MusicArtist&#8220; inside our project called &#8222;WpfListViewExampleCs&#8220; AND inside the &#8222;Models&#8220; namespace. So this is basically why that &#8222;rubbish&#8220; comes out of it, it displays the complete namespace to class path!</p>



<h3 class="wp-block-heading">Overriding that &#8222;default-rubbish&#8220;</h3>



<p>Before we are going to use the final solution for this, I first want to explain and show you, how you could potentially solve it at this point. Please keep in mind, that this solution depends on your usecase! Usually, if you want to display like &#8222;multiple columns&#8220;, you would actually need – well – multiple columns.</p>



<p>In the image from above, you are seeing the <strong><a href="https://learn.microsoft.com/en-us/dotnet/api/system.object.tostring?view=net-9.0" target="_blank" rel="noreferrer noopener">default object class &#8222;ToString&#8220;</a></strong> output. To change it, you can just override it in your derived class – being the &#8222;MusicArtist&#8220;-class like in a second. Hint: I&#8217;m using the newer, shorter version of the overriding functionality. This means, no body parantheses and an arrow (for C#), as well as string interpolation (for both languages).</p>



<p>You could add this to the &#8222;MusicArtist&#8220; class:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MusicArtist.cs" data-enlighter-group="override-musicartist-tostring">// rest of the MusicArtist class

public override string ToString()
    => $"{FirstName} {LastName}";

// rest of the MusicArtist class</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MusicArtist.vb" data-enlighter-group="override-musicartist-tostring">' rest of the MusicArtist class

Public Overrides Function ToString() As String
    Return $"{FirstName} {LastName}"
End Function

' rest of the MusicArtist class</pre>



<p>So the current / new output would look like this:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/01/Bound-ListView-Items-with-overriden-ToString-Function.png"><img loading="lazy" decoding="async" width="354" height="210" src="https://robbelroot.de/wp-content/uploads/2023/01/Bound-ListView-Items-with-overriden-ToString-Function.png" alt="Bound ListView Items with overriden ToString Function" class="wp-image-14168" title="Bound ListView Items with overriden ToString Function"/></a><figcaption class="wp-element-caption">Bound ListView Items with overriden ToString Function</figcaption></figure>



<h2 class="wp-block-heading">Using the ListViews &#8222;View&#8220; Property creating columns</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/01/Creating-columns-using-the-ListView-View-Property-640px.png"><img loading="lazy" decoding="async" width="640" height="360" src="https://robbelroot.de/wp-content/uploads/2023/01/Creating-columns-using-the-ListView-View-Property-640px.png" alt="Creating columns using the ListView View Property" class="wp-image-14218" title="Creating columns using the ListView View Property"/></a><figcaption class="wp-element-caption">Creating columns using the ListView View Property</figcaption></figure>



<p>After cleaning up that &#8222;namespace and class&#8220;-mess we saw in the last section, we now can go the last step (I think). Currently, our ListView is only displaying some kind of single dimensioned data, which is not thaaaat bad, but I guess bad for multi-dimensioned data? What if I wanted to have some sort of separated columns for first and last name? This is exactly, where the so called &#8222;View&#8220;-property of the WPF ListView comes into play!</p>



<h3 class="wp-block-heading">But why a ListView, why no DataGrid instead?</h3>



<p>Sure, you could ask yourself: &#8222;Why would I use a ListView, when I could use a DataGrid instead?&#8220;. The answer is: &#8222;It depends&#8220;, yeah, I hate those answers as well.. Usually there&#8217;s one rule floating around in the internet: Use a DataGrid, if you need editing, use a ListView otherwise – bang. I would pretty much love going deeper into this topic, but well, I think this post is already too big, isn&#8217;t it?</p>



<h3 class="wp-block-heading">Specifying a &#8222;View&#8220;-template</h3>



<p>To start creating those columns we talked about, we need to specify some sort of template for the View property. But it&#8217;s not a usual &#8222;DataTemplate&#8220;, it&#8217;s something more special, lemme give you an example. The basic view provided from WPF itself, is something called a &#8222;GridView&#8220;. I mean, the name pretty much suggests what it is. If needed, you could create something similiar for your own needs, but again, I think this would blow up this post even more..</p>



<div style="box-sizing:border-box;margin:36px 0;border-radius:12px;overflow:hidden;background:#1a1a2e;position:relative;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;">
  <div style="position:absolute;inset:0;background-image:linear-gradient(rgba(255,255,255,0.03) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,0.03) 1px,transparent 1px);background-size:40px 40px;pointer-events:none;"></div>
  <div style="position:absolute;top:-60px;right:-60px;width:240px;height:240px;background:radial-gradient(circle,rgba(230,126,34,0.18) 0%,transparent 70%);pointer-events:none;"></div>
  <div style="position:relative;padding:32px 28px;">
    <div style="display:inline-block;font-size:11px;font-weight:700;letter-spacing:2.5px;text-transform:uppercase;color:#e67e22;margin-bottom:14px;border:1px solid rgba(230,126,34,0.35);border-radius:4px;padding:3px 10px;">Need a WPF developer?</div>
    <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Got a WPF project that needs professional hands?</p>
    <p style="margin:0 0 24px 0;font-size:14px;color:rgba(255,255,255,0.65);line-height:1.7;max-width:540px;">I build WPF applications with clean MVVM architecture in C# and VB.NET — professionally and efficiently. Just send me a message.</p>
    <div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;">
      <a href="https://robbelroot.de/contact/" style="display:inline-block;padding:12px 24px;background:#e67e22;color:#ffffff;font-size:14px;font-weight:700;text-decoration:none;border-radius:7px;white-space:nowrap;" onmouseover="this.style.background='#cf6d17'" onmouseout="this.style.background='#e67e22'">→ Get in touch</a>
    </div>
  </div>
</div>



<p>So let&#8217;s stick with the basic GridView for now. Back into your MVVM prepared ListView, we can now provide a GridView template for our ListView. Watch out for that nice string format functionality, where I specified a custom format for that birthday binding. Basically all you have to do is, providing the columns you want, with a header of your choice. Then you need to tell the ListViewItem, where it should pull the data from (being the DisplayMemberPath-Binding).</p>



<pre class="EnlighterJSRAW" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">            &lt;ListView ItemsSource="{Binding MusicArtists}">
                &lt;ListView.View>
                    &lt;GridView>
                        &lt;GridView.Columns>
                            &lt;GridViewColumn Header="FirstName" DisplayMemberBinding="{Binding FirstName}" />
                            &lt;GridViewColumn Header="LastName" DisplayMemberBinding="{Binding LastName}" />
                            &lt;GridViewColumn Header="Birthday" DisplayMemberBinding="{Binding Birthday, StringFormat={}{0:dd.MM.yyyy}}" />
                        &lt;/GridView.Columns>
                    &lt;/GridView>
                &lt;/ListView.View>
            &lt;/ListView></pre>



<p>And finally, you end up having this nice thing here:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/01/WPF-ListView-with-specified-View-Property-as-GridView.png"><img loading="lazy" decoding="async" width="505" height="268" src="https://robbelroot.de/wp-content/uploads/2023/01/WPF-ListView-with-specified-View-Property-as-GridView.png" alt="WPF ListView with specified View Property as GridView" class="wp-image-14226" title="WPF ListView with specified View Property as GridView"/></a><figcaption class="wp-element-caption">WPF ListView with specified View Property as GridView</figcaption></figure>



<h3 class="wp-block-heading">Adding, removing, etc. the MVVM way – preparations</h3>



<p>Because it&#8217;s a bit harder, I saved this topic (and other) for the end of this blog post. You actually need some sort of &#8222;ICommand&#8220; implementation, which we won&#8217;t cover here, but I will give you the example code needed. There will be another blog post about those commands in english, currently, it&#8217;s only available in german, sorry.</p>



<h3 class="wp-block-heading">A DelegateCommand base class</h3>



<p>Please go ahead and <strong>create another folder inside your project</strong>, called &#8222;<strong>Utils</strong>&#8222;. We will deposit a small class over there, which helps us with the buttons in MVVM style. The class I&#8217;m talking about looks like this, it&#8217;s a basic implementation of a delegated action (with check) for the <strong><a href="https://learn.microsoft.com/en-US/dotnet/api/system.windows.input.icommand?view=net-9.0" target="_blank" rel="noreferrer noopener">ICommand-interface</a></strong>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="DelegateCommand.cs" data-enlighter-group="delegate-command">using System.Windows.Input;
using System;

namespace Utils
{
    public class DelegateCommand : ICommand
    {
        private Action&lt;object?> _action;

        private Func&lt;object?, bool>? _canExecute;

        public DelegateCommand(Action&lt;object?> action)
        {
            _action = action;
        }

        public DelegateCommand(Action&lt;object?> action, Func&lt;object?, bool> canExecute)
        {
            _action = action;
            _canExecute = canExecute;
        }

        public void Execute(object? parameter)
        {
            _action(parameter);
        }

        public bool CanExecute(object? parameter)
        {
            if (_canExecute == null)
                return true;
            return _canExecute(parameter);
        }

        public void RaiseCanExecuteChanged()
        {
            CanExecuteChanged?.Invoke(this, EventArgs.Empty);
        }

        public event EventHandler? CanExecuteChanged;
    }
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="DelegateCommand.vb" data-enlighter-group="delegate-command">Namespace Utils
    Public Class DelegateCommand
        Implements ICommand
        Private _action As Action(Of Object)
        Private _canExecute As Func(Of Object, Boolean)
        Sub New(action As Action(Of Object))
            _action = action
        End Sub
        Sub New(action As Action(Of Object), canExecute As Func(Of Object, Boolean))
            _action = action
            _canExecute = canExecute
        End Sub
        Public Sub Execute(parameter As Object) Implements ICommand.Execute
            ' führt unsere von außen mitgegebene Aktion aus und übergibt auch den Parameter
            _action(parameter)
        End Sub
        Public Function CanExecute(parameter As Object) As Boolean Implements ICommand.CanExecute
            If _canExecute Is Nothing Then
                Return True
            End If
            Return _canExecute(parameter)
        End Function
        Public Event CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged
    End Class
End Namespace</pre>



<h3 class="wp-block-heading">A PropertyChangedBase class</h3>



<p>Without going into too much detail, please copy this class and put it into the &#8222;Utils&#8220; folder as well. There is <strong><a href="https://robbelroot.de/blog/der-ultimative-inotifypropertychanged-guide/" target="_blank" rel="noreferrer noopener">a blog post for the INotifyPropertyChanged-interface</a></strong>, but <strong>currently it&#8217;s only in german</strong>. Maybe you could use a browser-translator for now, but I will add the english version soon. So now, please take this class:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="PropertyChangedBase.cs" data-enlighter-group="property-changed-base">using System.Runtime.CompilerServices;
using System.ComponentModel;

namespace Utils;

public abstract class PropertyChangedBase : INotifyPropertyChanged
{
    protected void NotifyOfPropertyChange([CallerMemberName] string? propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler? PropertyChanged;
}</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="PropertyChangedBase.vb" data-enlighter-group="property-changed-base">Imports System.ComponentModel
Imports System.Runtime.CompilerServices

Namespace Utils

    Public Class PropertyChangedBase
        Implements INotifyPropertyChanged

        Protected Sub NotifyOfPropertyChange(&lt;CallerMemberName> Optional propertyName As String = Nothing)
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
        End Sub

        Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

    End Class

End Namespace</pre>



<h3 class="wp-block-heading">Corresponding buttons</h3>



<p>Please add something like a StackPanel and 3 Buttons inside of it. There will be one button for adding and one for removing an item at a specific position. The third button will be for removing the selected item. At this point, we will also those commands, please have a look at the following XAML. Please pardon me for not making this visually appealing, it&#8217;s only for its functional purpose.</p>



<p>Keep in mind, that you also need to create 3 new properties of type of &#8222;DelegateCommand&#8220;, 1 for each command, being:</p>



<ul class="wp-block-list">
<li>AddItemCommand</li>



<li>RemoveItemCommand</li>



<li>RemoveItemAtIndexCommand</li>
</ul>



<pre class="EnlighterJSRAW" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">        &lt;GroupBox Header="Music stars" Padding="8" Width="400" VerticalAlignment="Center" HorizontalAlignment="Center">
            &lt;StackPanel>
                &lt;ListView SelectedItem="{Binding SelectedMusicArtist}" ItemsSource="{Binding MusicArtists}">
                    &lt;ListView.View>
                        &lt;GridView>
                            &lt;GridView.Columns>
                                &lt;GridViewColumn Header="FirstName" DisplayMemberBinding="{Binding FirstName}" />
                                &lt;GridViewColumn Header="LastName" DisplayMemberBinding="{Binding LastName}" />
                                &lt;GridViewColumn Header="Birthday" DisplayMemberBinding="{Binding Birthday, StringFormat={}{0:dd.MM.yyyy}}" />
                            &lt;/GridView.Columns>
                        &lt;/GridView>
                    &lt;/ListView.View>
                &lt;/ListView>
                &lt;StackPanel Orientation="Horizontal" Margin="0 12 0 0" HorizontalAlignment="Right">
                    &lt;Button Command="{Binding AddItemCommand}" Content="Add item" Margin="0 0 8 0" />
                    &lt;Button Command="{Binding RemoveItemCommand}" Content="Remove item" Margin="0 0 8 0" />
                    &lt;Button Command="{Binding RemoveItemAtIndexCommand}" Content="Remove item at index" />
                &lt;/StackPanel>
            &lt;/StackPanel>
        &lt;/GroupBox></pre>



<p>The &#8222;new&#8220; UI now looks like this:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2023/01/WPF-ListView-MVVM-based-UI-1.png"><img loading="lazy" decoding="async" width="477" height="250" src="https://robbelroot.de/wp-content/uploads/2023/01/WPF-ListView-MVVM-based-UI-1.png" alt="MVVM based UI" class="wp-image-14269" title="MVVM based UI"/></a><figcaption class="wp-element-caption">MVVM based UI</figcaption></figure>



<h3 class="wp-block-heading">The MainViewModel</h3>



<p>Now create a new folder called &#8222;ViewModels&#8220; and a &#8222;MainViewModel&#8220; class inside. Let the &#8222;MainViewModel&#8220; class inherit from the &#8222;PropertyChangedBase&#8220; you copied from the previous paragraph. The view (code behind) file should now be abandoned as it&#8217;s getting too much otherwise.</p>



<p>Over here we fully implemented the &#8222;SelectedMusicArtist&#8220;-property to actually tell the &#8222;RemoveItemCommand&#8220;: &#8222;Hey, here was something selected, check if you can be executed now&#8220;. We&#8217;re  subscribing to the &#8222;CollectionChanged&#8220; event of the ObservableCollection as well. This way, we can also refresh the commands state, when the collection is changed.</p>



<p>In the next steps, we are going to instantiate the commands and therefore telling them, what to do and when.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MainViewModel.cs" data-enlighter-group="the-main-view-model">using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using Utils;
using WpfListViewExampleCs.Models;

namespace WpfListViewExampleCs.ViewModels;

public class MainViewModel : PropertyChangedBase
{

    public ObservableCollection&lt;MusicArtist> MusicArtists { get; set; }

    private MusicArtist? _selectedMusicArtist;

    public MusicArtist? SelectedMusicArtist
    {
        get => _selectedMusicArtist;
        set
        {
            if (_selectedMusicArtist == value)
                return;
            _selectedMusicArtist = value;
            RemoveItemCommand.RaiseCanExecuteChanged();
        }
    }

    public DelegateCommand AddItemCommand { get; set; }

    public DelegateCommand RemoveItemCommand { get; set; }

    public DelegateCommand RemoveItemAtIndexCommand { get; set; }

    public MainViewModel()
    {
        MusicArtists = new ObservableCollection&lt;MusicArtist>();
        MusicArtists.CollectionChanged += MusicArtists_CollectionChanged;
        MusicArtists.Add(new MusicArtist("Jimmy", "Hendrix", new DateTime(1942, 11, 27)));
        MusicArtists.Add(new MusicArtist("Michael", "Jackson", new DateTime(1958, 8, 29)));
        MusicArtists.Add(new MusicArtist("The", "Beatles", new DateTime(1960, 1, 1)));
    }

    private void MusicArtists_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
    {
        RemoveItemCommand.RaiseCanExecuteChanged();
        RemoveItemAtIndexCommand.RaiseCanExecuteChanged();
    }

}
</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MainWindow.xaml.vb" data-enlighter-group="the-main-view-model">Imports System
Imports System.Collections.ObjectModel
Imports System.Collections.Specialized
Imports Utils
Imports WpfListViewExampleCs.Models

Namespace WpfListViewExampleCs.ViewModels

    Public Class MainViewModel
        Inherits PropertyChangedBase

        Public Property MusicArtists As ObservableCollection(Of MusicArtist)

        Private _selectedMusicArtist As MusicArtist?

        Public Property SelectedMusicArtist As MusicArtist?
            Get
                Return _selectedMusicArtist
            End Get
            Set(ByVal value As MusicArtist?)
                If _selectedMusicArtist = value Then Return
                _selectedMusicArtist = value
                RemoveItemCommand.RaiseCanExecuteChanged()
            End Set
        End Property

        Public Property AddItemCommand As DelegateCommand

        Public Property RemoveItemCommand As DelegateCommand

        Public Property RemoveItemAtIndexCommand As DelegateCommand

        Public Sub New()
            MusicArtists = New ObservableCollection(Of MusicArtist)()
            AddHandler MusicArtists.CollectionChanged, AddressOf MusicArtists_CollectionChanged
            MusicArtists.Add(New MusicArtist("Jimmy", "Hendrix", New DateTime(1942, 11, 27)))
            MusicArtists.Add(New MusicArtist("Michael", "Jackson", New DateTime(1958, 8, 29)))
            MusicArtists.Add(New MusicArtist("The", "Beatles", New DateTime(1960, 1, 1)))
        End Sub

        Private Sub MusicArtists_CollectionChanged(ByVal sender As Object?, ByVal e As NotifyCollectionChangedEventArgs)
            RemoveItemCommand.RaiseCanExecuteChanged()
            RemoveItemAtIndexCommand.RaiseCanExecuteChanged()
        End Sub

    End Class

End Namespace</pre>



<h3 class="wp-block-heading">Modern alternative (.NET 6+): CommunityToolkit.Mvvm</h3>



<p>Writing <code>DelegateCommand</code> and <code>PropertyChangedBase</code> manually works perfectly fine &#x1f449; and understanding how they work is exactly why we did it this way. But in 2026, you would typically reach for the <strong><a href="https://learn.microsoft.com/en-us/dotnet/communitytoolkit/mvvm/" target="_blank" rel="noreferrer noopener">CommunityToolkit.Mvvm</a></strong> NuGet package instead.</p>



<p>It ships source generators like <code>[ObservableProperty]</code> and <code>[RelayCommand]</code>, which produce the same boilerplate automatically at compile time, meaning less code to write and maintain.</p>



<p>Compare the two approaches with these small code snippets:</p>



<p>&#x274c; Manual (what we did above)</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">private MusicArtist? _selectedMusicArtist;
public MusicArtist? SelectedMusicArtist {
    get => _selectedMusicArtist;
    set { _selectedMusicArtist = value; NotifyOfPropertyChange(); }
}</pre>



<p>&#x2705; CommunityToolkit.Mvvm</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">[ObservableProperty]
private MusicArtist? _selectedMusicArtist;</pre>



<p>Well worth a look once you are comfortable with the concepts above!</p>



<h3 class="wp-block-heading">Assign a ViewModel to the MainWindow</h3>



<p>To be able to this all work, make sure, you set an appropriate ViewModel for your MainWindow. Otherwise, the binding system wouldn&#8217;t know, where to search for your bindings. This is done by adding this code to your MainWindow XAML file:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="xml" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">&lt;!-- create a namespace mapping at the top of your file -->
xmlns:vm="clr-namespace:WpfListViewExampleCs.ViewModels"

&lt;!-- Set the DataContext MainViewModel instance by XAML -->
&lt;Window.DataContext>
    &lt;vm:MainViewModel />
&lt;/Window.DataContext></pre>



<h3 class="wp-block-heading">How to add WPF ListView items with MVVM</h3>



<p>After you got our little helper class from above inside your &#8222;Utils&#8220; folder and everything else ready, we can now continue. Adding items is now kinda different, because our items are actually bound and not just simple strings. Our commands wants at least to know, what it should do, when executed. We can pass a function, to let the command determine, if it can be executed. I mean, we don&#8217;t want a &#8222;remove selected item&#8220; to happen, when there&#8217;s no item, right?</p>



<p>The following code is needed for the actual functionality: Instantiate the command inside the constructor (don&#8217;t forget to take the command property from above!).</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MainViewModel.cs" data-enlighter-group="main-view-model-add-item">    // other properties

    public DelegateCommand AddItemCommand { get; set; }

    public MainViewModel()
    {
        AddItemCommand = new DelegateCommand(AddItem);

        // list instantiation etc..
    }

    // the delegate function to be executed on click
    private void AddItem(object? parameter)
    {
        // adding miley cyrus, as we have no dynamic dialog, as it's not a part of this here..
        MusicArtists.Add(new MusicArtist("Miley", "Cyrus", new DateTime(1992, 11, 23)));
    }</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MainViewModel.vb" data-enlighter-group="main-view-model-add-item">    ' other properties
   
    Public Property AddItemCommand As DelegateCommand

    Sub New()
        AddItemCommand = new DelegateCommand(AddItem);

        ' list instantiation etc..
    End Sub

    Private Sub AddItem(parameter As Object)
        MusicArtists.Add(New MusicArtist("Miley", "Cyrus", New DateTime(1992, 11, 23)))
    End Sub</pre>



<h3 class="wp-block-heading">Removing the selected item MVVM style</h3>



<p>The important thing here is, that we can only remove a selected item, if there is actually one selected. Please check the &#8222;SelectedMusicArtist&#8220;-property from the above MainViewModel for this. If the selected item (therefore the SelectedMusicArtist) changes, we tell the command to refresh.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MainViewModel.cs" data-enlighter-group="main-view-model-remove-item">    // other properties

    public DelegateCommand RemoveItemCommand { get; set; }

    public MainViewModel()
    {
        RemoveItemCommand = new DelegateCommand(RemoveItem, CanRemoveItem);

        // list instantiation etc..
    }

    private void RemoveItem(object? parameter)
    {
        // we should know that SelectedMusicArtist isn't null, therefore the !
        MusicArtists.Remove(SelectedMusicArtist!);
    }

    private bool CanRemoveItem(object? parameter)
    {
        return SelectedMusicArtist != null;
    }</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MainViewModel.vb" data-enlighter-group="main-view-model-remove-item">    ' other properties
   
    Public Property RemoveItemCommand As DelegateCommand

    Sub New()
        RemoveItemCommand = new DelegateCommand(RemoveItem, CanRemoveItem);

        ' list instantiation etc..
    End Sub

    Private Sub RemoveItem(parameter As Object)
        MusicArtists.Remove(SelectedMusicArtist)
    End Sub

    Private Function CanRemoveItem(parameter As Object) As Boolean
        Return SelectedMusicArtist IsNot Nothing
    End Function</pre>



<h3 class="wp-block-heading">Deleting an item by index, MVVM like</h3>



<p>In the last example, we do pretty much the same, but with some hardcoded index, just as an example!</p>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MainViewModel.cs" data-enlighter-group="main-view-model-remove-item-index">    // other properties

    public DelegateCommand RemoveItemAtIndexCommand { get; set; }

    public MainViewModel()
    {
        RemoveItemAtIndexCommand = new DelegateCommand(RemoveItemAtIndex, CanRemoveItemAtIndex);

        // list instantiation etc..
    }

    private void RemoveItemAtIndex(object? parameter)
    {
        // we need at least one item inside
        MusicArtists.RemoveAt(0);
    }

    private bool CanRemoveItemAtIndex(object? parameter)
    {
        return MusicArtists.Count > 0;
    }</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="MainViewModel.vb" data-enlighter-group="main-view-model-remove-item-index">    ' other properties
   
    Public Property RemoveItemAtIndexCommand As DelegateCommand

    Sub New()
        RemoveItemAtIndexCommand = new DelegateCommand(RemoveItemAtIndex, CanRemoveItemAtIndex);

        ' list instantiation etc..
    End Sub

    Private Sub RemoveItemAtIndex(parameter As Object)
        MusicArtists.RemoveAt(0)
    End Sub

    Private Function CanRemoveItemAtIndex(parameter As Object) As Boolean
        MusicArtists.Count > 0
    End Function</pre>



<h2 class="wp-block-heading">Conclusion – WPF ListView Control</h2>



<p>If you want to have a control, which is able to display things in like a list, being able to select one or more items out of it, the ListView is possibly your choice. When thinking about: &#8222;Should I use a ListView or a DataGrid&#8220;, you should choose the ListView, if editing is not a concern. As mostly always, you have the option to go for the code behind, or the MVVM approach, I would personally always choose the MVVM one. It seems much cleaner for my personal preferences and doesn&#8217;t mix up UI with business code. Feel free to leave any comment on how to improve this article, or if I may explained something wrong.</p>



<div style="box-sizing:border-box;margin:36px 0;border-radius:12px;overflow:hidden;background:#1a1a2e;position:relative;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;">
  <div style="position:absolute;inset:0;background-image:linear-gradient(rgba(255,255,255,0.03) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,0.03) 1px,transparent 1px);background-size:40px 40px;pointer-events:none;"></div>
  <div style="position:absolute;top:-60px;right:-60px;width:240px;height:240px;background:radial-gradient(circle,rgba(230,126,34,0.18) 0%,transparent 70%);pointer-events:none;"></div>
  <div style="position:relative;padding:32px 28px;">
    <div style="display:inline-block;font-size:11px;font-weight:700;letter-spacing:2.5px;text-transform:uppercase;color:#e67e22;margin-bottom:14px;border:1px solid rgba(230,126,34,0.35);border-radius:4px;padding:3px 10px;">Need a WPF developer?</div>
    <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Got a WPF project that needs professional hands?</p>
    <p style="margin:0 0 24px 0;font-size:14px;color:rgba(255,255,255,0.65);line-height:1.7;max-width:540px;">I build WPF applications with clean MVVM architecture in C# and VB.NET — professionally and efficiently. Just send me a message.</p>
    <div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;">
      <a href="https://robbelroot.de/contact/" style="display:inline-block;padding:12px 24px;background:#e67e22;color:#ffffff;font-size:14px;font-weight:700;text-decoration:none;border-radius:7px;white-space:nowrap;" onmouseover="this.style.background='#cf6d17'" onmouseout="this.style.background='#e67e22'">→ Get in touch</a>
    </div>
  </div>
</div>



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



<div class="schema-faq wp-block-yoast-faq-block"><div class="schema-faq-section" id="faq-question-1774441748497"><strong class="schema-faq-question">What is the difference between a WPF ListView and a DataGrid?</strong> <p class="schema-faq-answer">A ListView is best for displaying read-only data in list or grid format, while a DataGrid supports inline editing, sorting, and cell-level interaction. Use a ListView when you only need to display and select items, use a DataGrid when users need to edit data directly in the table.</p> </div> <div class="schema-faq-section" id="faq-question-1774441768936"><strong class="schema-faq-question">How do I add columns to a WPF ListView?</strong> <p class="schema-faq-answer">Set the ListView&#8217;s View property to a GridView, then define GridViewColumn elements with Header and DisplayMemberBinding. Each column binds to a property of your data model, allowing multi-column display.</p> </div> <div class="schema-faq-section" id="faq-question-1774441780175"><strong class="schema-faq-question">Can I use the WPF ListView with MVVM and data binding?</strong> <p class="schema-faq-answer">Yes, bind the ItemsSource property to an ObservableCollection in your ViewModel. Use ICommand implementations (like DelegateCommand or RelayCommand) for add/remove operations, and bind SelectedItem for selection tracking.</p> </div> </div>



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



<p>If you need quick and ready to use examples, just go ahead and download the ones you need. Maybe I&#8217;ll add some more later.</p>



<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 wp-element-button" href="https://robbelroot.de/file-download/?dlid=6a6afb78-5d9f-4104-98af-8b46cdb3b68a" target="_blank" rel="noreferrer noopener">WpfListViewExampleCs.zip</a></div>



<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="https://robbelroot.de/file-download/?dlid=eae7bc5f-d92c-4b01-b60d-c4e4e362e055" target="_blank" rel="noreferrer noopener">WpfListViewExampleCsMvvm.zip</a></div>
</div>
<p>Der Beitrag <a href="https://robbelroot.de/blog/the-wpf-listview-control-the-complete-guide/">The WPF ListView Control – the complete Guide in 2026</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/the-wpf-listview-control-the-complete-guide/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Eine CSV-Preisliste mit VB.NET einlesen – 2024-Version</title>
		<link>https://robbelroot.de/blog/eine-csv-preisliste-mit-vb-net-einlesen/</link>
					<comments>https://robbelroot.de/blog/eine-csv-preisliste-mit-vb-net-einlesen/#respond</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Fri, 02 Dec 2022 18:08:01 +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[artikelstamm]]></category>
		<category><![CDATA[basic]]></category>
		<category><![CDATA[comma]]></category>
		<category><![CDATA[csv]]></category>
		<category><![CDATA[datagridview]]></category>
		<category><![CDATA[datei]]></category>
		<category><![CDATA[einlesen]]></category>
		<category><![CDATA[lesen]]></category>
		<category><![CDATA[preise]]></category>
		<category><![CDATA[preisliste]]></category>
		<category><![CDATA[separated]]></category>
		<category><![CDATA[stammdaten]]></category>
		<category><![CDATA[tabelle]]></category>
		<category><![CDATA[values]]></category>
		<category><![CDATA[vbnet]]></category>
		<category><![CDATA[verarbeiten]]></category>
		<category><![CDATA[visual]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=12422</guid>

					<description><![CDATA[<p>Artikeldaten-Beispiel: Einlesen aus .csv-Datei Hast Du Dich auch schonmal gefragt, wie Du eine CSV-Preisliste in VB.NET einlesen kannst? Gestern habe ich einen YouTube-Kommentar, bzw. einen Video-Wunsch eines Benutzers erhalten, wo es genau darum ging. Natürlich bin ich ein guter Klein-YouTuber *schnief* und setze die Wünsche meiner Zuschauer selbstverständlich um &#x1f609;! &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/eine-csv-preisliste-mit-vb-net-einlesen/">Eine CSV-Preisliste mit VB.NET einlesen – 2024-Version</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/12/CSV-Preisliste-mit-VB.NET-einlesen-–-Beispiel-App.png"><img loading="lazy" decoding="async" width="477" height="330" src="https://robbelroot.de/wp-content/uploads/2022/12/CSV-Preisliste-mit-VB.NET-einlesen-–-Beispiel-App.png" alt="CSV-Preisliste mit VB.NET einlesen – Beispiel-App" class="wp-image-12469" title="CSV-Preisliste mit VB.NET einlesen – Beispiel-App"/></a><figcaption class="wp-element-caption">CSV-Preisliste mit VB.NET einlesen – Beispiel-App (ä ist Absicht..)</figcaption></figure>






<h2 class="wp-block-heading">Artikeldaten-Beispiel: Einlesen aus .csv-Datei</h2>



<p>Hast Du Dich auch schonmal gefragt, wie Du eine CSV-Preisliste in VB.NET einlesen kannst? Gestern habe ich einen YouTube-Kommentar, bzw. einen Video-Wunsch eines Benutzers erhalten, wo es genau darum ging. Natürlich bin ich ein guter Klein-YouTuber *schnief* und setze die Wünsche meiner Zuschauer selbstverständlich um &#x1f609;!</p>



<p class="info-banner">&#x1f4a1; Wenn Du ein schnelles Code-Beispiel brauchst, scrolle einfach nach unten zum <strong><a href="#kompletter-code">kompletten Code</a></strong>, oder den <a href="#downloads"><strong>Downloads</strong></a>. Auch wenn dieses Beispiel auf VB.NET ausgelegt ist, kannst Du es selbstverständlich auch kinderleicht für C# verwenden.</p>



<p>Da der User unter dem VB-Video kommentiert hatte, dachte ich, ich mache es direkt passend &#8211; dennoch arbeite ich heutzutage fast nur noch mit C# (außer ein Kunde wünscht es anders, oder ich mache ein Video zu VB.NET).</p>



<style>
.info-banner {
    background: #03a9f4;
    padding: 2em;
    border-radius: 0.5em;
    color: whitesmoke;
}
.info-banner a {
    color: #FED766;
}
</style>



<h2 class="wp-block-heading">Keine Lust auf Text? Einfach als Video schauen</h2>


<div class="async-youtube" data-embed="2vNxxBkxbxM" data-alt="">
    <div class="play-button"></div>      
  </div>



<p>Falls Du keine Lust hat, diesen Beitrag in Textform zu lesen, kannst Du natürlich auch zum passenden YouTube-Video von mir rüberschwenken. Einfach in das Rechteck hier drüber klicken und schon geht es los.</p>



<h2 class="wp-block-heading">Gedanken, die man sich machen sollte: Objektorientierung</h2>



<p>Bevor wir mit dem eigentlichen &#8222;Problem&#8220;, also der programmiertechnischen Herausforderung starten, setzen wir unsere Segel erstmal Richtung Datentypen. Wir machen uns also im ersten Schritt Gedanken darüber, mit welcher Art Daten, bzw. mit welchen Objekten wir arbeiten werden. Hier kommt bei einer Artikel-, bzw. Preisliste natürlich ein &#8222;Ding&#8220; sofort in unseren Kopf: Der Artikel!</p>



<p>Eine letztendliche Auflistung dieser Artikel ist ja dann praktische unsere Preisliste im objektorientierten Sinne. Wenn Diese schön sauber gebaut ist, haben wir anschließend sogar noch die Möglichkeit, Sie zu filtern und weiterzuverarbeiten. Dazu kommen wir dann weiter unten..</p>



<p>Damit wir die Klasse allerdings gut strukturieren können (erneut &#8211; hier einfach gehalten), schauen wir uns im nächsten Schritt die Datei selbst an. Bringt ja schließlich nichts, mit Spekulationen zu programmieren, wir brauchen harte Fakten!</p>



<h2 class="wp-block-heading">Die Preisliste.csv-Datei für VB.NET</h2>



<p>Wenn wir an eine typische CSV-Datei denken, dann denkt man wohl an verschiedene Werte, Welche durch Kommata getrennt sind (naja, &#8222;comma separated values&#8220; halt, gell?). Jede Zeile steht hierbei für einen jeweils eigenen Datensatz / Artikel.</p>



<p>Also ungefähr so:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Name,Preis
Artikel 1,12.95
Artikel 2,120.95
Artikel 3,1000</pre>



<p>Man trifft allerdings häufiger auf so eine Variante hier an, also durch Semikola (ja, ist tatsächlich der Plural von Semikolon und hat nichts mit dem Getränk zu tun!) getrennte Spalten:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Name;Preis
Artikel 1;12.95
Artikel 2;120.95
Artikel 3;1000</pre>



<p>Im Endeffekt ist uns das auch fast egal, denn dann verarbeiten wir die Spalten einfach nur durch ein anders getrenntes Zeichen &#8211; muss man aber trotzdem drauf achten. Ebenso wichtig ist hier das Encoding,  es könnte zu Problemen mit Umlauten sowie Sonderzeichen führen. Hierbei bin ich ein Fan von UTF-8 :)!</p>



<p>Da wir die Daten nun kennen, bauen wir im nächsten Schritt einfach die Artikel-Klasse.</p>



<h2 class="wp-block-heading">Die Artikel-Klasse</h2>



<p>Fangen wir also nun mit der Erstellung einer passenden Klasse an. Beachte jedoch, dass ich Diese für dieses Beispiel hier klein und einfach gehalten habe. Je nach Anwendungsfall, müsstest Du die Klasse natürlich noch um die ein oder andere Eigenschaft / Funktionalität erweitern.</p>



<p>Lege also eine neue Datei im Projekt an und bezeichne Diese als &#8222;Artikel.vb&#8220;:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="VB.NET" data-enlighter-group="base-article-class">Public Class Artikel

    Public Property Name As String

    Public Property Preis As Decimal

End Class</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="C#" data-enlighter-group="base-article-class">public class Artikel
{

    public string Name { get; set; }

    public decimal Preis { get; set; }

}</pre>



<p>Hierbei habe ich die beiden für mich wichtigsten Eigenschaften des Artikels gewählt:</p>



<ol class="wp-block-list">
<li>Name &#8211; natürlich ein String</li>



<li>Preis &#8211; ein Decimal</li>
</ol>



<h3 class="wp-block-heading">Optionaler, leerer Konstruktor</h3>



<p>Nachdem wir diese beiden Eigenschaften definiert haben, könntest Du eventuell einen expliziten, leeren Konstruktor anlegen. Auch wenn Dieser praktisch von Haus aus vorhanden und &#8222;KISS &#8211; Keep It Smart &amp; Simple&#8220; an der Tagesordnung ist, finde ich es so (persönlich) trotzdem sauberer. Allerspätestens wenn Du (wie häufig) Parameter bei der Erstellung übergeben möchtest, bist Du darauf sowieso angewiesen.</p>



<p>Erweitere also die Artikel-Klasse bei Bedarf um den parameterlosen Konstruktor:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="VB.NET" data-enlighter-group="parameterloser-konstruktor">' Rest der Klasse...

Sub New()
  
End Sub

' ...</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="C#" data-enlighter-group="parameterloser-konstruktor">// Rest der Klasse...

public Artikel()
{

}

// ...</pre>



<h2 class="wp-block-heading">Auf geht&#8217;s in die Form</h2>



<p>Im nächsten Step hüpfen wir in das Formular, Welches uns lediglich einen Button und auch noch eine Tabelle (DataGridView) bereitstellen wird. Wenn wir auf den Button klicken, sollen die Artikeldaten aus der CSV-Datei verarbeitet und anschließend dargestellt werden. Schaue Dir hierzu ggf. noch einmal das Beitragsbild von ganz oben an und designe es nach Bedarf ähnlich.</p>



<p>Klicke nun einmal doppelt auf die Form, damit wir direkt einmal das DataGridView konfigurieren können. Wir stellen hierbei die automatische Generierung der Spalten aus, Diese legen wir selbst fest, weil wir später noch eine &#8222;lesbarere Spalte&#8220; definieren wollen! Durch den Doppelklick (oder einem anderen Weg) solltest Du nun im Load-Ereignishandler des Formulars sein:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" 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 MyBase.Load
        'Dim enUsCulture = New CultureInfo("en-US")
        'Thread.CurrentThread.CurrentCulture = enUsCulture
        DataGridView1.AutoGenerateColumns = False
    End Sub</pre>



<p>Beachte, dass die obigen beiden Anweisungen gebraucht werden, wenn Du in der CSV-Datei ein englisches Zahlenformat (also &#8222;49.95&#8220; statt &#8222;49,95&#8220;) verwendest. Damit setzt Du die sogenannte <strong><a href="https://learn.microsoft.com/de-de/dotnet/api/system.globalization.cultureinfo?view=net-7.0" target="_blank" rel="noreferrer noopener">CultureInfo</a></strong> auf &#8222;Englisch&#8220;.</p>



<p>Danach kommen wir zum wichtigen, gerade eben angesprochenen Punkt: Wir schalten die automatische Generierung von Spalten bei Zuweisung einer Datenquelle aus. Dies geht durch das Zuweisen von &#8222;False&#8220; mit der <strong><a href="https://learn.microsoft.com/de-de/dotnet/api/system.windows.controls.datagrid.autogeneratecolumns?view=windowsdesktop-7.0" target="_blank" rel="noreferrer noopener">&#8222;AutoGenerateColumns&#8220;-Eigenschaft</a></strong>. Falls Du die automatisch generierten Spalten behalten möchtest, kommentiere diese Zeile natürlich dementsprechend aus.</p>



<h3 class="wp-block-heading">DataGridView-Spalten konfigurieren</h3>



<p>Nun kannst Du die Spalten des DataGridViews (bei ausgeschalteter Auto-Generierung) manuell festlegen. Gehe dazu mit einem Klick auf Dein DataGridView und wähle im Eigenschaftsfenster (Designer!) die &#8222;Columns&#8220;-Eigenschaft. Verwende die 3 Punkte, damit sich ein Menü öffnet und pflege die erwünschten Spalten ein. Im Beispiel von oben sind das zwei: Name und Preis.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/12/DataGridView-Spalten-Konfiguration-–-CSV-Preisliste-mit-VB.NET-einlesen.png"><img loading="lazy" decoding="async" width="594" height="395" src="https://robbelroot.de/wp-content/uploads/2022/12/DataGridView-Spalten-Konfiguration-–-CSV-Preisliste-mit-VB.NET-einlesen.png" alt="DataGridView Spalten-Konfiguration – CSV-Preisliste mit VB.NET  einlesen" class="wp-image-12486" title="DataGridView Spalten-Konfiguration – CSV-Preisliste mit VB.NET  einlesen"/></a><figcaption class="wp-element-caption">DataGridView Spalten-Konfiguration – CSV-Preisliste mit VB.NET einlesen</figcaption></figure>



<p>Achte hier auf die Bezeichnung der Spalte (cName, cPreis z. B.) und wähle einen entsprechenden Kopf-Text. Das Wichtigste bei der Verwendung via Datenbindung ist hier, dass Du die <strong><a href="https://learn.microsoft.com/de-de/dotnet/api/system.windows.forms.datagridviewcolumn.datapropertyname?view=windowsdesktop-7.0" target="_blank" rel="noreferrer noopener">&#8222;DataPropertyName&#8220;-Eigenschaft</a></strong> setzt. Diese muss auf den Namen der zu bindenden / darzustellenden Eigenschaft gesetzt werden. In unserem Fall ist das &#8222;Name&#8220; und &#8222;Preis&#8220; &#8211; siehe Eigenschaften der Artikel-Klasse.</p>



<p>Dies ist besonders relevant, wenn Du (wie ich) lieber die sauber als Euro-Wert formatierte Variante des Preises sehen möchtest. Ergänze hierzu die Artikel-Klasse um eine passende ReadOnly-Eigenschaft:</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="">' restliche Artikel-Klasse..

    Public ReadOnly Property LesbarerPreis As String
        Get
            Return Preis.ToString("C2")
        End Get
    End Property

' ...</pre>



<h3 class="wp-block-heading">Achtung bei xx.xx und xx,xx!</h3>



<p>Beachte hierbei, dass Du ggf. oben die CultureInfo geändert hast, er würde daher nun die englische Ausgabe verwenden. Erinnere Dich hierzu, dass wir die &#8222;Sprache&#8220; global geändert/gesetzt haben, damit er die Zahlen aus der CSV-Datei richtig verarbeitet. Du könntest hier nun z. B. die deutsche CultureInfo mitgeben, damit dies hier funktioniert:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="VB.NET" data-enlighter-group="culture-info-helfer">' restliche Artikel-Klasse...

    ' Shared - bitte nicht bei jedem Abruf der Property neu instanziieren &#x1f648;
    Private Shared deutscheCultureInfo = New CultureInfo("de-DE")

    Public ReadOnly Property LesbarerPreis As String
        Get
            Return Preis.ToString("C2", deutscheCultureInfo)
        End Get
    End Property

' ....</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="C#" data-enlighter-group="culture-info-helfer">// restliche Artikel-Klasse...    

    // Shared - bitte nicht bei jedem Abruf der Property neu instanziieren &#x1f648;
    private static var deutscheCultureInfo = new CultureInfo("de-DE");

    public string LesbarerPreis
    {
        get
        {
            return Preis.ToString("C2", deutscheCultureInfo);
        }
    }

// ...</pre>



<p>Erstelle im nächsten Schritt einen Handler für das Klick-Ereignis des Buttons und den dementsprechenden Code. Um Dich nicht direkt mit dem Code zu erschlagen, teile ich Ihn in verdauliche Aspekte auf.</p>



<h2 class="wp-block-heading">Was ist zu tun – der Pseudo-Code</h2>



<ul class="wp-block-list">
<li>Unser Quell der Daten ist eine Datei -&gt; ergo, wir brauchen Dateioperationen</li>



<li>Dateipfad zusammenstückeln -&gt; woher lesen wir?</li>



<li>Datei einlesen -&gt; Dateioperation durchführen</li>



<li>Wir möchten 0, 1, oder mehrere Artikel aus der Datei bekommen -&gt; wird verwenden einen dementsprechenden Datentyp: Array / List</li>



<li>Die erste Zeile der Datei ist die Kopf-Zeile -&gt; hier gibt es wichtige Informationen über die Struktur der Datei</li>



<li>Jede sonstige Zeile beinhaltet jeweils einen Artikel</li>
</ul>



<p>Anhand der Fakten sähe unser (erstes) Vorhaben also pseudo-code-mäßig so aus:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">- Lese Zeilen aus Datei
- Verarbeite die erste Zeile, um Basis-Informationen zu erhalten
- Lese und verarbeite die restlichen Zeilen und erstelle jeweils einen Artikel daraus
- Fügen den Artikel unserer objektorientierten / virtuellen Preisliste hinzu</pre>



<p>Dies würde näher an .NET formuliert erstmal grob wie gleich folgend aussehen. Man beachte hier von Beginn an das &#8222;Async&#8220; Schlüsselwort – wir haben sicherlich nicht vor eine synchrone und eventuell hängende IO-Operation durchzuführen. Stell Dir vor, die Datei wäre 10MB groß, dann freut man sich hier mit der synchronen Variante sicherlich nicht! Nun zum Code:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="VB.NET" data-enlighter-group="dummy-code">    Private Async Sub btnPreislisteEinlesen_Click(sender As Object, e As EventArgs) Handles btnPreislisteEinlesen.Click
        Dim dateipfad = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "preisliste.csv")
        Dim zeilen = Await File.ReadAllLinesAsync(dateipfad)

        Dim artikelListe = New List(Of Artikel)()
        For Each zeile In zeilen
            Dim artikel = New Artikel()
            ' zeile verarbeiten und Artikel befüllen
            artikelListe.Add(artikel)
        Next

        ' Rest...

    End Sub</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="C#" data-enlighter-group="dummy-code">private async void btnPreislisteEinlesen_Click(object sender, EventArgs e)
{
    var dateipfad = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "preisliste.csv");
    var zeilen = await File.ReadAllLinesAsync(dateipfad);

    var artikelListe = new List&lt;Artikel>();
    foreach (var zeile in zeilen)
    {
        var artikel = new Artikel();
        // zeile verarbeiten und Artikel befüllen
        artikelListe.Add(artikel);
    }
}</pre>



<h2 class="wp-block-heading">Wenn alles so einfach wäre..</h2>



<p>Grundsätzlich würde das obige Vorgehen vermutlich erstmal aushalten, aber jeder, der mal &#8222;echte Daten&#8220; importiert hat, wird wissen, dass das leider nicht so einfach ist. Kunden, Exporte von System, usw. spielen einem häufig eben genau das aus, was man nicht erwartet, deswegen ist jede Art von Flexibilität willkommen!</p>



<p>Denke z. B. an die folgende Situation – wir erwarten:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Name;Preis
Artikel 1;12.95
Artikel 2;120.95
Artikel 3;1000</pre>



<p>Es kommt aber eine getauschte Variante.. und stell&#8216; Dir dies nun mit 15 vertauschten Spalten vor &#x1f92e;..</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Preis;Name
12.95;Artikel 1
120.95;Artikel 2
1000;Artikel 3</pre>



<p>Im nächsten Schritt bauen wir daher eine Funktionalität ein, Welche von selbst erkennt, wo sich die jeweiligen Spalten befinden. Wir lesen also die Header-Spalte und schauen: &#8222;Wo befindet sich der Preis?&#8220;. Dies könnte man sogar noch weiter spinnen und mit Übersetzungen, Abkürzungen und Co. machen, aber gut, ich lasse die Kirche mal wieder im Dorf.</p>



<h2 class="wp-block-heading">Verfeinerung &#8211; yummy!</h2>



<p>Die Erkennung der korrekten Spalten (Indices) wäre dementsprechend in dem Moment angebracht, wenn wir in der ersten Zeile sind. Nun kannst Du auch sehen, warum ich eine For- und keine For-Each-Schleife genommen habe. Dies kannst Du selbstverständlich so machen, wie Du es für richtig hältst. Achte nur darauf, dass Du nicht etwa in jeder Iteration irgendwie so einen Quatsch wie &#8222;IndexOf&#8220; machst, da er sonst pro Schleifendurchlauf nochmal alle Einträge durch muss.</p>



<p>Da wir uns die Positionen natürlich nicht in jedem Durchlauf erneut suchen möchten (und auch nicht können, da wir nicht &#8222;nochmal&#8220; in Zeile 0/1 sind), initialisieren wir uns die Variablen außerhalb. Ich nehme hier bewusst die -1, da man so ggf. noch prüfen könnte, ob eine jeweilige Spalte überhaupt gefunden wurde.</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="">' außerhalb der For-Schleife
        Dim nameIndex = -1
        Dim preisIndex = -1

' innerhalb der For-Schleife 
        Dim zeile = zeilen(i)
        Dim daten = zeile.Split(";")           
        Dim ersteZeile = i = 0
        If ersteZeile Then
            For j = 0 To daten.Length - 1
                Dim headerBezeichnung = daten(j)
                If headerBezeichnung = "Name" Then
                    nameIndex = j
                ElseIf headerBezeichnung = "Preis" Then
                    preisIndex = j
                End If
            Next
            Continue For
        End If
' .. weiterer Inhalt der For-Schleife</pre>



<h2 class="wp-block-heading">Verarbeiten eines jeweiligen Artikels / Datensatzes</h2>



<p>Nun ist es an der Zeit, den Datensatz, also die Zeile eines jeweiligen Artikels zu verarbeiten. Wir kennen an dieser Stelle bereits die Positionen der jeweiligen Informationen können daher also direkt damit arbeiten. Hier eine Möglichkeit den Artikel zu befüllen, man könnte freilich auch einen passenden Konstruktor verwenden:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="VB.NET" data-enlighter-group="article-info">' Innerhalb der For-Schleife...
    Dim artikel = New Artikel()
    artikel.Name = daten(nameIndex)
    artikel.Preis = Convert.ToDecimal(daten(preisIndex))
    artikelListe.Add(artikel)
' ...</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="C#" data-enlighter-group="article-info">// Innerhalb der For-Schleife...
var artikel = new Artikel();
artikel.Name = daten(nameIndex);
artikel.Preis = Convert.ToDecimal(daten(preisIndex));
artikelListe.Add(artikel);
// ...</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="VB.NET" data-enlighter-group="button-code">    Private Async Sub btnPreislisteEinlesen_Click(sender As Object, e As EventArgs) Handles btnPreislisteEinlesen.Click
        Dim dateipfad = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "preisliste.csv")
        Dim zeilen = Await File.ReadAllLinesAsync(dateipfad)

        Dim nameIndex = -1
        Dim preisIndex = -1

        Dim artikelListe = New List(Of Artikel)
        For i = 0 To zeilen.Length - 1
            Dim zeile = zeilen(i)
            Dim daten = zeile.Split(";")

            Dim ersteZeile = i = 0
            If ersteZeile Then
                For j = 0 To daten.Length - 1
                    Dim headerBezeichnung = daten(j)
                    If headerBezeichnung = "Name" Then
                        nameIndex = j
                    ElseIf headerBezeichnung = "Preis" Then
                        preisIndex = j
                    End If
                Next
                Continue For
            End If

            Dim artikel = New Artikel()
            artikel.Name = daten(nameIndex)
            artikel.Preis = Convert.ToDecimal(daten(preisIndex))
            artikelListe.Add(artikel)
        Next
        DataGridView1.DataSource = artikelListe
    End Sub</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="C#" data-enlighter-group="button-code">private async void btnPreislisteEinlesen_Click(object sender, EventArgs e)
{
    var dateipfad = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "preisliste.csv");
    var zeilen = await File.ReadAllLinesAsync(dateipfad);

    var nameIndex = -1;
    var preisIndex = -1;

    var artikelListe = new List&lt;Artikel>();
    for (var i = 0; i &lt;= zeilen.Length - 1; i++)
    {
        var zeile = zeilen(i);
        var daten = zeile.Split(";");

        var ersteZeile = i == 0;
        if (ersteZeile)
        {
            for (var j = 0; j &lt;= daten.Length - 1; j++)
            {
                var headerBezeichnung = daten(j);
                if (headerBezeichnung == "Name")
                    nameIndex = j;
                else if (headerBezeichnung == "Preis")
                    preisIndex = j;
            }
            continue;
        }

        var artikel = new Artikel();
        artikel.Name = daten(nameIndex);
        artikel.Preis = Convert.ToDecimal(daten(preisIndex));
        artikelListe.Add(artikel);
    }
    DataGridView1.DataSource = artikelListe;
}
</pre>



<h2 class="wp-block-heading">Darstellen im DataGridView</h2>



<p>Nun fehlt nur noch ein letzter Schritt, um unseren verarbeiteten Artikeldaten in unserer Tabelle (DataGridView) darstellen zu können. Füge dazu einfach den gleich folgenden Code nach der For-Schleife ein. Vergiss allerdings nicht, dass Du die Konfiguration der Spalten oben tätigen solltest!</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">' For Schleife

' For Schleife Ende

' artikelListe = Deine Variable (vom Typ List(Of Artikel)), Welche die verarbeiteten Artikel beinhaltet
DataGridView1.DataSource = artikelListe</pre>



<h2 class="wp-block-heading" id="kompletter-code">Kompletter Code</h2>



<p>Hast Du es eilig? Kein Problem, kenne ich! Nimm Dir, was Du brauchst einfach hier weg, oder lade das Beispielprojekt weiter unten herunter. Bevor die Wörter-Polizei kommt: &#8222;Artikäl&#8220; ist mit Absicht so geschrieben..</p>



<h3 class="wp-block-heading">Die Preisliste.csv</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Name;Preis;
Artikäl 1;15,95;
Artikel 2;49,95;
Artikel 3;120,95;</pre>



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



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="VB.NET" data-enlighter-group="kompletter-code-article">Public Class Artikel

    Public Property Name As String

    Public Property Preis As Decimal

    Public ReadOnly Property LesbarerPreis As String
        Get
            Return Preis.ToString("C2")
        End Get
    End Property

    Sub New()

    End Sub

End Class</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="C#" data-enlighter-group="kompletter-code-article">public class Artikel
{
    public string Name { get; set; }

    public decimal Preis { get; set; }

    public string LesbarerPreis
    {
        get
        {
            return Preis.ToString("C2");
        }
    }

    public Artikel()
    {
    }
}
</pre>



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



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="VB.NET" data-enlighter-group="kompletter-code-form">Imports System.IO

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'Dim enUsCulture = New CultureInfo("de-DE")
        'Thread.CurrentThread.CurrentCulture = enUsCulture
        DataGridView1.AutoGenerateColumns = False
    End Sub

    Private Async Sub btnPreislisteEinlesen_Click(sender As Object, e As EventArgs) Handles btnPreislisteEinlesen.Click
        Dim dateipfad = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "preisliste.csv")
        Dim zeilen = Await File.ReadAllLinesAsync(dateipfad)

        Dim nameIndex = -1
        Dim preisIndex = -1

        Dim artikelListe = New List(Of Artikel)
        For i = 0 To zeilen.Length - 1
            Dim zeile = zeilen(i)
            Dim daten = zeile.Split(";")

            Dim ersteZeile = i = 0
            If ersteZeile Then
                For j = 0 To daten.Length - 1
                    Dim headerBezeichnung = daten(j)
                    If headerBezeichnung = "Name" Then
                        nameIndex = j
                    ElseIf headerBezeichnung = "Preis" Then
                        preisIndex = j
                    End If
                Next
                Continue For
            End If

            Dim artikel = New Artikel()
            artikel.Name = daten(nameIndex)
            artikel.Preis = Convert.ToDecimal(daten(preisIndex))
            artikelListe.Add(artikel)
        Next
        DataGridView1.DataSource = artikelListe
    End Sub

End Class</pre>



<pre class="EnlighterJSRAW" data-enlighter-language="csharp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="C#" data-enlighter-group="kompletter-code-form">using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualBasic;

public class Form1
{
    private void Form1_Load(object sender, EventArgs e)
    {
        // Dim enUsCulture = New CultureInfo("de-DE")
        // Thread.CurrentThread.CurrentCulture = enUsCulture
        DataGridView1.AutoGenerateColumns = false;
    }

    private async void btnPreislisteEinlesen_Click(object sender, EventArgs e)
    {
        var dateipfad = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "preisliste.csv");
        var zeilen = await File.ReadAllLinesAsync(dateipfad);

        var nameIndex = -1;
        var preisIndex = -1;

        var artikelListe = new List&lt;Artikel>();
        for (var i = 0; i &lt;= zeilen.Length - 1; i++)
        {
            var zeile = zeilen(i);
            var daten = zeile.Split(";");

            var ersteZeile = i == 0;
            if (ersteZeile)
            {
                for (var j = 0; j &lt;= daten.Length - 1; j++)
                {
                    var headerBezeichnung = daten(j);
                    if (headerBezeichnung == "Name")
                        nameIndex = j;
                    else if (headerBezeichnung == "Preis")
                        preisIndex = j;
                }
                continue;
            }

            var artikel = new Artikel();
            artikel.Name = daten(nameIndex);
            artikel.Preis = Convert.ToDecimal(daten(preisIndex));
            artikelListe.Add(artikel);
        }
        DataGridView1.DataSource = artikelListe;
    }
}</pre>



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



<p>Du brauchst ein schnelles Code-Beispiel, um alles in eigener Hand ausprobieren zu können? Dann lade es Dir hier einfach kostenlos das herunter!</p>



<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 wp-element-button" href="https://bit.ly/vbnet-csv-preisliste-beispiel-download" target="_blank" rel="noreferrer noopener">PreislisteEinlesen.zip</a></div>
</div>



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



<p>Vielleicht ist auch einer der folgenden Beiträge für Dich interessant:</p>



<ul class="wp-block-list">
<li><strong><a href="https://robbelroot.de/blog/ini-datei-lesen-und-schreiben-einstellungen-speichern/" target="_blank" rel="noreferrer noopener">Ini Dateien lesen und schreiben</a></strong></li>



<li><strong><a href="https://robbelroot.de/blog/vbnet-rfid-scanner-chips-mit-arduinomikrocontroller-auslesen/" target="_blank" rel="noreferrer noopener">Chikarten und Tags mit VB.NET und Arduino auslesen</a></strong></li>



<li><strong><a href="https://robbelroot.de/blog/dein-vb-net-plugin-system-im-eigenbau-das-ultimative-beispiel/" target="_blank" rel="noreferrer noopener">Wie man ein eigenes VB.NET Plugin-System baut</a></strong></li>
</ul>
<p>Der Beitrag <a href="https://robbelroot.de/blog/eine-csv-preisliste-mit-vb-net-einlesen/">Eine CSV-Preisliste mit VB.NET einlesen – 2024-Version</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/eine-csv-preisliste-mit-vb-net-einlesen/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>&#x1f511; VB.NET RFID Scanner &#8211; Chips mit dem Arduino Mikrocontroller auslesen</title>
		<link>https://robbelroot.de/blog/vbnet-rfid-scanner-chips-mit-arduinomikrocontroller-auslesen/</link>
					<comments>https://robbelroot.de/blog/vbnet-rfid-scanner-chips-mit-arduinomikrocontroller-auslesen/#comments</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Fri, 20 May 2022 23:31:10 +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[arduino]]></category>
		<category><![CDATA[basic]]></category>
		<category><![CDATA[beispiel]]></category>
		<category><![CDATA[chipkarte]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[einfach]]></category>
		<category><![CDATA[hardware]]></category>
		<category><![CDATA[input]]></category>
		<category><![CDATA[io]]></category>
		<category><![CDATA[nano]]></category>
		<category><![CDATA[output]]></category>
		<category><![CDATA[reader]]></category>
		<category><![CDATA[rfid]]></category>
		<category><![CDATA[scannen]]></category>
		<category><![CDATA[scanner]]></category>
		<category><![CDATA[schnittstelle]]></category>
		<category><![CDATA[serial]]></category>
		<category><![CDATA[serialport]]></category>
		<category><![CDATA[seriell]]></category>
		<category><![CDATA[vb]]></category>
		<category><![CDATA[vbnet]]></category>
		<category><![CDATA[visual]]></category>
		<category><![CDATA[zugang]]></category>
		<category><![CDATA[zugangskontrolle]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=9930</guid>

					<description><![CDATA[<p>RFID Chips mit Visual Basic .NET und dem Arduino Mikrocontroller auslesen Wer in VB.NET Daten aus einem RFID-Chip auslesen möchte, trifft unter normalen Umständen vermutlich auf die handelsüblichen Geräte. Ruckzuck an den PC angeschlossen sind Sie auch schon startklar, uns die ausgelesenen Daten als Tastatur-Input bereitzustellen. Gleichzeitig liegt genau hier &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-rfid-scanner-chips-mit-arduinomikrocontroller-auslesen/">&#x1f511; VB.NET RFID Scanner &#8211; Chips mit dem Arduino Mikrocontroller auslesen</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/05/VB.NET-RFID-Scanner-Chips-mit-dem-Arduino-Mikrocontroller-auslesen.png"><img loading="lazy" decoding="async" width="640" height="360" src="https://robbelroot.de/wp-content/uploads/2022/05/VB.NET-RFID-Scanner-Chips-mit-dem-Arduino-Mikrocontroller-auslesen.png" alt="VB.NET RFID Scanner - Chips mit dem Arduino Mikrocontroller auslesen" class="wp-image-9934" title="VB.NET RFID Scanner - Chips mit dem Arduino Mikrocontroller auslesen"/></a><figcaption>VB.NET RFID Scanner &#8211; Chips mit dem Arduino Mikrocontroller auslesen</figcaption></figure>






<h2 class="wp-block-heading">RFID Chips mit Visual Basic .NET und dem Arduino Mikrocontroller auslesen</h2>



<p>Wer in VB.NET Daten aus einem RFID-Chip auslesen möchte, trifft unter normalen Umständen vermutlich auf die handelsüblichen Geräte. Ruckzuck an den PC angeschlossen sind Sie auch schon startklar, uns die ausgelesenen Daten als Tastatur-Input bereitzustellen. Gleichzeitig liegt genau hier das Problem, jedoch gleich mehr dazu. Im heutigen Beitrag beschäftigen wir uns also mit einem RFID-Scanner der Marke Eigenbau und schauen uns die Verarbeitung mit VB.NET an.</p>



<p>Zu den bekannten Einsatzgebieten der kleinen RFID-Sensoren zählen unter anderem: Zugangs- und Zugriffskontrollen wie z. B. Ticketsysteme und Türen, aber ebenso bei unseren tierischen Freunden und sogar im Ausweis finden Sie Ihre Anwendung. Selbst beim Einkauf können wir mit der RFID-Technologie kontaktlose Bezahlvorgänge durchführen und somit unseren Alltag erleichtern.</p>



<p class="info-banner">&#x1f4a1; Achtung: In diesem Beitrag geht es in erster Linie um die Verarbeitung der RFID-Daten seitens VB.NET. Ich werde in einem zukünftigen Beitrag noch die Seite des Mikrocontrollers (Arduino Nano, Mega, whatever) erläutern. Hier beschäftigen wir uns ein wenig mit den Aspekten wie Handhabung und Sicherheit. Ich verwende in diesem Beitrag Affiliate-Links, womit Du mich vollkommen kostenlos bei einem Kauf über die Links unterstützen kannst.</p>



<style>
.info-banner {
  background: #03a9f4;
  padding: 2em;
  border-radius: 0.5em;
  color: whitesmoke;
}
</style>



<h2 class="wp-block-heading">VB.NET RFID Reader aus dem Handel = meist &#8222;Tastatur-a-like only&#8220;</h2>



<p>Kommen wir nochmal genauer auf das Problem mit der angesprochenen Tastatur-Emulation (wenn das der exakt korrekte Ausdruck ist..) zurück. Wenn wir mit solchen Geräten, bzw. Sensoren wie einem RFID-Scanner arbeiten möchten, dann natürlich so flexibel wie möglich. Man stellt sich also vor, man startet seine Anwendung, lässt Sie in Ruhe laufen und wenn man loslegen will, kommt ein Kollege und möchte sich &#8222;eben&#8220; im System anmelden.</p>



<p>Dies funktioniert mit den gängigen Geräten im Discount-Bereich häufig nicht, da Diese zwangsweise eine fokussierte Oberfläche (TextBox, etc.) benötigen. Das ist freilich nicht gerade cool, wenn wir eine Bestellung bearbeiten und zig Daten neu eingeben müssten, nachdem unser Kollege fertig ist. Schöner wäre es hingegen, wenn unser Kollege seinen Chip einscannt, eine kleine Maske kommt und er seine 2–3 Eingaben so erledigen könnte. Anschließend könnten wir dann mit unserer Arbeit fortfahren und wir wären durch.</p>



<p>Sicherlich gibt es vermutlich auch andere Varianten, Welche dann zig andere Funktionen unterstützen, aber hier bewegen wir uns dann auch zumeist im vergleichsweise teureren Preis-Segment. Leider bieten die handelsüblichen Geräte also häufig nur eine Art &#8222;nix Halbes und nix Ganzes&#8220;-Lösung. Das Gerät emuliert häufig einfach nur eine Art Tastatur, Welche dann die einzelnen Daten-Bestandteile runterschreibt und häufig mit einem &#8222;Enter&#8220; bestätigt.</p>


<div class="async-youtube" data-embed="yPgT8BAmEAo" data-alt="">
    <div class="play-button"></div>      
  </div>



<h2 class="wp-block-heading">Was benötigen wir für den VB.NET RFID Reader</h2>



<p>Bedenke den blauen Hinweis oben, dass wir in diesem Beitrag vorerst nur die VB.NET Seite der Medaille betrachten. Trotzdem möchte ich hier eben noch einmal die verwendeten Dinge auflisten, alles Weitere wird dann in einem zukünftigen Beitrag ergänzend erscheinen.</p>



<p>Wir benötigen also:</p>



<ul class="wp-block-list"><li>Einen Mikrocontroller wie z. B. den <strong><a href="https://amzn.to/3yQisn0" target="_blank" rel="noreferrer noopener">Arduino Nano</a></strong> in meinem Fall</li><li>Die <strong><a href="https://www.arduino.cc/en/software" target="_blank" rel="noreferrer noopener">Arduino IDE</a></strong> (am häufigsten verwendet)</li><li>Ein <strong><a href="https://amzn.to/3wGgz9x" target="_blank" rel="noreferrer noopener">RFID Kit</a></strong> (häufig bestehend aus Sensor, Pins und Chipkarten/Anhänger)</li><li>Ausreichend <strong><a href="https://amzn.to/3NtBPX2" target="_blank" rel="noreferrer noopener">Jumper-Kabel</a></strong> (je nach Setup &#8211; hier 7 male to female)</li><li>1 <strong><a href="https://amzn.to/3Nwt8ex" target="_blank" rel="noreferrer noopener">Mini-USB Kabel</a></strong> zur Verbindung des Arduinos zum PC (eigentlich immer beim Arduino dabei..)</li></ul>



<p>Nachdem wir nun von den Hardware-Komponenten erstmal startklar sind, widmen wir uns nach der Verbindung endlich dem Visual Basic NET Code.</p>



<h2 class="wp-block-heading">Den RFID Scanner mit unserem PC verbinden</h2>



<p>Ebenso einfach wie der oben beschriebene Weg mit den handelsüblichen RFID Scanner-Geräten, verfahren wir auch mit unserem Eigenbau. Verbinde den Arduino mithilfe eines Mini-USB Kabel mit einem USB-Port Deiner Wahl. Es sollte dann ein normales &#8222;Pling-Plong&#8220;-Geräusch kommen, Welches wie üblich das Anschließen eines neuen Gerätes signalisiert.</p>



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



<p>Natürlich kann auch hier das ein oder andere Problem auf Dich zukommen, so traf es auch mich – Thema Treiber.. Um den typischen CH340 Chip erkennbar und zum Laufen zu bringen, installierst Du den für Dein System passenden Treiber. Danach wirst Du vermutlich zu einem Neustart Deines PCs aufgefordert, Welchen Du auch – um weitere Fehlerquellen zu vermeiden – durchführen solltest.</p>



<p class="info-banner">&#x1f4a1; Achtung: Bei der <strong><a href="http://www.wch.cn/download/CH341SER_ZIP.html" target="_blank" rel="noreferrer noopener">Treiber-Seite</a></strong> handelt es sich um einen chinesischen Anbieter. Achte auf das für dich passende Paket und verwende ggf. die z. B. in Chrome vorhandene Übersetzungs-Funktion. Grundsätzlich ist das dicke blaue Download-Icon aber nicht zu übersehen. Der &#8222;341SER.zip&#8220;-Treiber sollte auch für die 340er Variante funktionieren. Gerne würde ich Dir den Treiber ebenfalls zum Download anbieten, aber ich möchte vermeiden, dass Du nachher mit einem veralteten Treiber arbeitest.</p>



<p>Öffne dann einfach die &#8222;SETUP.exe&#8220; im &#8222;CH341SER&#8220;-Ordner und klicke auf &#8222;install&#8220;:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/05/Arduino-USB-Treiber-Installation-CH341SER.png"><img loading="lazy" decoding="async" width="536" height="292" src="https://robbelroot.de/wp-content/uploads/2022/05/Arduino-USB-Treiber-Installation-CH341SER.png" alt="" class="wp-image-9965"/></a><figcaption>Arduino USB Treiber Installation CH341SER – VB.NET RFID Scanner</figcaption></figure>



<p>Starte anschließend Deinen PC wie gesagt am besten neu, damit Du keine eventuellen Installations-, bzw. Erkennungsprobleme hast. Danach sollte der CH340 Chip ganz normal als COM-Port im Gerätemanager auftauchen (natürlich nur wenn tatsächlich physisch verbunden &#8211; Captain Obvious..):</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/05/USB-Verbindung-vom-Arduino-CH340-Chip-erkannt.png"><img loading="lazy" decoding="async" width="785" height="208" src="https://robbelroot.de/wp-content/uploads/2022/05/USB-Verbindung-vom-Arduino-CH340-Chip-erkannt.png" alt="" class="wp-image-9969"/></a><figcaption>USB Verbindung vom Arduino CH340 Chip erkannt – VB.NET RFID Scanner</figcaption></figure>



<h2 class="wp-block-heading">Code – RFID-Daten über VB.NET auslesen</h2>



<p>Kommen wir nun zum vermutlich heißt ersehnten VB.NET Code zum Auslesen der jeweiligen RFID-Daten. Im Mittelpunkt aller Dinge steht hier die <strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.io.ports.serialport?view=dotnet-plat-ext-6.0" target="_blank" rel="noreferrer noopener">SerialPort-Klasse</a></strong>, Welche Du ggf. noch via NuGet-Paket installieren musst. Suche dazu am besten im NuGet-Paketmanager nach &#8222;System.IO.Ports&#8220;, oder verwende <strong><a href="https://www.nuget.org/packages/System.IO.Ports/" target="_blank" rel="noreferrer noopener">diesen Link</a>, </strong>dort drin befindet sich die Klasse. Nachdem wir jetzt über die erforderlichen Mittel für die Kommunikation via COM-Ports besitzen, können wir starten.</p>



<p>Lege z. B. eine .NET 6 Windows Forms App an und gehe wie gewohnt mit F7 in den Code hinter der Form. Zuerst legen wir (je nach Belieben/gewünschten Einschränkungen) eine Eigenschaft namens &#8222;Connection&#8220; an, Welche unsere SerialPort-Verbindung widerspiegeln 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="">Public Property Connection As SerialPort</pre>



<p>Als nächstes fügen wir noch ein &#8222;<strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.collections.generic.dictionary-2?view=net-6.0" target="_blank" rel="noreferrer noopener">Dictionary</a></strong>&#8220; für eine Zuweisung von Uids (Strings &#8211; die Ids der gescannten Chips) zu Nutzern (User-Klasse) hinzu. Beachte hierbei, dass ich mit einer generischen Variante, also einem Interface arbeite, alternativ kannst Du das große &#8222;i&#8220; auch weglassen. Die User-Klasse erstellen wir gleich und dient nur zur Veranschaulichung.</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 UidsToUser As IDictionary(Of String, User)</pre>



<h3 class="wp-block-heading">Vorbereiten der Verbindung</h3>



<p>Erstelle als Nächstes einen Konstruktor für die Form, indem Du &#8222;Sub New&#8220; innerhalb der &#8222;Form1&#8220;-Klasse tippst und mit &#8222;Enter&#8220; bestätigst. Dann sollte Visual Studio Dir ein grobes Skelett für den Konstruktor generieren, diesen passen wir wie folgt an:</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()
        Connection = New SerialPort("COM3", 9600, Parity.None, 8, StopBits.One)
        AddHandler Connection.DataReceived, AddressOf Connection_DataReceived
    End Sub</pre>



<p>Zuerst lassen wir die von Haus aus kommende &#8222;InitializeComponent&#8220;-Methode unangetastet, da unsere eventuellen Form-Steuerelemente sonst nicht funktionieren würden. Danach instanziieren wir eine neue Instanz der Klasse &#8222;SerialPort&#8220; mit einigen Werten.</p>



<ul class="wp-block-list"><li>COM3 &#8211; steht für den für die Kommunikation zu wählenden COM-Port. In meinem Fall steckt mein Arduino am COM-Port Nr. 3.</li><li>9600 &#8211; ist die sogenannte Baudrate und regelt die &#8222;Kommunikationsgeschwindigkeit&#8220; zwischen Arduino und PC. Achte hier darauf, dass Du den gleichen Wert wie in Deinem Arduino Sketch unter &#8222;Serial.Begin(&lt;der Wert&gt;)&#8220; wählst.</li></ul>



<p>Dann stellen wir noch gewisse andere Dinge wie die Parität, die Daten-Bits und die Stop-Bits ein. (Ich erspare Dir jede einzelne Erklärung hier..).</p>



<p>Im letzten Konstruktor-Schritt bezüglich der SerialPort-Verbindung fügen wir auch noch einen Ereignishandler für das <strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.io.ports.serialport.datareceived?view=dotnet-plat-ext-6.0" target="_blank" rel="noreferrer noopener">&#8222;DataReceived&#8220;-Ereignis</a></strong> hinzu.</p>



<h3 class="wp-block-heading">Verbindung starten</h3>



<p>Danach können wir einen weiteren Handler generieren, hierbei handelt es sich um den Ereignishandler für das &#8222;Form Load&#8220;-Ereignis. Darin werden wir dann die Verbindung zum Arduino (über den SerialPort) öffnen, ansonsten können wir natürlich nicht kommunizieren &#x1f609;.</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 MyBase.Load
        Connection.Open()
    End Sub</pre>



<h3 class="wp-block-heading">Auf Daten reagieren/lauschen</h3>



<p>Nun müssen wir den oben zugewiesenen (aber bisher nicht existenten) Ereignishandler für das &#8222;DataReceived&#8220;-Ereignis erstellen. Das geht erstmal ganz einfach wie folgt:</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 Connection_DataReceived(sender As Object, e As SerialDataReceivedEventArgs)
        Dim text = Connection.ReadLine().TrimStart().TrimEnd()
        If text.StartsWith("RFID:") Then
            Dim uid = text.Split(":")(1)
            Invoke(Sub() OnUidScanned(uid))
        End If
    End Sub</pre>



<p class="info-banner">&#x1f4a1; Achtung: Ich habe seitens des Arduino-Codes sichergestellt, dass wir mit einem Zeilenumbruch arbeiten/kommunizieren. Daher kann ich hier mit dem <strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.io.ports.serialport.readline?view=dotnet-plat-ext-6.0" target="_blank" rel="noreferrer noopener">&#8222;ReadLine&#8220;-Befehl</a></strong> arbeiten. Beachte allerdings bei Deinen geplanten Projekten, dass das &#8222;DataReceived&#8220;-Ereignis (wie der Name schon sagt) lediglich sagt: &#8222;Ey, hier sind Daten&#8220; &#8211; das heißt aber nicht, dass ALLE Daten da sind, die Du Dir vorstellst. Da wir hier aber mit einer kleinen Datenmenge a la &#8222;RFID:DieUid&#8220; arbeiten, werden wir hier aller Voraussicht nach kein Problem bekommen. Wenn Du allerdings ellenlange Texte hin und her schiebst, könnte es zu einem Problem werden &#8211; aber auch dazu in einem anderen Beitrag mehr..</p>



<p>Nun lesen wir mit &#8222;ReadLine&#8220; die Daten ein und &#8222;säubern&#8220; Diese anschließend durch Verkettung von &#8222;TrimStart&#8220; und &#8222;TrimEnd&#8220;. Das verhindert unnötige und unerwartete Leerzeichen, kann aber natürlich auch durch saubere Programmierung am Arduino verhindert werden..</p>



<h3 class="wp-block-heading">Nun vor-verarbeiten</h3>



<p>Grundsätzlich haben wir den Text, Welcher vom Arduino kommt endlich vorliegen und können Ihn verarbeiten. Beachte, dass ich hier ein kleines &#8222;Protokoll&#8220; einhalte, auch wenn es nur praktisch gesehen aus einem Teil besteht. Ich halte mich an meine Regel, dass ich beim erfolgreichen Einlesen eines RFID-Chips den String &#8222;RFID:&#8220; gefolgt von der Uid-Zeichenfolge und einem Zeilenumbruch durch den SerialPort jage.</p>



<p>Ergo muss ich mich natürlich an der Gegenstelle (VB.NET) daran halten und die Daten dementsprechend auslesen und verarbeiten. Das mache ich dann im nächsten Schritt, indem ich prüfe, ob die eingelesenen Daten mit einem &#8222;RFID:&#8220; beginnen. Ich splitte also den String anhand des Doppelpunktes und nehme mir den zweiten Teil des Strings als Uid.</p>



<h3 class="wp-block-heading">Daten an die UI delegieren</h3>



<p>Anders als gedacht sollte man hier normalerweise nun nicht mit einer Art &#8222;ich update mal jetzt direkt die UI a la Label1.Text = &#8230;&#8220; arbeiten. Das liegt daran, dass das Ereignis vom SerialPort (und somit unser Handler) meines Wissens nach auf einem anderen Thread als die UI ausgeführt wird. Von dort aus also nun auf die grafische Oberfläche zuzugreifen sollte aller Wahrscheinlichkeit nach einen &#8222;Cross Thread bla blupp&#8220;-Fehler auslösen.</p>



<p>Um dies zu vermeiden, verwende ich die &#8222;Invoke&#8220;-Methode der Form in Kombination mit einem inline definierten Delegaten (&#8222;Sub() &lt;etc&gt;..&#8220;). Dieser Delegat hat einen zugrunde liegenden Aufruf namens &#8222;OnUidScanned&#8220; &#8211; mit dem passenden String-Parameter. Alternativ könntest Du hier auch mit einem &#8222;BeginInvoke&#8220;-Aufruf arbeiten, dies lässt den Aufrufer nicht auf den Abschluss des Codes warten.</p>



<h3 class="wp-block-heading">Reine Erkennung von Uids fertig &#8211; und nun?</h3>



<p>An dieser Stelle haben wir unser Grundgerüst, was das Auslesen und &#8222;parsen&#8220; der Uids der Chips betrifft fertig. Nun wirst Du Dich hoffentlich fragen – ja cool, und was nun? Nur Geduld junger Padawan, es geht direkt weiter. Als Nächstes definieren wir (in .NET-Manier) eine typische Ereignis-Methode namens &#8222;On&#8230;&#8220;. Diese kann bei Bedarf in Sub-Klassen überschrieben werden und dient als Basis für unser eigenes Ereignis.</p>



<p>Erstelle nun am Ende der Datei (da lege ich die Ereignisse eigentlich immer ab) ein Ereignis wie das Folgende. Beachte dabei, dass man normalerweise eine eigene von EventArgs abgeleitete Klasse für die Ereignisinformationen verwenden sollte, darauf habe ich hier verzichtet. Unser Ereignis beinhaltet nur die Uid-Information, also einen simplen String.</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 Event UidScanned As EventHandler(Of String)</pre>



<p>Die passende &#8222;On&#8220;-Methode würde also so 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="">    Protected Overridable Sub OnUidScanned(uid As String)
        RaiseEvent UidScanned(Me, uid)
    End Sub</pre>



<p>Zu guter Letzt verknüpfen wir nun unser eigens erstelltes Ereignis via Handles-Klausel mit einer passenden Methode als Handler:</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 Me_UidScanned(sender As Object, uid As String) Handles Me.UidScanned
        Dim user As User = Nothing
        UidsToUser.TryGetValue(uid, user)
        If user Is Nothing Then
            MessageBox.Show("Login failed!")
            Return
        End If
        MessageBox.Show($"Hey {user.Name}!")
    End Sub</pre>



<p>Hier initialisieren wir zuerst eine leere Variable namens &#8222;User&#8220;, Welche anschließend durch die <strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.collections.generic.dictionary-2.trygetvalue?view=net-6.0" target="_blank" rel="noreferrer noopener">&#8222;TryGetValue&#8220;-Funktion</a></strong> der generischen Dictionary Klasseninstanz befüllt werden sollte. Wenn kein zur Uid passender Nutzer ermittelt werden konnte, wird hier eine kleine &#8222;Login failed!&#8220;-Meldung ausgegeben. Ansonsten zeigen wir testweise den Namen des jeweils ermittelten Nutzers an.</p>



<p class="info-banner">&#x1f4a1; Achtung: Hier noch der Hinweis, dass es sich hierbei keinesfalls um einen &#8222;production ready&#8220; Code handelt. Das Beispiel dient lediglich zur Veranschaulichung des Empfangs von seriellen Sensordaten via SerialPort. Jeder mit einigermaßen vorhandenen <strong>Disassembler</strong>-Kenntnissen würde in wenigen Sekunden an die jeweiligen Chip-Uids kommen. Normalerweise sollte das Programm nur als Schnittstelle dienen, also die Daten einlesen und an eine passende (Web-) Schnittstelle zur Verarbeitung weiterleiten. Wenn sicher über Https übertragen, könnte die Schnittstelle also anhand der Uid einen passenden Nutzer aus der Datenbank laden und einen Zugriff ermöglichen. Auch wenn ich diesen Satz hasse: &#8222;..aber das würde den Rahmen sprengen&#8220; / &#8222;The princess is in another castle&#8220; &#8211; wenn Du mich verstehst &#x1f61b;..</p>



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



<p>Bevor ich es vergesse, hier noch die verwendete, simple User-Klasse:</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 User

    Public Property Name As String

    Sub New(name As String)
        Me.Name = name
    End Sub

    Public Overrides Function ToString() As String
        Return Name
    End Function

End Class</pre>



<h2 class="wp-block-heading">Weitere Links</h2>



<ul class="wp-block-list"><li><strong><a href="https://robbelroot.de/blog/chipkarten-tags-mit-arduino-rfid-scanner-auslesen" target="_blank" rel="noreferrer noopener">Arduino RFID Scanner</a></strong></li><li><a href="https://robbelroot.de/blog/virtuelle-com-ports-mit-com0com-erstellen-emulieren/" target="_blank" rel="noreferrer noopener"><strong>Virtuelle COM Ports emulieren mit com0com</strong></a></li></ul>



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



<p>Wie immer findest Du hier am Schluss den vollständigen Download des (VB.NET) Codes. Ggf. ergänze ich der Vollständigkeit halber trotzdem noch den Arduino-Code, ansonsten wird Dieser später in dem getrennten Arduino-Teil kommen.</p>



<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-rfid-scanner-download-hp" target="_blank" rel="noreferrer noopener">RfidReaderExample.zip</a></div>



<div class="wp-block-button"><a class="wp-block-button__link" href="https://www.nuget.org/packages/System.IO.Ports/" target="_blank" rel="noreferrer noopener">System.IO.Ports NuGet Package</a></div>



<div class="wp-block-button"><a class="wp-block-button__link" href="http://www.wch.cn/download/CH341SER_ZIP.html" target="_blank" rel="noreferrer noopener">CH340 Driver Site</a></div>


</div>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-rfid-scanner-chips-mit-arduinomikrocontroller-auslesen/">&#x1f511; VB.NET RFID Scanner &#8211; Chips mit dem Arduino Mikrocontroller auslesen</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vbnet-rfid-scanner-chips-mit-arduinomikrocontroller-auslesen/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>VB NET MouseMove – Mausbewegungen mit AutoIt3 simulieren</title>
		<link>https://robbelroot.de/blog/vb-net-mousemove-mausbewegungen-mit-autoit3-simulieren/</link>
					<comments>https://robbelroot.de/blog/vb-net-mousemove-mausbewegungen-mit-autoit3-simulieren/#comments</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Sun, 03 Oct 2021 01:30:53 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Visual Basic .NET]]></category>
		<category><![CDATA[Visual Basic .NET Problemlösungen]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[automatisch]]></category>
		<category><![CDATA[automatisieren]]></category>
		<category><![CDATA[automatisierung]]></category>
		<category><![CDATA[basic]]></category>
		<category><![CDATA[bewegen]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[maus]]></category>
		<category><![CDATA[mausbewegung]]></category>
		<category><![CDATA[mausposition]]></category>
		<category><![CDATA[mouse]]></category>
		<category><![CDATA[mousemove]]></category>
		<category><![CDATA[move]]></category>
		<category><![CDATA[position]]></category>
		<category><![CDATA[positionieren]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[vb]]></category>
		<category><![CDATA[vb.net]]></category>
		<category><![CDATA[vbnet]]></category>
		<category><![CDATA[visual]]></category>
		<category><![CDATA[visual basic]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=6455</guid>

					<description><![CDATA[<p>VB NET MouseMove – Mausposition durch Code setzen Du möchtest einen &#8222;VB NET MouseMove&#8222;-Befehl realisieren, aber weißt nicht ganz wie Du das anstellen sollst? Lerne im diesmaligen Beitrag, wie Du in VB NET eine Mausbewegung via Code ausführen kannst. Zugehörig zu den anderen AutoIt3-Beiträgen, fahre ich mit der kleinen Serie &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vb-net-mousemove-mausbewegungen-mit-autoit3-simulieren/">VB NET MouseMove – Mausbewegungen mit AutoIt3 simulieren</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-MouseMove.png"><img loading="lazy" decoding="async" width="1200" height="675" src="https://robbelroot.de/wp-content/uploads/2021/10/VB.NET-MouseMove.png" alt="VB.NET MouseMove mit AutoIt3 simulieren" class="wp-image-6457" title="VB.NET MouseMove mit AutoIt3 simulieren"/></a><figcaption>VB.NET MouseMove mit AutoIt3 simulieren</figcaption></figure>






<h2 class="wp-block-heading">VB NET MouseMove – Mausposition durch Code setzen</h2>



<p>Du <strong>möchtest </strong>einen &#8222;<strong>VB NET MouseMove</strong>&#8222;-Befehl realisieren, aber weißt <strong>nicht ganz wie </strong>Du das anstellen sollst?</p>



<p><strong>Lerne </strong>im diesmaligen Beitrag, wie Du in <strong>VB NET</strong> eine <strong>Mausbewegung via Code</strong> ausführen kannst.</p>



<p><strong>Zugehörig zu </strong>den <strong>anderen </strong>AutoIt3-<strong>Beiträgen</strong>, <strong>fahre </strong>ich <strong>mit </strong>der kleinen <strong>Serie </strong>hier nun <strong>fort</strong>.</p>



<p>Du <strong>brauchst </strong>Dir auch <strong>keine </strong>besonderen <strong>Sorgen über </strong>die <strong>Speichergröße </strong>der hier verwendeten Hilfsmittel machen.</p>



<p><strong>Darauf </strong>gehe ich aber zu einem <strong>späteren Zeitpunkt </strong>noch einmal kurz ein.</p>



<p><strong>Auch wenn </strong>Du damit vermutlich <strong>keinen</strong> &#8222;<strong><a href="https://osu.ppy.sh/home" target="_blank" rel="noreferrer noopener">OSU!</a></strong>&#8222;-Bot bauen kannst denke ich, dass es hier und <strong>da sehr hilfreich </strong>sein kann!</p>



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



<iframe loading="lazy" width="560" height="315" src="https://www.youtube-nocookie.com/embed/wlG_qTQF7fk" 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>Wenn </strong>Du <strong>lieber </strong>ein <strong>Video </strong>sehen möchtest, statt Dich durch den Beitrag zu lesen, <strong>kannst </strong>Du das hier <strong>auch </strong>tun.</p>



<p><strong>Gerne schweife ich </strong>in meinen Beiträgen auch mal <strong>ab und bringe </strong>hier und da Nebeninformationen rein.</p>



<p><strong>Leider fehlt </strong>mir dazu oft <strong>in </strong>den <strong>Videos die Zeit</strong>, da ich denke, dass man einen <strong>Beitrag einfacher durchscrollen </strong>kann.</p>



<p><strong>Sicherlich </strong>ist man vom Fernseher und von Videos <strong>gewohnt</strong>, hier und da mal <strong>durch </strong>zu <strong>zappen</strong>.</p>



<p>Ich <strong>finde allerdings</strong>, dass das <strong>Scrollen zu </strong>bestimmten <strong>Überschriften </strong>einfacher und <strong>leichter </strong>von der Hand geht.</p>



<p><strong>Glücklicherweise hat <a href="https://youtube.com" target="_blank" rel="noreferrer noopener">YouTube</a></strong> seit längerer Zeit <strong>eine </strong>Art <strong>Kapitelübersicht </strong>hinzugefügt.</p>



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



<h2 class="wp-block-heading">Wie ich auf den Beitrag kam</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/09/Haeufige-Backgroundworker-Fragen.jpg"><img loading="lazy" decoding="async" width="640" height="320" src="https://robbelroot.de/wp-content/uploads/2021/09/Haeufige-Backgroundworker-Fragen.jpg" alt="VB NET MouseMove – Cursor bewegen" class="wp-image-5986"/></a><figcaption>VB NET MouseMove – Cursor bewegen</figcaption></figure>



<p><strong>Auch wenn </strong>wir damit <strong>wie </strong>oben schon <strong>erwähnt </strong>vermutlich keinen &#8222;OSU!&#8220;-Bot bauen können, <strong>geht </strong>dennoch <strong>einiges</strong>.</p>



<p><strong>In Kombination mit </strong>den anderen <strong>unten verlinkten Funktionalitäten </strong>kann man so manches realisieren.</p>



<p><strong>Ich selbst kam nicht selten in </strong>die <strong>Versuchung</strong> gewisse <strong>Tools </strong>zur Erleichterung meiner Arbeit und auch des Gamings zu <strong>umzusetzen</strong>.</p>



<p><strong>Daher </strong>beschäftigen wir uns <strong>in diesem Beitrag </strong>damit, <strong>wie </strong>man gewisse <strong>Mausbewegungen via Code </strong>steuern kann.</p>



<p>Im <strong>nächsten </strong>Teil des Beitrags schauen wir dazu allerdings erstmal die <strong>notwendigen Tools </strong>an.</p>



<p><strong>Danach </strong>beschäftigen wir uns <strong>mit </strong>dem <strong>Aufsetzen des </strong>Visual Studio <strong>Projektes und </strong>der <strong>Installation der </strong>notwendigen <strong>Bibliotheken</strong>.</p>



<h2 class="wp-block-heading">Nicht ohne Hilfe – wir nutzen AutoIt</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="Mit Hilfe von AutoIt" class="wp-image-6341" title="Mit Hilfe von AutoIt"/></a><figcaption>Mit Hilfe von AutoIt</figcaption></figure>



<p><strong>Für unser Vorhaben</strong>, Welches <strong>auch roh </strong>in VB NET <strong>möglich </strong>wäre, <strong>verwenden </strong>wir <strong>hier </strong>allerdings bewusst die Bibliothek von <strong>AutoIt3</strong>.</p>



<p><strong>Ich habe</strong> im <a href="https://robbelroot.de/blog/vb-net-imagesearch-bilder-in-spielen-desktop-und-co-suchen/" target="_blank" rel="noreferrer noopener"><strong>&#8222;ImageSearch&#8220;-Beitrag</strong></a> schon einmal angesprochen dass <strong>viele Entwickler kritisch mit </strong>der <strong>Speichergröße </strong>der Projekte umgehen.</p>



<p><strong>In erster Linie </strong>ist das natürlich völlig <strong>nachvollziehbar</strong>, da ich <strong>selbst </strong>ein <strong>Freund des KISS (Keep It Smart and Simple)</strong> bin.</p>



<p><strong>Ich denke </strong>allerdings, dass es Situationen gibt, wo <strong>man </strong>es auch <strong>übertreiben kann</strong>.</p>



<p>In <strong>Festplatten</strong>&#8211;<strong>Generation </strong>&#8222;<strong>Terrabyte zum Preis von damaligen 80GB</strong>&#8220; nörgle ich nicht für 1MB rum.</p>



<p><strong>Das </strong>was <strong>letztendlich zählen </strong>sollte, ist die <strong>Relation zwischen Aufwand und Erfolg</strong>, bzw. das Erreichen des Ziels.</p>



<p><strong>In intelligent </strong>entwickelten, bzw. <strong>strukturierten Programmen </strong>ist der <strong>spätere Austausch </strong>kein Problem.</p>



<p><strong>Daher </strong>immer <strong>schön sauber </strong>mit Interfaces und deren Implementierungen <strong>arbeiten </strong>*zwinker*.</p>



<h2 class="wp-block-heading">Ein neues Projekt anlegen und in Visual Studio vorbereiten</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 und vorbereiten" class="wp-image-6352" title="Neues Visual Studio Projekt anlegen und vorbereiten"/></a><figcaption>Neues Visual Studio Projekt anlegen und vorbereiten</figcaption></figure>



<p><strong>Nun</strong> wären wir an der Stelle, die <strong><a href="/downloads/tools/AutoItPackage.zip" target="_blank" rel="noreferrer noopener"><strong>notwendigen</strong> Libraries</a> </strong>herunterzuladen.</p>



<p>Erledige das gern direkt hier, oder suche Dir <strong>anderweitige Quellen </strong>im Netz dafür.</p>



<p><strong>Erstelle</strong> danach einfach ein <strong>neues </strong>Windows Forms-, oder ein WPF-<strong>Projekt</strong>.</p>



<p><strong>Füge</strong> die &#8222;<strong>AutoItX3.Assembly.dll</strong>&#8222;-Datei nun als Verweis hinzu, <strong>damit </strong>wir Diese im Code nutzen können.</p>



<p>Relativ simpel geht das in Visual Studio zum Beispiel außen rechts <strong>über </strong>den <strong>Projektmappen-Explorer</strong>.</p>



<p><strong>Führe </strong>dazu einfach einen <strong>rechten Mausklick </strong>auf &#8222;<strong>Verweise</strong>/<strong>Abhängigkeiten</strong>&#8220; <strong>aus </strong>und wähle die Datei aus.</p>



<p><strong>Neben </strong>dem genannten Weg, gibt es <strong>auch </strong>noch <strong>andere Möglichkeiten</strong>, zum Beispiel über das obige &#8222;Hauptmenü&#8220;.</p>



<p><strong>Kopiere </strong>anschließend <strong>alle anderen </strong>Dateien (außer die ImageSearchDLL.dll) <strong>in </strong>den <strong>Debug-Ordner</strong> deines Projekts.</p>



<p>Die <strong>oben </strong>erwähnte <strong>Datei </strong>dürfte sich <strong>aufgrund </strong>des <strong>Imports schon </strong>im Ordner befinden.</p>



<h2 class="wp-block-heading">Der Code – VB NET MouseMove</h2>



<p><strong>Nun </strong>kommen wir <strong>endlich </strong>an den Punkt, wo wir uns <strong>an </strong>den <strong>Code </strong>heranwagen.</p>



<p><strong>Nachdem </strong>Du <strong>alle Vorbereitungen abgeschlossen </strong>hast, kann Du <strong>nun </strong>den <strong>Namespace importieren</strong>.</p>



<p><strong>Dadurch </strong>kannst Du dann auf die <strong>benötigte Klasse </strong>zugreifen:</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 AutoIt</pre>



<p>Durch die <strong>nun verfügbare Klasse </strong>&#8222;<strong>AutoItX</strong>&#8222;, können wir <strong>jetzt </strong>die <strong>Mausbewegungen </strong>an sich realisieren.</p>



<p><strong>Klicke </strong>Dir <strong>nun </strong>vielleicht <strong>noch </strong>vorher <strong>eine GUI </strong>wie Diese hier, mit <strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.label?view=net-5.0" target="_blank" rel="noreferrer noopener">2 Labels</a></strong>, <strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.textbox?view=net-5.0" target="_blank" rel="noreferrer noopener">2 Textboxen</a></strong> und einen <strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.button?view=net-5.0" target="_blank" rel="noreferrer noopener">Button</a></strong> zurecht:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/10/VB-NET-Maus-bewegen-Beispiel-GUI.png"><img loading="lazy" decoding="async" width="320" height="222" src="https://robbelroot.de/wp-content/uploads/2021/10/VB-NET-Maus-bewegen-Beispiel-GUI.png" alt="VB NET Maus bewegen Beispiel GUI" class="wp-image-6489" title="VB NET Maus bewegen Beispiel GUI"/></a><figcaption>VB NET Maus bewegen Beispiel GUI</figcaption></figure>



<p>Die <strong>beiden Labels sollen </strong>Dich auch noch <strong>in </strong>einem <strong>halben Jahr </strong>dran<strong> erinnern</strong>, <strong>welche Inputs wohin </strong>müssen.</p>



<p>Bei den <strong>Textboxen </strong>verzichten wir bei der <strong>Eingabe </strong>der <strong>Koordinaten </strong>in diesem Beispiel auf eine Prüfung.</p>



<p>Wir prüfen also nicht explizit, <strong>ob </strong>es sich dabei <strong>wirklich </strong>um <strong>Zahlen </strong>handelt, etc.</p>



<p><strong>Anschließend holen </strong>wir uns die <strong>Koordinaten </strong>aus den Textboxen <strong>und wandeln </strong>Diese um.</p>



<p><strong>Dafür </strong>verwenden wir natürlich den korrekten <strong>Datentyp </strong>namens <strong>Integer</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 x = Integer.Parse(tbX.Text)
Dim y = Integer.Parse(tbY.Text)</pre>



<p><strong>Nun </strong>kommen wir <strong>zum </strong>goldenen Teil des Beitrages, also der <strong>Durchführung </strong>der <strong>Mausbewegung </strong>selbst.</p>



<p><strong>Dazu </strong>benutzen wir die <strong>importierte Klasse </strong>&#8222;AutoItX&#8220; in Kombination <strong>mit </strong>den gerade festgelegten <strong>Koordinaten</strong>.</p>



<p><strong>Optional </strong>könntest Du <strong>auch </strong>noch eine Art <strong>Geschwindigkeit der Bewegung</strong>, bzw. der &#8222;Animation&#8220; <strong>festlegen </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 movementSpeed = 50
AutoItX.MouseMove(x, y, movementSpeed)</pre>



<p>Als <strong>nächstes </strong>möchte ich die <strong>Parameter </strong>noch der Vollständigkeit halber <strong>erläutern</strong>, oder eher auflisten.</p>



<p><strong>Detailliertere Informationen </strong>findest Du <strong>auf </strong>der offiziellen <strong>Seite</strong>, bzw. der <strong><a href="https://www.autoitscript.com/autoit3/docs/functions/MouseMove.htm" target="_blank" rel="noreferrer noopener">offiziellen Dokumentation</a></strong>:</p>



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



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



<p> Gibt den Koordinaten-Punkt des Klicks auf der horizontalen (X) Achse an.</p>



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



<p> Setzt die Koordinate des auszuführenden Klicks auf der vertikalen (Y) Achse. </p>



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



<p>Gibt die Geschwindigkeit der Bewegung an.</p>



<h2 class="wp-block-heading">Der komplette Code – TL;DR</h2>



<p><strong>Obwohl </strong>der Code hier vermutlich <strong>nicht durch </strong>seine <strong>Quantität glänzt</strong>, hier nochmal alles in einem Stück.</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 AutoIt

Public Class Form1

    Private Sub btnMoveMouse_Click(sender As Object, e As EventArgs) Handles btnMoveMouse.Click
        Dim x = Integer.Parse(tbX.Text)
        Dim y = Integer.Parse(tbY.Text)
        Dim moveSpeed = 50
        AutoItX.MouseMove(x, y, moveSpeed)
    End Sub

End Class</pre>



<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">Visual Basic NET MouseClick simulieren</a></strong></li><li><strong><a href="https://robbelroot.de/blog/vb-net-imagesearch-bilder-in-spielen-desktop-und-co-suchen/" target="_blank" rel="noreferrer noopener">VB NET ImageSearch in Spielen, auf dem Desktop, etc.</a></strong></li><li><strong><a href="https://robbelroot.de/blog/vbnet-texterkennung-auf-bildern/" target="_blank" rel="noreferrer noopener">Visual Basic .NET Texterkennung auf Bildern via Google Cloud Vision API [OCR]</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">AutoItPackage.zip</a></div>



<div class="wp-block-button"><a class="wp-block-button__link" href="/downloads/vbnet/MouseMoveExample.zip" target="_blank" rel="noreferrer noopener">MouseMoveExample.zip</a></div>
</div>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vb-net-mousemove-mausbewegungen-mit-autoit3-simulieren/">VB NET MouseMove – Mausbewegungen mit AutoIt3 simulieren</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vb-net-mousemove-mausbewegungen-mit-autoit3-simulieren/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>VB NET MouseClick simulieren – mit AutoIt3</title>
		<link>https://robbelroot.de/blog/vb-net-mouseclick-simulieren-mit-autoit3/</link>
					<comments>https://robbelroot.de/blog/vb-net-mouseclick-simulieren-mit-autoit3/#comments</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Sat, 02 Oct 2021 18:14:30 +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[ausführen]]></category>
		<category><![CDATA[autoit]]></category>
		<category><![CDATA[autoit3]]></category>
		<category><![CDATA[autoklick]]></category>
		<category><![CDATA[autoklicker]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[automatisch]]></category>
		<category><![CDATA[automatisieren]]></category>
		<category><![CDATA[basic]]></category>
		<category><![CDATA[click]]></category>
		<category><![CDATA[klick]]></category>
		<category><![CDATA[klicken]]></category>
		<category><![CDATA[mausklick]]></category>
		<category><![CDATA[mouseclick]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[simulate]]></category>
		<category><![CDATA[simulieren]]></category>
		<category><![CDATA[steuern]]></category>
		<category><![CDATA[vb]]></category>
		<category><![CDATA[vb.net]]></category>
		<category><![CDATA[vbnet]]></category>
		<category><![CDATA[visual]]></category>
		<category><![CDATA[visual basic]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=6393</guid>

					<description><![CDATA[<p>VB NET MouseClick simulieren Einen VB NET MouseClick simulieren zu können wollte vermutlich jeder Entwickler schon einmal. Ich würde sogar sagen, jeder Gamer sowieso, denn wer hat schon Lust auf die typische &#8222;Monkey-Work&#8220;. Zig tausend mal die gleichen Dialoge in exakter Reihenfolge zu bestätigen und sich mühselig manuell durchzuklicken. Also &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vb-net-mouseclick-simulieren-mit-autoit3/">VB NET MouseClick simulieren – mit AutoIt3</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-MouseClick-simulieren.png"><img loading="lazy" decoding="async" width="1200" height="675" src="https://robbelroot.de/wp-content/uploads/2021/10/VB.NET-MouseClick-simulieren.png" alt="VB.NET MouseClick simulieren" class="wp-image-6395" title="VB.NET MouseClick simulieren"/></a><figcaption>VB.NET MouseClick simulieren</figcaption></figure>






<h2 class="wp-block-heading">VB NET MouseClick simulieren</h2>



<p>Einen <strong>VB NET MouseClick simulieren</strong> zu können wollte vermutlich jeder Entwickler schon einmal.</p>



<p>Ich <strong>würde </strong>sogar <strong>sagen</strong>, <strong>jeder Gamer </strong>sowieso, denn wer hat schon Lust auf die typische &#8222;Monkey-Work&#8220;.</p>



<p><strong>Zig tausend mal </strong>die <strong>gleichen Dialoge </strong>in exakter Reihenfolge zu <strong>bestätigen </strong>und sich <strong>mühselig </strong>manuell <strong>durchzuklicken</strong>.</p>



<p>Also echt mal, da hat doch <strong>keiner Bock drauf</strong>, seufz, jedenfalls aller spätestens beim 2, 3, .. Mal.</p>



<p><strong>Natürlich </strong>treffen wir <strong>ähnliche Bedürfnisse </strong>und <strong>Probleme </strong>auch <strong>im Büroalltag </strong>an, Excel, usw. lassen lieb grüßen.</p>



<p><strong>Ein Glück</strong>, dass man (angehender) <strong>Entwickler </strong>ist, gell &#x1f609;!</p>



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



<iframe loading="lazy" width="560" height="315" src="https://www.youtube-nocookie.com/embed/wlG_qTQF7fk" 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 <strong>eher </strong>für eine <strong>visuelle Darstellung </strong>des Beitrages zu haben bist, <strong>kannst </strong>Du Dir <strong>natürlich auch </strong>das <strong>Video </strong>(vielleicht auch ergänzend zum Beitrag) <strong>anschauen</strong>.</p>



<p><strong>Bei </strong>meinen Beiträgen bringe ich gerne auch immer diverse Detail-Infos, oder andere Dinge hinein.</p>



<p><strong>Leider fehlt </strong>mir dazu oft <strong>in </strong>den <strong>Videos die Zeit</strong>, da ich denke, dass man einen <strong>Beitrag einfacher durchscrollen </strong>kann.</p>



<p>Vor allem den Beitrag sinnvoll zu gliedern ist denke ich einfacher, <strong>als durch </strong>ein <strong>Video </strong>zu <strong>zappen</strong>.</p>



<p><strong>Immerhin hat <a href="https://youtube.com" target="_blank" rel="noreferrer noopener">YouTube</a></strong> seit geraumer Zeit <strong>eine </strong>Art <strong>Kapitelübersicht </strong>hinzugefügt, Welche ich auch gern verwende.</p>



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



<h2 class="wp-block-heading">Die Idee zum Beitrag – VB NET MouseClick</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/09/BackgroundWorker-starten.jpg"><img loading="lazy" decoding="async" width="640" height="360" src="https://robbelroot.de/wp-content/uploads/2021/09/BackgroundWorker-starten.jpg" alt="VB NET MouseClick - Die Idee zum Beitrag" class="wp-image-5991" title="VB NET MouseClick - Die Idee zum Beitrag"/></a><figcaption>VB NET MouseClick &#8211; Die Idee zum Beitrag</figcaption></figure>



<p><strong>Man möchte sich </strong>im Optimalfall natürlich <strong>selbst helfen </strong>können und <strong>besonders </strong>auch <strong>zukunftsorientiert</strong>.</p>



<p><strong>Gerne hätte man </strong>eine Art <strong>Hilfe </strong>in Form einer Person, der man dann einfach sagen könnte &#8222;<strong>Mach </strong>das <strong>mal</strong>..&#8220;.</p>



<p><strong>Als Programmierer können wir </strong>uns kreativen Köpfen selbstverständlich <strong>selbst </strong>unter die Arme greifen, man weiß nur nicht immer wie.</p>



<p><strong>Daher lass</strong>&#8218; <strong>mich Dir </strong>mit diesem kleinen Beitrag <strong>helfen </strong>und zeigen, wie Du einen <strong>VB NET MouseClick</strong> mit der Hilfe von <strong><a href="https://www.autoitscript.com/site/" target="_blank" rel="noreferrer noopener">AutoIt3</a></strong> durchführen kannst.</p>



<p><strong>Dadurch kannst Du </strong>dann verschiedene Tools wie <strong>diverse Klicker</strong>&#8211;<strong>Bots </strong>realisieren und Dir Deinen <strong>Alltag erleichtern</strong>.</p>



<h2 class="wp-block-heading">Nicht ohne mein AutoIt</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="Mit Hilfe von AutoIt" class="wp-image-6341" title="Mit Hilfe von AutoIt"/></a><figcaption>Mit Hilfe von AutoIt</figcaption></figure>



<p>Naja <strong>etwas witzig angelehnt </strong>die Headline hier, <strong>aber tatsächlich </strong>werden wir dieses kleine Geplänkel <strong>nicht ohne AutoIt3 </strong>realisieren.</p>



<p><strong>Klar gibt </strong>es auch die <strong>Möglichkeit </strong>in VB NET <strong>einfach </strong>ich nenne es mal &#8222;<strong>manuell</strong>&#8220; einen <strong>Mausklick </strong>zu <strong>simulieren</strong>, aber ich find&#8217;s hier <strong>mit AutoIt3 </strong>definitiv <strong>angenehmer</strong>.</p>



<p><strong>Wie auch </strong>im <a href="https://robbelroot.de/blog/vb-net-imagesearch-bilder-in-spielen-desktop-und-co-suchen/" target="_blank" rel="noreferrer noopener"><strong>&#8222;ImageSearch&#8220;-Beitrag</strong></a> schon angesprochen gehen <strong>viele Entwickler kritisch mit </strong>der <strong>Speichergröße </strong>der Projekte um.</p>



<p>Das <strong>kann ich </strong>natürlich <strong>nachvollziehen</strong>, da ich <strong>selbst </strong>ein <strong>Freund des Minimalismus </strong>bin, <strong>jedoch </strong>kann man die <strong>Kirche </strong>auch <strong>im Dorf lassen</strong>.</p>



<p>Ich würde mit Sicherheit in <strong>Festplatten</strong>&#8211;<strong>Generation </strong>&#8222;<strong>Terrabyte zum Preis von damaligen 80GB</strong>&#8220; nicht anfangen für 1MB rumzunörgeln.</p>



<p><strong>Letztendlich </strong>muss man ja <strong>immer </strong>den möglichen <strong>Mehrwert in Relation zur Eigenarbeit</strong> sehen.</p>



<p><strong>Später </strong>kannst Du <strong>bei </strong>einem intelligent <strong>strukturierten Programm natürlich </strong>bedürftige <strong>Komponenten </strong>isoliert <strong>austauschen</strong>.</p>



<h2 class="wp-block-heading">Projekt in Visual Studio vorbereiten</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 und vorbereiten" class="wp-image-6352" title="Neues Visual Studio Projekt anlegen und vorbereiten"/></a><figcaption>Neues Visual Studio Projekt anlegen und vorbereiten</figcaption></figure>



<p><strong>Lade </strong>Dir <strong>jetzt </strong>die <strong><a href="/downloads/tools/AutoItPackage.zip" target="_blank" rel="noreferrer noopener">benötigten Bibliotheken</a></strong> direkt hier <strong>herunter</strong>, oder suche alternativ nach <strong>anderen Quellen</strong> im Netz.</p>



<p><strong>Danach </strong>kannst Du wie üblich ein <strong>neues </strong>Windows Forms-, oder auch ein WPF-<strong>Projekt anlegen</strong>.</p>



<p><strong>Lege </strong>die &#8222;<strong>AutoItX3.Assembly.dll</strong>&#8222;-Datei nun als Verweis an, <strong>damit </strong>dein Projekt <strong>damit arbeiten </strong>kann.</p>



<p>Ganz <strong>einfach </strong>geht das zum Beispiel rechts <strong>über </strong>den <strong>Projektmappen-Explorer</strong> in Visual Studio.</p>



<p><strong>Führe </strong>dazu einfach einen <strong>rechten Mausklick </strong>auf &#8222;<strong>Verweise</strong>/<strong>Abhängigkeiten</strong>&#8220; <strong>aus </strong>und wähle die Datei aus.</p>



<p><strong>Neben </strong>dem Weg über den <strong>Projektmappen</strong>&#8211;<strong>Explorer </strong>gibt es <strong>auch </strong>noch <strong>andere Möglichkeiten</strong>.</p>



<p><strong>Kopiere </strong>anschließend <strong>alle anderen </strong>Dateien (außer die ImageSearchDLL.dll) <strong>in </strong>den <strong>Debug-Ordner</strong> deines Projekts.</p>



<p>Die <strong>oben </strong>erwähnte <strong>Datei </strong>dürfte sich <strong>aufgrund </strong>des <strong>Imports schon </strong>im Ordner befinden.</p>



<h2 class="wp-block-heading">Nun zum Code – VB NET MouseClick</h2>



<p>Sehen wir uns <strong>im nächsten Schritt </strong>den benötigten <strong>Code </strong>im Detail an.</p>



<p><strong>Wenn </strong>Du alle <strong>vorherigen Schritte abgeschlossen </strong>hast, kannst Du <strong>nun </strong>den korrekten <strong>Import </strong>durchführen:</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 AutoIt</pre>



<p><strong>Damit </strong>wird <strong>im aktuellen Scope </strong>die &#8222;AutoItX&#8220;-<strong>Klasse verfügbar</strong>, womit wir im nächsten Part den Klick realisieren können.</p>



<p><strong>Zuvor </strong>kannst Du Dir allerdings <strong>noch </strong>eine <strong>solche </strong>(oder ähnliche) <strong>GUI zurechtklicken </strong>– relativ simpel.</p>



<p><strong>Füge </strong>einfach nur <strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.label?view=net-5.0" target="_blank" rel="noreferrer noopener">2 Labels</a></strong>, <strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.textbox?view=net-5.0" target="_blank" rel="noreferrer noopener">2 Textboxen</a></strong> und einen <strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.button?view=net-5.0" target="_blank" rel="noreferrer noopener">Button</a> </strong>hinzu:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/10/VB.NET-MouseClick-simulieren-Beispiel-GUI.png"><img loading="lazy" decoding="async" width="296" height="147" src="https://robbelroot.de/wp-content/uploads/2021/10/VB.NET-MouseClick-simulieren-Beispiel-GUI.png" alt="VB.NET MouseClick simulieren Beispiel-GUI" class="wp-image-6431" title="VB.NET MouseClick simulieren Beispiel-GUI"/></a><figcaption>VB.NET MouseClick simulieren Beispiel-GUI</figcaption></figure>



<p>Die <strong>2 Labels</strong> sollen <strong>einfach </strong>nur ein wenig <strong>fürs Auge </strong>klar machen, <strong>welche Inputs</strong>, <strong>wo hinein </strong>müssen.</p>



<p><strong>Bei </strong>den <strong>Textboxen </strong>handelt es sich um <strong>Eingabefelder für </strong>die <strong>Koordinaten</strong>, allerdings verzichten wir hier im Code auf Prüfungen.</p>



<p><strong>Wir werden </strong>also <strong>der Einfachheit halber nicht </strong>weiter <strong>überprüfen</strong>, <strong>ob </strong>es sich bei den Eingaben um <strong>Zahlen </strong>handelt, bzw. <strong>ob </strong>etwas <strong>eingegeben </strong>wurde.</p>



<p><strong>Nun ziehen </strong>wir die <strong>Koordinaten aus </strong>den <strong>Textboxen </strong>und wandeln Diese dann in <strong>Ganzzahlen </strong>vom Typ <strong><a href="https://docs.microsoft.com/de-de/dotnet/visual-basic/language-reference/data-types/integer-data-type" target="_blank" rel="noreferrer noopener">Integer</a></strong> um:</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 x = Integer.Parse(tbX.Text)
Dim y = Integer.Parse(tbY.Text)</pre>



<p><strong>Danach </strong>können wir dann die wichtige und <strong>essentielle AutoIt3-Funktion</strong> namens &#8222;<strong>MouseClick</strong>&#8220; 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="">AutoItX.MouseClick("LEFT", x, y, 1, 50)</pre>



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



<p>Die <strong>möglichen Parameter </strong>möchte ich <strong>hier </strong>einmal näher erläutern:</p>



<p><strong>Weitere Informationen </strong>findest Du <strong>in </strong>der <strong><a href="https://www.autoitscript.com/autoit3/docs/functions/MouseClick.htm" target="_blank" rel="noreferrer noopener">offiziellen Dokumentation</a></strong> von AutoIt.</p>



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



<p><strong>Hier </strong>können wir den <strong>gewünschten Button als String </strong>übergeben, mögliche Werte sind: &#8222;&#8220; (leer), &#8222;LEFT&#8220;, &#8222;MIDDLE&#8220;, &#8222;RIGHT&#8220;, &#8222;PRIMARY&#8220;, &#8222;MAIN&#8220;, &#8222;SECONDARY&#8220;, &#8222;MENU&#8220;. <strong>Wenn </strong>ein <strong>leerer String </strong>übergeben wird, wird <strong>automatisch </strong>die <strong>linke Maustaste </strong>verwendet.</p>



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



<p>Gibt den Koordinaten-Punkt des Klicks auf der horizontalen (X) Achse an.</p>



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



<p>Setzt die Koordinate des auszuführenden Klicks auf der vertikalen (Y) Achse.</p>



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



<p><strong>Legt </strong>die <strong>Anzahl der </strong>durchzuführenden <strong>Klicks </strong>an den Koordinaten <strong>fest</strong>.</p>



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



<p>Gibt die Geschwindigkeit der durchzuführenden Klicks an.</p>



<h2 class="wp-block-heading">Der komplette Code – TL;DR</h2>



<p>Es ist <strong>zwar nicht viel</strong>, oder gar komplexer Code, <strong>aber hier </strong>siehst Du Ihn <strong>in einem</strong> <strong>Stück </strong>– vielleicht für die &#8222;TL;DR&#8220;-guys haha.</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 AutoIt

Public Class Form1

    Private Sub btnExecuteClick_Click(sender As Object, e As EventArgs) Handles btnExecuteClick.Click
        Dim x = Integer.Parse(tbX.Text)
        Dim y = Integer.Parse(tbY.Text)
        AutoItX.MouseClick("LEFT", x, y, 1, 50)
    End Sub

End Class</pre>



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



<ul class="wp-block-list"><li><strong><a href="https://robbelroot.de/blog/vb-net-imagesearch-bilder-in-spielen-desktop-und-co-suchen" target="_blank" rel="noreferrer noopener">VB NET ImageSearch – Bilder in Spielen, Desktop und Co. suchen</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><li><strong><a href="https://robbelroot.de/blog/vbnet-texterkennung-auf-bildern/" target="_blank" rel="noreferrer noopener">VB.NET Texterkennung auf Bildern via Google Cloud Vision API [OCR]</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">AutoItPackage.zip</a></div>



<div class="wp-block-button"><a class="wp-block-button__link" href="/downloads/vbnet/MouseClickExample.zip" target="_blank" rel="noreferrer noopener">MouseClickExample.zip</a></div>
</div>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vb-net-mouseclick-simulieren-mit-autoit3/">VB NET MouseClick simulieren – mit AutoIt3</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vb-net-mouseclick-simulieren-mit-autoit3/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>VB.NET Texterkennung auf Bildern via Google Cloud Vision API [OCR]</title>
		<link>https://robbelroot.de/blog/vbnet-texterkennung-auf-bildern/</link>
					<comments>https://robbelroot.de/blog/vbnet-texterkennung-auf-bildern/#comments</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Tue, 24 Aug 2021 01:44:36 +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[api]]></category>
		<category><![CDATA[basic]]></category>
		<category><![CDATA[bild]]></category>
		<category><![CDATA[card]]></category>
		<category><![CDATA[cardgame]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[dotnet]]></category>
		<category><![CDATA[erkennen]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[jpg]]></category>
		<category><![CDATA[karte]]></category>
		<category><![CDATA[kartenspiel]]></category>
		<category><![CDATA[lesen]]></category>
		<category><![CDATA[ocr]]></category>
		<category><![CDATA[optical character recognization]]></category>
		<category><![CDATA[optische]]></category>
		<category><![CDATA[png]]></category>
		<category><![CDATA[recognize]]></category>
		<category><![CDATA[text]]></category>
		<category><![CDATA[texterkennung]]></category>
		<category><![CDATA[trading card game]]></category>
		<category><![CDATA[vb]]></category>
		<category><![CDATA[vbnet]]></category>
		<category><![CDATA[verarbeiten]]></category>
		<category><![CDATA[vision]]></category>
		<category><![CDATA[visual]]></category>
		<category><![CDATA[yugioh]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=5877</guid>

					<description><![CDATA[<p>VB.NET Texterkennung auf Bildern [OCR] Du möchtest eine VB.NET Texterkennung auf Bildern umsetzen, weiß nur noch nicht ganz wie? Kein Problem! In meinem heutigen Beitrag und dem dazugehörigen YouTube-Video, erkläre ich es Dir! Dazu brauchst Du nicht viel mehr als ein passendes NuGet-Package von Google und die passenden Zugangsdaten. Im &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-texterkennung-auf-bildern/">VB.NET Texterkennung auf Bildern via Google Cloud Vision API [OCR]</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/08/OCR-Thumbnail.png"><img loading="lazy" decoding="async" width="1920" height="1080" src="https://robbelroot.de/wp-content/uploads/2021/08/OCR-Thumbnail.png" alt="VB.NET Texterkennung auf Bildern" class="wp-image-5879" title="VB.NET Texterkennung auf Bildern"/></a><figcaption>VB.NET Texterkennung auf Bildern</figcaption></figure>






<h2 class="wp-block-heading" id="vb-net-texterkennung-auf-bildern-ocr">VB.NET Texterkennung auf Bildern [OCR]</h2>



<p>Du möchtest eine VB.NET Texterkennung auf Bildern umsetzen, weiß nur noch nicht ganz wie?</p>



<p>Kein Problem! In meinem heutigen Beitrag und dem dazugehörigen YouTube-Video, erkläre ich es Dir!</p>



<p>Dazu brauchst Du nicht viel mehr als ein passendes <strong><a href="https://de.wikipedia.org/wiki/NuGet" target="_blank" rel="noreferrer noopener">NuGet-Package</a></strong> von Google und die passenden Zugangsdaten.</p>



<h2 class="wp-block-heading" id="im-videoformat-auf-youtube-ansehen">Im Videoformat auf YouTube ansehen</h2>



<p>Falls Du Dir das Tutorial lieber in flüssigerer Form ansehen möchtest, kannst Du Dir selbstverständlich auch das folgende YouTube-Video ansehen.</p>



<p>Dort zeige ich Dir alles Schritt für Schritt und im Detail, wie Du Deine Texterkennung &#8222;ready to go&#8220; machst.</p>



<p>Ebenso weise ich Dich auf diverse Dinge wie Fehlermeldungen und Nutzungskontingente der &#8222;Google Cloud Vision&#8220;-Schnittstelle hin.</p>



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



<h2 class="wp-block-heading" id="einsatzmoglichkeiten-und-hintergrunde">Einsatzmöglichkeiten und Hintergründe</h2>



<p>Die Einsatzmöglichkeiten der optischen Zeichenerkennung sind breit gestreut.</p>



<p>Mit der Verwendung der &#8222;<a href="https://de.wikipedia.org/wiki/Texterkennung" target="_blank" rel="noreferrer noopener">optical character recoginition</a>&#8220; (kurz OCR) können z. B. viele Bereiche im Arbeitsalltag erleichtert werden.</p>



<p>Häufig vertreten ist die OCR beispielweise im Bereich der Finanzen, Steuerdokumente etc. automatisch eingelesen und abgeglichen werden.</p>



<p>Dies hat natürlich den Vorteil, dass man kein zusätzliches Personal benötigt, um die Arbeit zu erledigen.</p>



<p>Neben dem personellen Faktor und den damit verbundenen Kosten an sich, ist eine automatisierte Variante durch OCR natürlich auch performanter.</p>



<p>Man kann also den (denke ich) wichtigsten Bereich als Digitalisierung von Dokumenten bezeichnen.</p>



<h2 class="wp-block-heading" id="meine-eigene-story-zur-ocr">Meine eigene Story zur OCR</h2>



<p>Ich selbst bin hier und da mal aus verschiedenen Gründen auf das Thema OCR gestoßen.</p>



<p>Wir Du oben im Video eventuell gesehen hast, verwende ich dort eine  Yu-Gi-Oh!-Karte.</p>



<p>Für die weniger &#8222;Trading-Cardgame&#8220; orientierte Leser, ist  Yu-Gi-Oh! praktisch nur ein Sammelkartenspiel, wo es verschiedene Arten von Karten gibt.</p>



<p>Darunter befinden sich Monster, Zauber- und Fallenkarten und mehr, Welche selbst unterschiedliche Funktionen im Spiel selbst haben.</p>



<p>Wie fast immer, wenn wir über eines der Lieblingsthemen des Menschen, also das Sammeln nachdenken, gibt es natürlich auch einen gewissen Wert.</p>



<p>Während normale &#8222;Common&#8220;-Karten zu Centbeträgen, bzw. überhaupt gehandelt werden, gibt es auch durchaus Wertvollere.</p>



<p>Wenn man den folgenden Betrag, der &#8222;Tournament Black Luster Soldier&#8220;-Karte hört, könnte man glatt in Ohnmacht fallen.</p>



<p>Setze Dich also daher besser hin, wenn Du nicht sowieso schon auf Deinem Stuhl o. Ä. Platz genommen hast.</p>



<h2 class="wp-block-heading" id="die-teuerste-karte-der-welt">Die teuerste Karte der Welt</h2>



<p>Die laut meiner Erfahrung teuerste Karte der Welt soll round about 2 Millionen US-Dollar kosten, ja richtig gelesen.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/08/yu-gi-oh-tournament-black-luster-soldier-thumbnail.jpg"><img loading="lazy" decoding="async" width="1920" height="1080" src="https://robbelroot.de/wp-content/uploads/2021/08/yu-gi-oh-tournament-black-luster-soldier-thumbnail.jpg" alt="Die 2 Millionen Dollar Yu-Gi-Oh!-Karte – Tournamen Black Luster Soldier (Quelle: quora.com)" class="wp-image-5894" title="Die 2 Millionen Dollar Yu-Gi-Oh!-Karte – Tournamen Black Luster Soldier"/></a><figcaption>Die 2 Millionen Dollar Yu-Gi-Oh!-Karte – Tournamen Black Luster Soldier – (Quelle: quora.com)</figcaption></figure>



<p>Diese Karte wurde im Jahr 1999 in Japan im Rahmen einer Yu-Gi-Oh!-Meisterschaft an den Gewinner übergeben.</p>



<p>Ich selbst kannte mich durchaus gut im Bereich Yu-Gi-Oh! aus, hatte aber natürlich keine Lust meine Karten manuell durchzuschauen.</p>



<p>Im Endeffekt denke ich mir natürlich: &#8222;Wofür kannst Du denn programmieren?&#8220;.</p>



<p>So begann ich damals mich mit OCR auseinanderzusetzen und die Google Cloud Vision API zum Laufen zu bringen.</p>



<p>Mit einer Webcam bin ich dann letztendlich die einzelnen Karten durchgegangen und so Karte für Karte überprüft.</p>



<p>Gerne hätte ich hierfür eine Art Maschine gehabt, die also auch das Aufheben- und Ablegen von Karten unterstützte.</p>



<p>Diese Maschinen gibt es auch, kosten aber leider ein paar tausend Euro – ich hatte sogar die Idee selbst eine zu bauen, habe Diese aber verworfen.</p>



<p>Wie sich herausstellte hatte ich in meiner Sammlung hier und da ein paar gute Karten versteckt.</p>



<p>Darunter befand sich unter anderem eine &#8222;Elementarheld Bubbleman&#8220;-Karte, Welche ich für ca. 34€ auf eBay verkaufen konnte – nice!</p>



<p>Bis heute bin ich auch noch stolzer Besitzer einer &#8222;Wolkenkratzer&#8220;-Karte, Welche einen Fehldruck besitzt, es fehlt dort der Aufdruck des Titels.</p>



<figure class="wp-block-image size-full is-resized"><a href="https://robbelroot.de/wp-content/uploads/2021/08/Wolkenkratzer-Karte-mit-Fehldruck-fehlender-Titel.jpg"><img loading="lazy" decoding="async" src="https://robbelroot.de/wp-content/uploads/2021/08/Wolkenkratzer-Karte-mit-Fehldruck-fehlender-Titel.jpg" alt="Wolkenkratzer Karte mit Fehldruck - fehlender Titel" class="wp-image-5898" width="360" height="480" title="Wolkenkratzer Karte mit Fehldruck - fehlender Titel"/></a><figcaption>Wolkenkratzer Karte mit Fehldruck &#8211; fehlender Titel</figcaption></figure>



<p>Nun aber genug vom Trading Card Game und zurück zum eigentlichen Thema – VB.NET Texterkennung auf Bildern.</p>



<h2 class="wp-block-heading" id="google-cloud-vision-api">Google Cloud Vision API</h2>



<p>Die Google Cloud Vision API dient der Erkennung von Daten auf Bildern und kann somit in vielen Bereichen eine Hilfe sein.</p>



<p>Durch die einfache, intuitive Verwendung und die einfache Installation via NuGet-Paket-Manager lässt Dich schnell starten.</p>



<p>Schreibe doch gerne in die Kommentare unten und lass mich wissen, wofür Du die Google Cloud Vision API verwendest!</p>



<p>Die <strong><a href="https://cloud.google.com/dotnet/docs/reference/Google.Cloud.Vision.V1/latest/index" target="_blank" rel="noreferrer noopener">Dokumentation zur API</a></strong> für z. B. weitere Recherche, findest Du im angegeben Link.</p>



<h2 class="wp-block-heading" id="die-anwendung-vb-net-texterkennung-auf-bildern">Die Anwendung – VB.NET Texterkennung auf Bildern</h2>



<p>Einen Einblick in das fertige Beispiel siehst Du hier im animierten Gif-Bild.</p>



<p>Die Datei, bzw. das Bild wird hier eingelesen und anschließend mit der API von Google ausgewertet.</p>



<p>Anschließend verarbeiten wir die vom Server verarbeiteten Daten, wie wir es letztendlich möchten.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/08/VBNET-OCR-Texterkennung-Bild-YuGiOh-Karte-Beispiel.gif"><img loading="lazy" decoding="async" width="799" height="527" src="https://robbelroot.de/wp-content/uploads/2021/08/VBNET-OCR-Texterkennung-Bild-YuGiOh-Karte-Beispiel.gif" alt="VB.NET Texterkennung auf Bildern – YuGiOh Karte" class="wp-image-5904" title="VB.NET Texterkennung auf Bildern – YuGiOh Karte"/></a><figcaption>VB.NET Texterkennung auf Bildern – YuGiOh Karte</figcaption></figure>



<h3 class="wp-block-heading" id="installation-des-nuget-paketes">Installation des NuGet-Paketes</h3>



<p>Der erste Schritt in Richtung Ziel ist es, das von Google bereitgestellte NuGet-Paket für die Google Cloud Vision API zu installieren.</p>



<p>Das geht entweder über den Paketmanager, oder direkt über die NuGet-Paket-Manager-Konsole.</p>



<p>In der Konsole führen wir einfach den folgenden Befehl aus und alles Notwendige wird installiert.</p>



<p>Ich verwende hier erfolgreich die angegebene Version &#8222;2.3.0&#8220;:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Install-Package Google.Cloud.Vision.V1 -Version 2.3.0</pre>



<p>Alternativ kann man laut Google-Dokumentation auch diesen Befehl hier verwenden:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Install-Package Google.Apis</pre>



<p>Allerdings hört sich das für mich so an, als würde man hier praktisch alle möglichen APIs installieren, Du kannst es ja mal testen..</p>



<h3 class="wp-block-heading" id="dienstkonto-erstellen-vb-net-texterkennung-auf-bildern">Dienstkonto erstellen –  VB.NET Texterkennung auf Bildern </h3>



<p>Im nächsten Schritt müssen wir für die Verwendung der API ein <strong><a href="https://cloud.google.com/vision/docs/libraries#cloud-console" target="_blank" rel="noreferrer noopener">Dienstkonto erstellen</a></strong>, dafür findest Du den passenden Button auf der verlinkten Seite von Google.</p>



<p>Falls Du noch kein Projekt hast (war bei mir nicht der Fall), musst Du ggf. noch ein Projekt erstellen, das dürfte aber nicht weiter schwer sein.</p>



<p>Nachdem Du ein Projekt zur Verfügung hast, wählst Du Dieses aus und kannst das Dienstkonto erstellen:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/08/Google-Cloud-Platform-Dienstkonto-erstellen.png"><img loading="lazy" decoding="async" width="846" height="684" src="https://robbelroot.de/wp-content/uploads/2021/08/Google-Cloud-Platform-Dienstkonto-erstellen.png" alt="Google Cloud Platform Dienstkonto erstellen" class="wp-image-5910" title="Google Cloud Platform Dienstkonto erstellen"/></a><figcaption>Google Cloud Platform Dienstkonto erstellen</figcaption></figure>



<p>Ich habe für meine Testzwecke einfach nur &#8222;fueryoutube&#8220; eingetragen und die optionalen Felder einfach leer gelassen.</p>



<h3 class="wp-block-heading" id="schlussel-erstellen">Schlüssel erstellen</h3>



<p>Wenn das Dienstkonto erstellt ist, kannst Du dort nun einen Schlüssel im dementsprechenden Tab erstellen (JSON):</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/08/Google-Cloud-Platform-Dienstkonto-Schluessel-erstellen.png"><img loading="lazy" decoding="async" width="845" height="535" src="https://robbelroot.de/wp-content/uploads/2021/08/Google-Cloud-Platform-Dienstkonto-Schluessel-erstellen.png" alt="VB.NET Texterkennung auf Bildern - Google Cloud Platform Dienstkonto Schlüssel erstellen" class="wp-image-5912" title="Google Cloud Platform Dienstkonto Schlüssel erstellen"/></a><figcaption>Google Cloud Platform Dienstkonto Schlüssel erstellen</figcaption></figure>



<h3 class="wp-block-heading" id="schlussel-als-json-herunterladen">Schlüssel als JSON herunterladen</h3>



<p>Die JSON Datei wird dann heruntergeladen und ist für unseren Code verwendbar:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/08/Google-Cloud-Platform-Dienstkonto-Schluessel-erstellen-JSON.png"><img loading="lazy" decoding="async" width="567" height="384" src="https://robbelroot.de/wp-content/uploads/2021/08/Google-Cloud-Platform-Dienstkonto-Schluessel-erstellen-JSON.png" alt="VB.NET Texterkennung auf Bildern - Google Cloud Platform Dienstkonto Schlüssel erstellen JSON" class="wp-image-5914" title="Google Cloud Platform Dienstkonto Schlüssel erstellen JSON"/></a><figcaption>Google Cloud Platform Dienstkonto Schlüssel erstellen JSON</figcaption></figure>



<p>Nachdem wir nun fürs Erste mit der Google-Konfiguration fertig sind, können wir dann endlich zum Code starten.</p>



<h3 class="wp-block-heading" id="code-vb-net-texterkennung-auf-bildern">Code –  VB.NET Texterkennung auf Bildern</h3>



<p>Nun können wir uns dem Code und somit dem eigentlichen Spaß, also der VB.NET Texterkennung auf Bildern widmen – seufz..</p>



<h4 class="wp-block-heading" id="konstanten">Konstanten</h4>



<p>Im ersten Schritt legen wir 3 Konstanten an, Welcher diverse Werte speichern werden.</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 Const GOOGLE_APP_CREDENTIALS_ENV_VAR_NAME As String = "GOOGLE_APPLICATION_CREDENTIALS"
Public Const CREDENTIALS_FILE_PATH As String = "C:\Users\Anwender\Downloads\credentials.json"
Public Const CARD_IMAGE_FILE_PATH As String = "C:\Users\Anwender\Downloads\ElementarHeld Bubbleman.jpg"</pre>



<h5 class="wp-block-heading" id="google-app-credentials-env-var-name">GOOGLE_APP_CREDENTIALS_ENV_VAR_NAME</h5>



<p>Diese Konstante beinhaltet den Namen der Umgebungsvariable, Welche wir laut Google-Dokumentation verwenden müssen.</p>



<h5 class="wp-block-heading" id="credentials-file-path">CREDENTIALS_FILE_PATH</h5>



<p>Dies ist ein simpler Dateipfad, wo sich nachher die Datei mit unseren Zugangsdaten befindet, Welche wir oben als JSON-Datei heruntergeladen haben. Achte auf einen passenden Namen!</p>



<h5 class="wp-block-heading" id="card-image-file-path">CARD_IMAGE_FILE_PATH</h5>



<p>Die letzte Konstante speichert den Pfad zum jeweiligen Bild, Welches wir einlesen und verarbeiten möchten. Der Google Client erwartet letztendlich ein Bild. Dieses Bild hat einen eigenen von Google definierten Dateityp, wovon mit Factory-Methoden einzelne Instanzen erzeugt werden können. Dazu gleich mehr..</p>



<h3 class="wp-block-heading" id="der-aufruf-selbst">Der Aufruf selbst</h3>



<p>Kommen wir nun nach dem Motto &#8222;das Beste kommt zum Schluss&#8220;, an den eigentlichen Aufruf der Google-Schnittstelle:</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 Async Sub btnRecognizeCardText_Click(sender As Object, e As EventArgs) Handles btnRecognizeCardText.Click
        Environment.SetEnvironmentVariable(GOOGLE_APP_CREDENTIALS_ENV_VAR_NAME, CREDENTIALS_FILE_PATH)
        ' Dim img = Image.FetchFromUri("")
        Dim img = Await Image.FromFileAsync(CARD_IMAGE_FILE_PATH)
        Dim client = Await ImageAnnotatorClient.CreateAsync()
        Dim textAnnotations = Await client.DetectTextAsync(img)
        For Each anno In textAnnotations
            tbRecognizedText.AppendText($"{anno.Description} ")
        Next
    End Sub</pre>



<p>In der ersten Zeile setzen wir wie von der Dokumentation vorgegeben eine Umgebungsvariable mit passendem Namen. Dies könnte man natürlich auch nur einmalig im Load machen..</p>



<p>Danach können wir auf verschiedene Weisen ein passendes Image der Google Library erzeugen.</p>



<p>In diesem Beispiel verwende ich dafür die &#8222;FromFileAsync&#8220;-Factory-Funktion.</p>



<p>Schaue mit Hilfe von Intellisense-Code-Vorschlägen doch einfach mal die anderen Möglichkeiten durch.</p>



<p>Danach erzeuge ich mit Hilfe der &#8222;ImageAnnotatorClient.CreateAsync&#8220;-Factory- Funktion , einen neuen Client, womit wir die Anfragen dann gleich senden.</p>



<p>Beim Client kann ich dann die &#8222;DetectTextAsync&#8220;-Funktion mit Hilfe des &#8222;Bild&#8220;-Parameters aufrufen und bekomme die erkannten Daten zurück.</p>



<p>Diese durchlaufe ich anschließend mit Hilfe der Schleife und zeige Sie in der Textbox an.</p>



<p>Auch hier der Tipp: Schaue Dir mit Intellisense (oder mit der Doku) die alternativen Methoden wie &#8222;DetectLogos&#8220; an.</p>



<p>Die passende Doku dazu findest Du unter diesem Link: &#8222;<strong><a href="https://cloud.google.com/dotnet/docs/reference/Google.Cloud.Vision.V1/latest/index#detect-text-in-a-single-image" target="_blank" rel="noreferrer noopener">Google Cloud Vision API V1</a></strong>&#8222;.</p>



<h2 class="wp-block-heading" id="kompletter-code-vb-net-texterkennung-auf-bildern">Kompletter Code –  VB.NET Texterkennung auf Bildern </h2>



<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 Google.Cloud.Vision.V1

Public Class Form1

    Public Const GOOGLE_APP_CREDENTIALS_ENV_VAR_NAME As String = "GOOGLE_APPLICATION_CREDENTIALS"

    Public Const CREDENTIALS_FILE_PATH As String = "C:\Users\Anwender\Downloads\credentials.json"

    Public Const CARD_IMAGE_FILE_PATH As String = "C:\Users\Anwender\Downloads\ElementarHeld Bubbleman.jpg"

    Private Async Sub btnRecognizeCardText_Click(sender As Object, e As EventArgs) Handles btnRecognizeCardText.Click
        Environment.SetEnvironmentVariable(GOOGLE_APP_CREDENTIALS_ENV_VAR_NAME, CREDENTIALS_FILE_PATH)
        ' Dim img = Image.FetchFromUri("")
        Dim img = Await Image.FromFileAsync(CARD_IMAGE_FILE_PATH)
        Dim client = Await ImageAnnotatorClient.CreateAsync()
        Dim textAnnotations = Await client.DetectTextAsync(img)
        For Each anno In textAnnotations
            tbRecognizedText.AppendText($"{anno.Description} ")
        Next
    End Sub

End Class</pre>



<h2 class="wp-block-heading" id="downloads-links">Downloads &amp; Links</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/YuGiOhCardVisionExampleVB.zip" target="_blank" rel="noreferrer noopener">YuGiOhCardVisionExampleVB.zip</a></div>



<div class="wp-block-button"><a class="wp-block-button__link" href="https://cloud.google.com/dotnet/docs/reference/Google.Cloud.Vision.V1/latest/index" target="_blank" rel="noreferrer noopener">Google Cloud API Documentation</a></div>



<div class="wp-block-button"><a class="wp-block-button__link" href="https://cloud.google.com/docs/authentication/getting-started" target="_blank" rel="noreferrer noopener">Dienstkonto erstellen</a></div>
</div>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-texterkennung-auf-bildern/">VB.NET Texterkennung auf Bildern via Google Cloud Vision API [OCR]</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vbnet-texterkennung-auf-bildern/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>VBA</title>
		<link>https://robbelroot.de/blog/vba/</link>
					<comments>https://robbelroot.de/blog/vba/#respond</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Sun, 15 Aug 2021 19:22:04 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Visual Basic for Applications]]></category>
		<category><![CDATA[Visual Basic for Applications lernen]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[applications]]></category>
		<category><![CDATA[basic]]></category>
		<category><![CDATA[büro]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[familie]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[msft]]></category>
		<category><![CDATA[office]]></category>
		<category><![CDATA[onedrive]]></category>
		<category><![CDATA[onenote]]></category>
		<category><![CDATA[outlook]]></category>
		<category><![CDATA[powerpoint]]></category>
		<category><![CDATA[produkte]]></category>
		<category><![CDATA[teams]]></category>
		<category><![CDATA[vba]]></category>
		<category><![CDATA[visio]]></category>
		<category><![CDATA[visual]]></category>
		<category><![CDATA[visual basic]]></category>
		<category><![CDATA[visual basic for applications]]></category>
		<category><![CDATA[word]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=5700</guid>

					<description><![CDATA[<p>VBA Ein weiteres Akronym Namens VBA geistert seit längerer Zeit in der Welt der IT, aber auch im Büroalltag umher. Besonders Büroangestellte nutzen VBA häufig in Kombination mit den Microsoft Office Produkten, teilweise auch ohne es aktiv zu wissen. Doch was ist dieses VBA &#8222;Ding&#8220; denn nun, wofür wurde es &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vba/">VBA</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/08/VBA-Logo-–-Visual-Basic-for-Applications.png"><img loading="lazy" decoding="async" width="1200" height="628" src="https://robbelroot.de/wp-content/uploads/2021/08/VBA-Logo-–-Visual-Basic-for-Applications.png" alt="VBA Logo – Visual Basic for Applications" class="wp-image-5720" title="VBA Logo – Visual Basic for Applications"/></a><figcaption>VBA Logo – Visual Basic for Applications</figcaption></figure>






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



<p>Ein <strong>weiteres Akronym </strong>Namens <strong>VBA </strong>geistert seit längerer Zeit in der <strong>Welt der IT</strong>, aber <strong>auch </strong>im <strong>Büroalltag </strong>umher.</p>



<p><strong>Besonders Büroangestellte </strong>nutzen <strong>VBA </strong>häufig in Kombination mit den <strong>Microsoft Office Produkten</strong>, <strong>teilweise </strong>auch <strong>ohne </strong>es aktiv zu <strong>wissen</strong>.</p>



<p>Doch <strong>was ist </strong>dieses <strong>VBA </strong>&#8222;Ding&#8220; denn nun, <strong>wofür </strong>wurde es <strong>erfunden </strong>und <strong>was macht man </strong>damit genau?</p>



<h2 class="wp-block-heading">Was ist VBA?</h2>



<p><strong>VBA </strong>ist <strong>wie </strong>oben schon eingängig <strong>erwähnt </strong>ein <strong>Akronym</strong>, also eine <strong>Abkürzung für </strong>die Wörter &#8222;<strong>Visual Basic for Applications</strong>&#8222;.</p>



<p>Was <strong>irgendwie nach </strong>einer Art <strong>Brillenputzmittel</strong>, bzw. <strong>Auflage </strong>auf <strong>Brillen </strong>klingt, <strong>ist </strong>in Wahrheit eine <strong><a href="https://de.wikipedia.org/wiki/Skriptsprache" target="_blank" rel="noreferrer noopener">Skriptsprache</a></strong>.</p>



<p><strong>Diese Skriptsprache </strong>wurde <strong>von </strong>der <strong>Firma Microsoft </strong>unterstützend zu vielen Ihrer <strong>Office Produkte</strong>, wie z. B. <strong>Excel </strong>und <strong>Word entwickelt</strong>.</p>



<h2 class="wp-block-heading">Wofür VBA?</h2>



<p><strong>Da </strong>wir <strong>nun verstanden </strong>haben <strong>wo VBA eingesetzt </strong>wird, <strong>also bei </strong>bestehenden <strong>Produkten wie </strong>z. B. <strong>Microsoft Excel</strong>, schauen wir uns nun <strong>dessen Verwendung </strong>an.</p>



<p>Meiner <strong>persönlichen Erfahrung </strong>nach, <strong>denken viele </strong>Kenner <strong>sofort </strong>an <strong>Excel</strong>, <strong>wenn </strong>sie das <strong>Stichwort </strong>&#8222;<strong>VBA</strong>&#8220; hören, nicht ohne Grund.</p>



<p><strong>Auch wenn </strong>die <strong>Microsoft Office</strong> Produktfamilie <strong>natürlich </strong>über einen sehr <strong>großen Funktionsumfang </strong>verfügt, hat man häufig <strong>individuelle Wünsche</strong>.</p>



<p>Neben den individuellen Wünschen <strong>spielt </strong>natürlich <strong>auch </strong>z. B. die <strong>Automatisierung </strong>von gewissen Prozessen eine <strong>große Rolle</strong>.</p>



<p><strong>Wer hat </strong>schon <strong>Lust</strong>, die häufig an <strong>Praktikanten </strong>verteilte <strong>Arbeit </strong>zu <strong>übernehmen </strong>und sich <strong>dumm </strong>und <strong>dusselig </strong>zu <strong>klicken</strong>.</p>



<p><strong>Dafür könnte </strong>man sich einige <strong>kleine Skripte </strong>in VBA bauen, <strong>Die </strong>einem <strong>dann </strong>diese unangenehme <strong>Arbeit</strong> <strong>abnehmen</strong>, <strong>oder </strong>zumindest <strong>erleichtert</strong>.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/08/VBA-Was-ist-das-1.png"><img loading="lazy" decoding="async" width="1200" height="628" src="https://robbelroot.de/wp-content/uploads/2021/08/VBA-Was-ist-das-1.png" alt="VBA - Was ist das?" class="wp-image-5727" title="VBA - Was ist das"/></a><figcaption>VBA &#8211; Was ist das?</figcaption></figure>



<h2 class="wp-block-heading">Was ist nun das VB in VBA?</h2>



<p><strong>Nun kommst </strong>Du ggf. mit deinen <strong>Englischkenntnissen an </strong>den <strong>Punkt</strong>, <strong>wo </strong>Du die Bedeutung des &#8222;..<strong>for Applications</strong>&#8220; verstanden hast.</p>



<p>Denn <strong>wie erklärt</strong>, <strong>erweitert </strong>man bestehende <strong><a href="https://de.wikipedia.org/wiki/Microsoft_Office" target="_blank" rel="noreferrer noopener">Office-Programme</a></strong> <strong>durch VBA </strong>um seine individuell <strong>gewünschten Programm</strong>&#8211;<strong>Funktionen</strong>.</p>



<p><strong>Was </strong>dabei <strong>allerdings </strong>noch <strong>offen bleibt </strong>ist dieser <strong>Teil namens </strong>&#8222;Visual Basic&#8220; in <strong>VBA</strong>.</p>



<p><strong>Visual Basic</strong> (Classic) – oder auch kurz &#8222;VB&#8220; – ist die <strong><a href="https://de.wikipedia.org/wiki/Programmiersprache" target="_blank" rel="noreferrer noopener">Programmiersprache</a> worauf VBA </strong>letztendlich <strong>basiert</strong>.</p>



<p>Sie <strong>ist </strong>der <strong>Vorreiter für </strong>die <strong>Sprache</strong>, <strong>weshalb </strong>diese <strong>Webseite </strong>vor vielen Jahren überhaupt <strong>entstanden ist </strong>– Visual Basic NET.</p>



<h2 class="wp-block-heading">Einsatzbeispiel für VBA</h2>



<p><strong>Wie oben </strong>bereits <strong>erwähnt </strong>gibt es <strong>teilweise Situationen</strong> in denen man sich <strong>gerne </strong>ein <strong>Skript für wiederkehrende Arbeiten </strong>erstellen möchte.</p>



<p><strong>Damit </strong>könnte man <strong>nach initial </strong>investierter <strong>Zeit</strong>, <strong>zukünftig </strong>ein <strong>Vielfaches </strong>dieser Arbeitszeit und Arbeitskraft <strong>sparen </strong>und vereinfachen.</p>



<p>Schauen wir uns dafür <strong>in diesem Abschnitt </strong>einmal ein <strong>kleines Beispiel </strong>an, wo wir so eine <strong>individuelle Erweiterung </strong>genauer <strong>betrachten</strong>.</p>



<p>Das <strong>Beispiel in </strong>all seinen <strong>vollständigen Details </strong>findest Du im Beitrag &#8222;<strong><a href="https://robbelroot.de/blog/serienbrief-excel/" target="_blank" rel="noreferrer noopener">Serienbrief mit Ecxel</a></strong>&#8222;, ich <strong>werde hier </strong>die <strong>wesentlichen Schritte </strong>wiederholen.</p>



<p>Dabei <strong>ergänze ich </strong>einige <strong>Sachen</strong>, Welche zu diesem <strong>Beitrag </strong>hier <strong>besser passen </strong>und daher <strong>einfacher nachvollziehbar </strong>sind.</p>



<h3 class="wp-block-heading">Das Dilemma mit den Adressen</h3>



<p><strong>Jeder der schonmal </strong>in seinem Leben <strong>mit Adress-Daten</strong> gearbeitet hat, <strong>kennt </strong>das dahinter steckende <strong>Dilemma</strong>.</p>



<p><strong>Mal </strong>werden Postleitzahl und Ort <strong>vertauscht</strong>, hier und da <strong>ein Leerzeichen </strong>zu <strong>viel </strong>und und und.</p>



<p><strong>Manchmal fragt man sich </strong>wirklich, <strong>wie </strong>Diese herauskommenden <strong>Daten </strong>letztendlich <strong>zustande kommen</strong>.</p>



<p><strong>Ich selbst kenne </strong>das aufgrund einer ehemaligen Arbeitskollegin <strong>aus </strong>einen <strong>vergangenen Job </strong>sehr gut.</p>



<h3 class="wp-block-heading">Monkey Work als Beispiel – Kein Einzelfall</h3>



<p><strong>Sie war </strong>den <strong>ganzen Arbeitstag </strong>(!) damit <strong>beschäftigt</strong>, <strong>Adressen </strong>zu <strong>korrigieren </strong>und aufzuarbeiten – schrecklich.</p>



<p><strong>Leider </strong>ist das <strong>absolut</strong> <strong>kein Einzelfall</strong>, auch <strong>bei </strong>einem <strong>ehemaligen Kunden </strong>kannte ich <strong>Mitarbeiter</strong>, die dieser Arbeit nachkamen.</p>



<p><strong>Oftmals </strong>ist es <strong>in </strong>solchen <strong>Unternehmen </strong>leider die <strong>Folge von fehlendem Budget </strong>für individuelle Entwicklungen.</p>



<p><strong>Manchmal meint </strong>man auch, man <strong>könne </strong>sich dafür <strong>keine Zeit nehmen </strong>&#8222;..ich muss schließlich mein <strong>Tagesgeschäft fortführen</strong>..&#8220;.</p>



<p><strong>Fangen </strong>wir <strong>lieber nicht </strong>die <strong>mentale Debatte </strong>an, <strong>ob </strong>diese Vorgehensweisen <strong>so sinnvoll </strong>waren..</p>



<p><strong>Fokussieren </strong>wir uns <strong>stattdessen </strong>lieber <strong>auf </strong>das ursprüngliche <strong>Problem</strong>, eine <strong>kleine Funktionalität </strong>zur <strong>Korrektur von Adressen</strong> zu erstellen.</p>



<p><strong>Natürlich </strong>werde ich <strong>hier </strong>nur ein <strong>kleines Beispiel </strong>machen, <strong>da </strong>es <strong>nicht um </strong>die <strong>Funktionalität </strong>geht.</p>



<p><strong>Mir geht </strong>es hier <strong>besonders um </strong>das <strong>Verständnis über </strong>die <strong>Einsatzmöglichkeiten </strong>von <strong>VBA</strong>.</p>



<h3 class="wp-block-heading">Tabellenstruktur &amp; Beispieldaten</h3>



<p><strong>Schaue </strong>Dir am besten einfach mal <strong>folgende Tabellenstruktur und </strong>die darin befindlichen <strong>Daten </strong>an:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/08/VBA-Monkey-Work-Tabellenstruktur.png"><img loading="lazy" decoding="async" width="555" height="178" src="https://robbelroot.de/wp-content/uploads/2021/08/VBA-Monkey-Work-Tabellenstruktur.png" alt="VBA Monkey Work Tabellenstruktur" class="wp-image-5733" title="VBA Monkey Work Tabellenstruktur"/></a><figcaption>VBA Monkey Work Tabellenstruktur</figcaption></figure>



<p>Dir <strong>fällt </strong>sehr <strong>wahrscheinlich </strong>der <strong>falsche Datensatz </strong>in der dritten Zeile <strong>auf</strong>.</p>



<p><strong>Dort wurde </strong>bei der Eingabe (aus welcher Quelle auch immer), leider die <strong>Postleitzahl mit </strong>dem <strong>Ort vertauscht</strong>.</p>



<p><strong>Natürlich </strong>könnten wir <strong>bei </strong>diesen <strong>wenigen Einträgen</strong> <strong>auch </strong>eine <strong>manuelle Korrektur </strong>durchführen.</p>



<p><strong>Wenn </strong>ich allerdings <strong>an </strong>den <strong>erwähnten Kunden </strong>denke, dann <strong>hatte </strong>man <strong>mit </strong>ungefähr <strong>200 Bestellungen am Tag</strong> ein <strong>Problem</strong>.</p>



<h3 class="wp-block-heading">Lösungsansatz</h3>



<p><strong>Wenn </strong>wir <strong>nun </strong>über einen <strong>möglichen Lösungsansatz </strong>nachdenken, könnte man <strong>wie folgt </strong>vorgehen.</p>



<p><strong>Man geht </strong>das aktive <strong>Tabellenblatt bei </strong>z. B. einem <strong>Klick </strong>eines Buttons <strong>mit </strong>einer <strong>Schleife durch</strong>.</p>



<p>In <strong>jedem Schleifendurchlauf prüft </strong>man, <strong>ob </strong>z. B. <strong>im Ort Zahlen</strong> enthalten sind.</p>



<p><strong>Vermutlich </strong>gibt es <strong>hier noch andere Ansätze</strong>, allerdings <strong>reicht </strong>das für unser Beispiel <strong>aus</strong>.</p>



<p><strong>Meine Gedanken </strong>dabei waren, dass <strong>in einem Ort definitiv keine Zahlen</strong> vorkommen und <strong>eine Postleitzahl</strong> soweit ich weiß<strong> in einigen Gebieten</strong> <strong>auch Buchstaben </strong>enthalten kann.</p>



<p><strong>Im Endeffekt kann </strong>man das ja je nach individuellem Wunsch <strong>anpassen</strong>, bzw. <strong>verändern</strong>.</p>



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



<p>In <strong>diesem Abschnitt schauen </strong>wir uns den möglichen <strong>Code </strong>für die oben genannte Variante <strong>an</strong>.</p>



<p>Der <strong>erste Bestandteil </strong>ist wie erwähnt das <strong>Durchlaufen der Zeilen</strong>, des <strong>aktiven Tabellenblatts</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 rowRange As Range
For Each rowRange In ActiveSheet.UsedRange.Rows
  ' mach was mit der Range namens rowRange
Next</pre>



<p><strong>Danach könnten </strong>wir <strong>einstellen</strong>, dass die <strong>Reihe nur verarbeitet </strong>wird, <strong>wenn </strong>beide notwendigen <strong>Datenfelder ausgefüllt </strong>sind.</p>



<p><strong>Dazu benutze </strong>ich <strong>wie immer gerne</strong>, ein so genanntes &#8222;<strong>Early Return</strong>&#8222;, ich <strong>weise </strong>die <strong>Schleife </strong>in den <strong>nächsten Durchlauf</strong>, <strong>statt </strong>If-<strong>Konstrukte </strong>tief <strong>zu verschachteln</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 zipText As String
zipText = ActiveSheet.Cells(rowRange.Row, 1).Text
Dim hasNoZip As Boolean
hasNoZip = zipText = ""

Dim cityText As String
cityText = ActiveSheet.Cells(rowRange.Row, 2).Text
Dim hasNoCity As Boolean
hasNoCity = cityText = ""

If hasNoZip Or hasNoCity Then
  Continue For
End If</pre>



<p><strong>Zum Schluss </strong>können wir dann unsere <strong>Prüfung und </strong>die <strong>Tausch-Arbeit </strong>selbst durchführen.</p>



<p><strong>Dazu könnten </strong>wir <strong>auf komplizierte </strong>&#8222;<strong><a href="https://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck" target="_blank" rel="noreferrer noopener">Regular Expressions&#8220;</a></strong> zurückgreifen, <strong>jedoch </strong>bin ich ein <strong>Fan von </strong>&#8222;<strong><a href="https://de.wikipedia.org/wiki/KISS-Prinzip" target="_blank" rel="noreferrer noopener">KISS</a></strong>&#8222;, daher verwenden wir einfach den <strong><a href="https://docs.microsoft.com/de-de/office/vba/language/reference/user-interface-help/like-operator" target="_blank" rel="noreferrer noopener">&#8222;Like&#8220;-Operator</a></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 cityContainsNoNumber As Boolean
cityContainsNoNumber = cityText Not Like "*[0-9]*"
If cityContainsNoNumber Then
  ' wieder early return / Continue
  Continue For
End If</pre>



<p>Im <strong>letzten Schritt </strong>folgt der <strong>Tausch der Werte</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="">ActiveSheet.Cells(rowRange.Row, 1).Text = cityText
ActiveSheet.Cells(rowRange.Row, 2).Text = zipText</pre>



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



<p><strong>Hier </strong>findest Du noch einmal den <strong>vollständigen Code</strong>, <strong>um </strong>die <strong>PLZ mit </strong>dem <strong>Ort</strong>/der Stadt zu <strong>tauschen</strong>, <strong>wenn </strong>die <strong>Stadt </strong>eine <strong>Zahl enthält</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 rowRange As Range
For Each rowRange In ActiveSheet.UsedRange.Rows
  Dim zipText As String
  zipText = ActiveSheet.Cells(rowRange.Row, 1).Text
  Dim hasNoZip As Boolean
  hasNoZip = zipText = ""

  Dim cityText As String
  cityText = ActiveSheet.Cells(rowRange.Row, 2).Text
  Dim hasNoCity As Boolean
  hasNoCity = cityText = ""

  If hasNoZip Or hasNoCity Then
    Continue For
  End If

  Dim cityContainsNoNumber As Boolean
  cityContainsNoNumber = cityText Not Like "*[0-9]*"
  If cityContainsNoNumber Then
    Continue For
  End If

  ActiveSheet.Cells(rowRange.Row, 1).Text = cityText
  ActiveSheet.Cells(rowRange.Row, 2).Text = zipText
Next</pre>



<h2 class="wp-block-heading">Wo den Code unterbringen?</h2>



<p><strong>Damit </strong>Du den <strong>Code </strong>von oben verwenden kannst, muss er natürlich <strong>irgendwo untergebracht </strong>werden, <strong>damit </strong>er auch <strong>ausgeführt </strong>wird.</p>



<p>Das <strong>passiert </strong>in Excel z. B. <strong>häufig durch </strong>sogenannte <strong>Makros</strong>, wie Du auch in <strong>diesen Beiträgen </strong>erfahren konntest: <strong><a href="https://robbelroot.de/blog/excel-makro-erstellen/" target="_blank" rel="noreferrer noopener">Excel Makros erstellen</a></strong>, oder <strong><a href="https://robbelroot.de/blog/excel-makro-button/" target="_blank" rel="noreferrer noopener">Excel Makro Button</a></strong>.</p>



<h2 class="wp-block-heading">Fazit – VBA</h2>



<p>In <strong>diesem Beitrag </strong>hast Du <strong>gelernt</strong>, <strong>wie </strong>Du dein <strong>Erlebnis von Office Produkten </strong>wie z. B. <strong>Excel verbessern </strong>kannst.</p>



<p>Dies <strong>geschieht durch </strong>die <strong>auf </strong>der <strong>Visual Basic</strong> (Classic) <strong>basierenden Skriptsprache namens </strong>Visual Basic for Applications, oder <strong>kurz </strong>&#8222;<strong>VBA</strong>&#8222;.</p>



<p><strong>Diese Verbesserungen</strong> können <strong>in Form von </strong>zusätzlichen <strong>Funktionen</strong>, <strong>oder auch </strong>in Form von <strong>konkreten </strong>arbeitserleichternden <strong>Mitteln existieren</strong>.</p>



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



<div class="wp-block-file"><a href="https://robbelroot.de/wp-content/uploads/2021/08/VBA-Monkey-Work-Beispiel.xlsx">VBA-Monkey-Work-Beispiel</a><a href="https://robbelroot.de/wp-content/uploads/2021/08/VBA-Monkey-Work-Beispiel.xlsx" class="wp-block-file__button" download>Herunterladen</a></div>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vba/">VBA</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vba/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>VB.NET Anwendungsdauer auslesen</title>
		<link>https://robbelroot.de/blog/vbnet-anwendungsdauer-auslesen/</link>
					<comments>https://robbelroot.de/blog/vbnet-anwendungsdauer-auslesen/#respond</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Sat, 14 Aug 2021 01:04:48 +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[.net]]></category>
		<category><![CDATA[anwendungsdauer]]></category>
		<category><![CDATA[auslesen]]></category>
		<category><![CDATA[basic]]></category>
		<category><![CDATA[dauer]]></category>
		<category><![CDATA[dotnet]]></category>
		<category><![CDATA[duration]]></category>
		<category><![CDATA[feststellen]]></category>
		<category><![CDATA[länge]]></category>
		<category><![CDATA[laufzeit]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[runtime]]></category>
		<category><![CDATA[start]]></category>
		<category><![CDATA[starttime]]></category>
		<category><![CDATA[startzeit]]></category>
		<category><![CDATA[startzeitpunkt]]></category>
		<category><![CDATA[time]]></category>
		<category><![CDATA[vb]]></category>
		<category><![CDATA[vb.net]]></category>
		<category><![CDATA[visual]]></category>
		<category><![CDATA[visual basic]]></category>
		<category><![CDATA[zeit]]></category>
		<category><![CDATA[zeitpunkt]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=5408</guid>

					<description><![CDATA[<p>VB.NET Anwendungsdauer auslesen In VB.NET die Anwendungsdauer auslesen ist ein Problem, vor Welchem ich heute selbst stand, daher dachte ich, ich teile meine Lösung mit Dir. Je nach Sicherheitsanforderungen deiner Anwendung, könntest Du basierend auf dieser Zeitmessung zum Beispiel Nutzungsbegrenzungen festlegen. Beachte, dass es wie fast immer unterschiedliche Wege gibt, &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-anwendungsdauer-auslesen/">VB.NET Anwendungsdauer auslesen</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/08/VB.NET-Anwendungsdauer-auslesen.png"><img loading="lazy" decoding="async" width="1200" height="628" src="https://robbelroot.de/wp-content/uploads/2021/08/VB.NET-Anwendungsdauer-auslesen.png" alt="VB.NET Anwendungsdauer auslesen" class="wp-image-5412" title="VB.NET Anwendungsdauer auslesen"/></a><figcaption>VB.NET Anwendungsdauer auslesen</figcaption></figure>






<h2 class="wp-block-heading">VB.NET Anwendungsdauer auslesen</h2>



<p>In <strong>VB.NET die Anwendungsdauer auslesen</strong> ist ein Problem, vor Welchem ich heute selbst stand, daher <strong>dachte ich</strong>, ich <strong>teile </strong>meine <strong>Lösung </strong>mit Dir.</p>



<p><strong>Je nach Sicherheitsanforderungen </strong>deiner Anwendung, <strong>könntest </strong>Du basierend auf dieser <strong>Zeitmessung </strong>zum Beispiel <strong>Nutzungsbegrenzungen </strong>festlegen.</p>



<p><strong>Beachte</strong>, dass es wie fast immer <strong>unterschiedliche Wege </strong>gibt, diese <strong>Problemstellung </strong>anzugehen und ich nur <strong>eine Möglichkeit </strong>zeige.</p>



<p>Schaue doch zu einem <strong>anderen Zeitpunkt </strong>auch gerne bei <strong>diesen Beiträgen </strong>vorbei: <strong><a href="https://robbelroot.de/blog/vbnet-data-binding-tutorial/" target="_blank" rel="noreferrer noopener">VB.NET data bind</a></strong><a href="https://robbelroot.de/blog/vbnet-data-binding-tutorial/" target="_blank" rel="noreferrer noopener"><strong>ing Tutorial</strong></a>, <strong><a href="https://robbelroot.de/blog/vbnet-game-dein-eigenes-tictactoe-spiel/" target="_blank" rel="noreferrer noopener">Dein Eigenes TicTacToe Spiel</a></strong>, <strong><a href="https://robbelroot.de/blog/vbnet-array/" target="_blank" rel="noreferrer noopener">VB.NET Array</a></strong>.</p>



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



<h2 class="wp-block-heading">Meine erste Problemstellung – wo?</h2>



<p>Der <strong>erste Gedanke, Welcher</strong> mich <strong>beim Umsetzen </strong>dieser <strong>Aufgabe </strong>begleitete war es, <strong>herauszufinden wo </strong>ich den <strong>Code </strong>am besten <strong>ansetze</strong>.</p>



<p><strong>Am liebsten </strong>hätte ich es wie gleich folgend gehabt, um <strong>nicht </strong>großartig etwas <strong>instanziieren und </strong>durch z. B. eine Methode <strong>initialisieren </strong>zu <strong>müssen</strong>.</p>



<p><strong>Ebenso finde</strong> ich das Beispiel <strong>relativ einleuchtend</strong>, denn es <strong>klingt </strong>für mich <strong>logisch</strong>, die <strong>verstrichene Zeit </strong>der Anwendung, <strong>in </strong>der <strong>Anwendungsklasse </strong>zu <strong>finden</strong>, oder?</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 timeRunning = Application.GetTimeRunning()
' do something</pre>



<h2 class="wp-block-heading">Erweiterungsmethoden zu Hilfe – oder?</h2>



<p><strong>Grundsätzlich </strong>könnte man bei dieser Herangehensweise erstmal <strong>an Erweiterungsmethoden denken</strong>.</p>



<p>Mit Hilfe von <strong>Erweiterungsmethoden können </strong>wir die <strong>bestehenden </strong>.NET-Klassen, sowie eigene <strong>Klassen </strong>um Funktionalitäten <strong>erweitern</strong>.</p>



<p>Das <strong>würde sich </strong>für mich dann <strong>nach </strong>so etwas wie &#8222;<strong>Plug &amp; Play</strong>&#8220; <strong>anfühlen</strong>, also <strong>hinzufügen und </strong>&#8222;zack&#8220;, <strong>läuft</strong>!</p>



<h3 class="wp-block-heading">Winforms Anlauf – VB.NET Anwendungsdauer auslesen</h3>



<p>Mein <strong>erster Versuch,</strong> bzw. der <strong>erste Pseudocode </strong>(für Winforms) sah also so ähnlich 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="">Imports System.Runtime.CompilerServices

Module modExtensions

    Private ReadOnly StartedAt As Date = Date.Now

    &lt;Extension>
    Public Function GetTimeRunning(app As Application) As TimeSpan
        Dim timeDiff = Date.Now - StartedAt
        Return timeDiff
    End Function

End Module</pre>



<h4 class="wp-block-heading">Klappt leider direkt nicht</h4>



<p><strong>Leider </strong>können wir <strong>Klassen </strong>mit Hilfe von <strong>Erweiterungsmethoden keine statischen </strong>(shared) <strong>Methoden </strong>hinzufügen.</p>



<p>Das <strong>obige </strong>Code-<strong>Beispiel </strong>würde <strong>daher </strong>die <strong>Klasse </strong>&#8222;<a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.application?view=net-5.0" target="_blank" rel="noreferrer noopener">Application</a>&#8220; <strong>um </strong>den jeweiligen <strong>Code erweitern</strong>.</p>



<p><strong>Allerdings </strong>kann man die <strong>Methode </strong>wie erklärt dann <strong>nur auf </strong>einer <strong>Instanz </strong>der &#8222;Application&#8220;-Klasse <strong>aufrufen</strong>.</p>



<p>&#8222;<strong>Shared</strong>&#8222;-<strong>Methoden </strong>sind <strong>in Modulen </strong>übrigens <strong>nicht verwendbar</strong>, also nicht gültig.</p>



<h3 class="wp-block-heading">Eins der Probleme bei WPF gelöst</h3>



<p><strong>Mit WPF </strong>können wir <strong>eines der Probleme</strong> <strong>einfach lösen</strong>, denn <strong>WPF </strong>kann <strong>auf </strong>die <strong>aktuelle Instanz </strong>der Anwendung <strong>zugreifen</strong>.</p>



<p><strong>Beherbergt </strong>in der &#8222;<a href="https://docs.microsoft.com/de-de/dotnet/api/system.windows.application.current?view=net-5.0" target="_blank" rel="noreferrer noopener"><strong>Application</strong></a>&#8222;-Klasse <strong>aus </strong>einem <strong>anderen Namespace</strong>, können wir nun auf die <strong>aktuelle Instanz </strong>der Anwendung <strong>zugreifen</strong>.</p>



<p><strong>Somit </strong>haben wir <strong>jetzt</strong> die <strong>Möglichkeit</strong>, die deklarierte <strong>Erweiterungsmethode </strong>zu <strong>verwenden</strong>.</p>



<h2 class="wp-block-heading">Die Erweiterungsmethode erklärt</h2>



<p>Hier <strong>erkläre </strong>ich Dir kurz die <strong>Vorgehensweise </strong>der <strong>Erweiterungsmethode </strong>und <strong>zeige </strong>Dir das <strong>erste Ergebnis</strong>.</p>



<h3 class="wp-block-heading">Vorgehensweise – VB.NET Anwendungsdauer auslesen</h3>



<p>Dort siehst Du <strong>ein </strong>beliebig benanntes <strong>Modul</strong>, Welches ein <strong>privates</strong> <strong>Feld </strong>namens &#8222;<strong>StartedAt</strong>&#8220; besitzt.</p>



<p>Dieses <strong>Feld sollte </strong>die <strong>aktuelle Zeit zum Anwendungsstart </strong>widerspiegeln – sollte, aber dazu gleich mehr.</p>



<p>Die &#8222;GetTimeRunning&#8220;-Funktion führt eine <strong>simple Subtraktion von 2 <a href="https://docs.microsoft.com/de-de/dotnet/api/system.datetime?view=net-5.0" target="_blank" rel="noreferrer noopener">Date</a></strong> (DateTime) <strong>Objekten </strong>durch.</p>



<p><strong>Dabei </strong>wird die <strong>Startzeit von </strong>der <strong>aktuellen Zeit abgezogen</strong>, Welche dann die <strong>verstrichene Zeit </strong>darstellt.</p>



<p>Die <strong>Subtraktion </strong>der <strong>Dates </strong>ist von .NET <strong>schon implementiert </strong>und gibt <strong>als Ergebnis </strong>ein <strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.timespan?view=net-5.0" target="_blank" rel="noreferrer noopener">TimeSpan</a></strong>-Objekt aus.</p>



<h3 class="wp-block-heading">Das erste Ergebnis</h3>



<p>Schaue Dir im <strong>folgenden Bild </strong>unser <strong>erstes Ergebnis </strong>der aktuellen Herangehensweise an.</p>



<p><strong>Dabei </strong>habe ich mir den <strong>Rückgabewert </strong>der Funktion einfach <strong>2x mit Verzögerung</strong> <strong>als String</strong> ausgeben lassen.</p>



<p>Das habe ich ganz <strong>simpel </strong>mit der &#8222;<strong>WriteLine&#8220;-</strong>Methode der <strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.diagnostics.debug?view=net-5.0" target="_blank" rel="noreferrer noopener">Debug</a></strong>-Klasse, <strong>innerhalb </strong>eines <strong>Button</strong>&#8211;<strong>Klicks </strong>umgesetzt.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/08/Ausgabe-Anwendungsdauer-mit-Erweiterungsmethode-falsch.png"><img loading="lazy" decoding="async" width="518" height="210" src="https://robbelroot.de/wp-content/uploads/2021/08/Ausgabe-Anwendungsdauer-mit-Erweiterungsmethode-falsch.png" alt="Ausgabe Anwendungsdauer mit Erweiterungsmethode falsch" class="wp-image-5428" title="Ausgabe Anwendungsdauer mit Erweiterungsmethode falsch"/></a><figcaption>Ausgabe Anwendungsdauer mit Erweiterungsmethode falsch</figcaption></figure>



<h3 class="wp-block-heading">Bittere Enttäuschung</h3>



<p><strong>Wie </strong>die <strong>Überschrift </strong>schon <strong>vermuten lässt</strong>, kommen wir mit diesem Beispiel leider <strong>nicht</strong> <strong>an </strong>unser gewünschtes <strong>Ziel</strong>.</p>



<p><strong>Erklären </strong>lässt sich das zwar <strong>korrekte </strong>aber <strong>nicht funktionierende Beispiel, mit </strong>Hilfe der dahinter liegenden <strong>Ausführungslogik </strong>von .NET.</p>



<p><strong>Obwohl </strong>ich schon <strong>vor dem ersten Klick </strong>ein wenig <strong>gewartet hatte</strong>, bekomme ich <strong>trotzdem </strong>einen <strong>komischen Wert</strong>.</p>



<p>Das <strong>liegt daran</strong>, <strong>dass </strong>das &#8222;StartedAt&#8220;-<strong>Feld </strong>des Moduls <strong>erst nach erstmaliger Verwendung </strong>des Moduls <strong>während </strong>der <strong>Laufzeit initialisiert </strong>wird.</p>



<p><strong>Nach </strong>ca. <strong>3 weiteren Sekunden</strong> habe ich dann <strong>erneut auf </strong>den <strong>Button geklickt </strong>und siehe da, ein besseres Ergebnis.</p>



<p>Zu <strong>diesem Zeitpunkt </strong>war das <strong>Feld</strong> bereits <strong>initialisiert </strong>und hatte somit <strong>einen </strong>&#8222;<strong>korrekten</strong>&#8220; Wert.</p>



<h3 class="wp-block-heading">Negativer Wert</h3>



<p><strong>Wie </strong>das <strong>Feld </strong>im <strong>ersten Schritt </strong>einen <strong>negativen Wert </strong>generieren konnte <strong>verstehe </strong>ich allerdings <strong>selbst nicht </strong>so <strong>ganz</strong>.</p>



<p><strong>Auch wenn </strong>ich einige <strong>Vermutungen </strong>im <strong>Bereich <a href="https://docs.microsoft.com/de-de/dotnet/api/system.datetime.minvalue?view=net-5.0" target="_blank" rel="noreferrer noopener">DateTime-MinValue</a></strong> aufstelle, dürften sich <strong>Diese </strong>eigentlich <strong>nicht bewahrheiten</strong>.</p>



<p><strong>Denn bevor </strong>ich <strong>auf </strong>das <strong>Feld zugreife</strong>, müsste Ihm ja <strong>trotzdem bereits </strong>der auf Modul-Ebene &#8222;Date.Now&#8220; <strong>Wert zugewiesen </strong>sein.</p>



<h3 class="wp-block-heading">Fokus auf das Wesentliche</h3>



<p><strong>Halten </strong>wir uns aber <strong>nicht weiter </strong>damit <strong>auf </strong>und <strong>fokussieren </strong>uns <strong>auf </strong>das <strong>Wesentliche</strong>.</p>



<p>Das <strong>eigentliche Problem mit </strong>der hier <strong>aufgeführten Möglichkeit </strong>ist, dass der <strong>Wert </strong>erst <strong>nach </strong>der <strong>ersten Verwendung </strong>zustande kommt.</p>



<p><strong>Einen </strong>möglichen <strong>Workaround </strong>um das <strong>zweite </strong>geschilderte <strong>Problem</strong>, finden wir mit Hilfe der &#8222;<strong><a href="https://docs.microsoft.com/de-de/dotnet/api/system.diagnostics.process?view=net-5.0" target="_blank" rel="noreferrer noopener">Process</a></strong>&#8222;-Klasse.</p>



<p>Dort <strong>speichert </strong>die nützliche <strong>Eigenschaft </strong>&#8222;<strong>StartTime</strong>&#8222;, den <strong>Startzeitpunkt </strong>der <strong>App </strong>in der aktuellen Prozess-Instanz.</p>



<p>Der <strong>Code </strong>um <strong>an </strong>die &#8222;<strong>StartTime</strong>&#8220; <strong>des </strong>momentanen <strong>Prozesses </strong>zu kommen, sieht <strong>so </strong>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="">Dim processStartTime = Process.GetCurrentProcess().StartTime</pre>



<h3 class="wp-block-heading">Erweiterungsmethode V2</h3>



<p>Wir <strong>schreiben </strong>unsere <strong>Erweiterungsmethode </strong>aus dem obigen Code-Snippet <strong>also </strong>wie folgt <strong>um</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.CompilerServices

Module modExtensions

    &lt;Extension>
    Public Function GetTimeRunning(app As Application) As TimeSpan
        Dim timeDiff = Date.Now - Process.GetCurrentProcess().StartTime
        Return timeDiff
    End Function

End Module</pre>



<p>Dabei <strong>entfernen </strong>wir das <strong>Feld </strong>&#8222;<strong>StartedAt</strong>&#8220; und <strong>ersetzen </strong>dessen <strong>Verwendung</strong> <strong>durch </strong>die hier drüber vorgestellte &#8222;<strong>StartTime</strong>&#8222;-<strong>Eigenschaft </strong>der &#8222;Process&#8220;-Klasse.</p>



<pre class="wp-block-verse"><strong>Achtung!</strong> <strong>Bei </strong>meiner <strong>Recherche </strong>bin ich <strong>auf </strong>diverse <strong>Probleme </strong>gestoßen, <strong>wenn </strong>man den <strong>Code im Debugging </strong>verwendete. <strong>Durch </strong>die <strong>gehostete Exe</strong>, ist der <strong>Prozess eventuell </strong>schon <strong>länger aktiv</strong>. <strong>Wenn </strong>man die <strong>Exe </strong>allerdings <strong>ohne Debugging </strong>startet (Strg+F5), <strong>klappt </strong>alles.</pre>



<h3 class="wp-block-heading">WPF läuft nun</h3>



<p>In einer <strong>WPF-Umgebung</strong> <strong>läuft </strong>der Code <strong>mit </strong>der <strong>Erweiterungsmethode </strong>ohne Probleme.</p>



<p>Die <strong>WPF-Anwendung</strong> selbst, <strong>findest </strong>Du natürlich auch <strong>in </strong>der <strong>Projektmappe </strong>des <strong>Downloads</strong>.</p>



<p>Nachdem ich die <strong>Anwendung starte </strong>und gefühlt <strong>3 Sekunden warte</strong>, bekomme ich <strong>folgende Ausgabe</strong>:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/08/Ausgabe-Anwendungsdauer-in-WPF-mit-Erweiterungsmethode.png"><img loading="lazy" decoding="async" width="474" height="183" src="https://robbelroot.de/wp-content/uploads/2021/08/Ausgabe-Anwendungsdauer-in-WPF-mit-Erweiterungsmethode.png" alt="Ausgabe Anwendungsdauer in WPF mit Erweiterungsmethode" class="wp-image-5453" title="Ausgabe Anwendungsdauer in WPF mit Erweiterungsmethode"/></a><figcaption>Ausgabe Anwendungsdauer in WPF mit Erweiterungsmethode</figcaption></figure>



<h2 class="wp-block-heading">Winforms-Fix – VB.NET Anwendungsdauer auslesen</h2>



<p><strong>Nun </strong>bringen wir das Ganze <strong>Snippet auch in </strong>ähnlicher Form in <strong>Winforms</strong>-Awendungen zum <strong>Laufen</strong>.</p>



<p><strong>Dazu </strong>lege ich <strong>einfach </strong>auch ein <strong>Modul</strong> an, <strong>Welches </strong>dann <strong>geschachtelte Klassen mit </strong>der <strong>Funktionalität </strong>enthält.</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="">Module modExtensions

    Public Class Extensions

        Public Class Application

            Public Shared Function GetTimeRunning() As TimeSpan
                Dim timeDiff = Date.Now - Process.GetCurrentProcess().StartTime
                Return timeDiff
            End Function

        End Class

    End Class

End Module</pre>



<p>Dessen <strong>Aufruf </strong>in einer <strong>Windows-Form</strong>, bzw. in einem Button Klick-Ereignishandler sieht dann<strong> ähnlich</strong> <strong>einfach </strong>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 Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Debug.WriteLine(Extensions.Application.Runtime())
    End Sub</pre>



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



<ul class="wp-block-list"><li><strong><a href="https://robbelroot.de/blog/vbnet-texterkennung-auf-bildern/" target="_blank" rel="noreferrer noopener">VB.NET Texterkennung auf Bildern via Google Cloud Vision API [OCR]</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 – Währungskurs Service Konsum von Grund auf erklärt</a></strong></li><li><strong><a href="https://robbelroot.de/blog/vb-net-imagesearch-bilder-in-spielen-desktop-und-co-suchen/" target="_blank" rel="noreferrer noopener">VB NET ImageSearch – Bilder in Spielen, Desktop und Co. suchen</a></strong></li></ul>



<h2 class="wp-block-heading">Downloads – VB.NET Anwendungsdauer auslesen</h2>



<p>Der Download <strong>enthält </strong>die <strong>Projektmappe</strong> für das &#8222;VB.NET Anwendungsdauer auslesen&#8220;-Projekt, bestehend aus dem <strong>Winforms</strong>&#8211; <strong>und </strong>dem <strong>WPF-Projekt</strong>.</p>



<pre class="wp-block-verse"><strong>Das </strong>richtige <strong>Startprojekt beim Ausprobieren </strong>des Codes <strong>kannst </strong>Du <strong>mit </strong>einem <strong>Rechtsklick </strong>auf das Projekt + "Als Startprojekt festlegen" <strong>ändern</strong>.</pre>



<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/ShowRunningTimeExample.zip" target="_blank" rel="noreferrer noopener">ShowRunningTimeExample.zip</a></div>
</div>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-anwendungsdauer-auslesen/">VB.NET Anwendungsdauer auslesen</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vbnet-anwendungsdauer-auslesen/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Excel Makro erstellen</title>
		<link>https://robbelroot.de/blog/excel-makro-erstellen/</link>
					<comments>https://robbelroot.de/blog/excel-makro-erstellen/#comments</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Mon, 09 Aug 2021 23:32:56 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Visual Basic for Applications]]></category>
		<category><![CDATA[Visual Basic for Applications Problemlösungen]]></category>
		<category><![CDATA[applications]]></category>
		<category><![CDATA[aufzeichnen]]></category>
		<category><![CDATA[basic]]></category>
		<category><![CDATA[cell]]></category>
		<category><![CDATA[column]]></category>
		<category><![CDATA[create]]></category>
		<category><![CDATA[erstellen]]></category>
		<category><![CDATA[for]]></category>
		<category><![CDATA[kalkulation]]></category>
		<category><![CDATA[macro]]></category>
		<category><![CDATA[makro]]></category>
		<category><![CDATA[neu]]></category>
		<category><![CDATA[new]]></category>
		<category><![CDATA[record]]></category>
		<category><![CDATA[recording]]></category>
		<category><![CDATA[row]]></category>
		<category><![CDATA[spalte]]></category>
		<category><![CDATA[tabelle]]></category>
		<category><![CDATA[table]]></category>
		<category><![CDATA[vb]]></category>
		<category><![CDATA[vba]]></category>
		<category><![CDATA[visual]]></category>
		<category><![CDATA[visual basic for applications]]></category>
		<category><![CDATA[xls]]></category>
		<category><![CDATA[xlsm]]></category>
		<category><![CDATA[zeile]]></category>
		<category><![CDATA[zelle]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=5200</guid>

					<description><![CDATA[<p>Excel Makro erstellen Ein Excel Makro erstellen und damit eventuell deine Arbeit zu erleichtern, bzw. zu automatisieren ist Dein Ziel? Dann ist es schön, dass Du auf dem Weg deiner Recherche zu meinem heutigen Beitrag gefunden hast, denn genau darum geht es heute! Schaue gerne alternativ auch bei meinen anderen &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/excel-makro-erstellen/">Excel Makro erstellen</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/08/Excel-Makro-erstellen.png"><img loading="lazy" decoding="async" width="1024" height="536" src="https://robbelroot.de/wp-content/uploads/2021/08/Excel-Makro-erstellen-1024x536.png" alt="Excel Makro erstellen" class="wp-image-5202" title="Excel Makro erstellen" srcset="https://robbelroot.de/wp-content/uploads/2021/08/Excel-Makro-erstellen-1024x536.png 1024w, https://robbelroot.de/wp-content/uploads/2021/08/Excel-Makro-erstellen-300x157.png 300w, https://robbelroot.de/wp-content/uploads/2021/08/Excel-Makro-erstellen-768x402.png 768w, https://robbelroot.de/wp-content/uploads/2021/08/Excel-Makro-erstellen-700x366.png 700w, https://robbelroot.de/wp-content/uploads/2021/08/Excel-Makro-erstellen-332x174.png 332w, https://robbelroot.de/wp-content/uploads/2021/08/Excel-Makro-erstellen.png 1200w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a><figcaption>Excel Makro erstellen</figcaption></figure>






<h2 class="wp-block-heading">Excel Makro erstellen</h2>



<p>Ein <strong>Excel Makro erstellen</strong> <strong>und </strong>damit eventuell deine <strong>Arbeit</strong> zu <strong>erleichtern</strong>, bzw. zu <strong>automatisieren </strong>ist Dein <strong>Ziel</strong>?</p>



<p><strong>Dann </strong>ist es schön, dass Du auf dem Weg <strong>deiner Recherche</strong> zu meinem <strong>heutigen Beitrag </strong>gefunden hast, denn genau darum <strong>geht es </strong>heute!</p>



<p><strong>Schaue </strong>gerne <strong>alternativ </strong>auch bei meinen anderen <strong>VBA </strong>Excel <strong>Beiträgen </strong>wie: <strong><a href="https://robbelroot.de/blog/excel-makro-button/" target="_blank" rel="noreferrer noopener">Excel Makro Button</a></strong>, <strong><a href="https://robbelroot.de/blog/vba-for-schleife/" target="_blank" rel="noreferrer noopener">VBA For Schleife</a></strong> &amp; <strong><a href="https://robbelroot.de/blog/vba-range/" target="_blank" rel="noreferrer noopener">Range VBA</a></strong> vorbei.</p>



<h2 class="wp-block-heading">Was ist eigentlich ein Makro?</h2>



<p><strong>Ganz nach </strong>dem Motto &#8222;<strong>Back To The Roots</strong>&#8220; schauen wir uns erstmal die <strong>Bedeutung eines Makros </strong>an und <strong>wofür </strong>man es letztendlich <strong>verwendet</strong>.</p>



<p><strong>Makros </strong>sind <strong>vor allem </strong>im Bereich der <strong>Automatisierung </strong>von diversen <strong>Prozessen </strong>nicht wegzudenken, denn Sie <strong>können </strong>die <strong>alltägliche Arbeit </strong>erleichtern.</p>



<p>Sie sind <strong>für </strong>die <strong>Non-Programmierer</strong> vor allem aus dem Bereich <strong>Microsoft Excel und Co</strong>. bekannt und werden dort täglich eingesetzt.</p>



<p>Ein <strong>Makro </strong>ist letztendlich nichts Anderes als eine <strong>Sammlung von Anweisungen</strong>, praktisch also <strong>ein Zettel mit</strong> &#8222;Tu dies, tu jenes und danach dies &amp; das&#8220;.</p>



<h2 class="wp-block-heading">Ein Makro auslösen</h2>



<p><strong>Bevor </strong>wir uns der <strong>Erstellung </strong>des <strong>Makros </strong>widmen, <strong>schauen </strong>wir uns <strong>nochmal kurz </strong>vorher die <strong>Möglichkeiten zur Auslösung </strong>von Makros an.</p>



<p>Dazu können wir auf eher <strong>passive Ereignisse</strong>, bzw. Trigger warten, <strong>oder </strong>die <strong>aktive</strong> Varianten wie z. B. durch einen <strong>Button</strong>&#8211;<strong>Klick</strong>, oder <strong>Hotkey </strong>wählen.:</p>



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



<ul class="wp-block-list"><li>auslösen durch <strong>Hotkeys</strong></li><li>im <strong>Ladevorgang </strong>der <strong>Projektmappe</strong></li><li>im <strong>Code </strong>durch den Visual Basic Editor (<strong>VBE</strong>)</li><li>und <strong>mehr</strong>..</li></ul>



<p>Mit diesen <strong>Ausgangspunkten </strong>können wir uns nun <strong>im nächsten Schritt</strong>, die <strong>Erstellung </strong>eines Makros <strong>anschauen</strong>.</p>



<h2 class="wp-block-heading">Vorbereitungen – Excel Makro erstellen</h2>



<p><strong>Oft </strong>bekommt man <strong>bei </strong>der <strong>ersten Arbeit </strong>mit Makros ein <strong>kleines </strong>&#8222;<strong>Problem</strong>&#8222;, Welches aber gar kein richtiges Problem, sondern eher ein <strong>Sicherheitsfeature </strong>ist.</p>



<p><strong>Zumeist </strong>ist die <strong>Verwendung</strong> <strong>von Makros </strong>in Microsoft Excel Tabellen <strong>standardmäßig </strong>mehr oder weniger <strong>deaktiviert</strong>.</p>



<p>Wir <strong>müssen </strong>die mögliche <strong>Nutzung von Makros </strong>also erstmal aktivieren und das machen wir <strong>über die Optionen</strong>.</p>



<h3 class="wp-block-heading">Makros aktivieren</h3>



<p><strong>Begebe </strong>Dich also <strong>nun </strong>unter den Punkt <strong>Datei->Optionen</strong> in die <strong>Optionen von Excel</strong>.</p>



<pre class="wp-block-verse"><strong>Achtung!</strong> Deine Optionen <strong>sehen eventuell anders aus</strong>, bei mir werden durch die <strong>Verwendung </strong>von <strong>Web-Office</strong> aktuell nur <strong>diese Optionen</strong> angezeigt.</pre>



<h4 class="wp-block-heading">Excel Optionen öffnen </h4>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Optionen-oeffnen.png"><img loading="lazy" decoding="async" width="657" height="426" src="https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Optionen-oeffnen.png" alt="Microsoft Excel Optionen öffnen" class="wp-image-5217" title="Microsoft Excel Optionen öffnen" srcset="https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Optionen-oeffnen.png 657w, https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Optionen-oeffnen-300x195.png 300w, https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Optionen-oeffnen-332x215.png 332w" sizes="auto, (max-width: 657px) 100vw, 657px" /></a><figcaption>Microsoft Excel Optionen öffnen</figcaption></figure>



<h4 class="wp-block-heading">Trust-Center &amp; Einstellungen öffnen</h4>



<p>Gehe anschließend auf den Punkt &#8222;Trust-Center&#8220;, oder manchmal auch &#8222;Sicherheitseinstellungen&#8220; genannt.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Trust-Center-Einstellungen.png"><img loading="lazy" decoding="async" width="694" height="290" src="https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Trust-Center-Einstellungen.png" alt="Microsoft Excel Trust Center Einstellungen" class="wp-image-5220" title="Microsoft Excel Trust Center Einstellungen" srcset="https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Trust-Center-Einstellungen.png 694w, https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Trust-Center-Einstellungen-300x125.png 300w, https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Trust-Center-Einstellungen-332x139.png 332w" sizes="auto, (max-width: 694px) 100vw, 694px" /></a><figcaption>Microsoft Excel Trust Center Einstellungen</figcaption></figure>



<h4 class="wp-block-heading">Makroeinstellungen öffnen</h4>



<p>Klicke auf den farblich markierten Button und <strong>öffne </strong>somit die <strong>Einstellungen des Trust-Centers</strong>.</p>



<pre class="wp-block-verse"><strong>Beachte </strong>natürlich die <strong>Hinweise </strong>hinter den einzelnen Optionen und <strong>öffne nur </strong>Dateien, dessen <strong>Absender </strong>Du <strong>kennst</strong>, bzw. <strong>vertraust</strong>!</pre>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Makroeinstellungen.png"><img loading="lazy" decoding="async" width="781" height="297" src="https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Makroeinstellungen.png" alt="Microsoft Excel Makroeinstellungen" class="wp-image-5221" title="Microsoft Excel Makroeinstellungen" srcset="https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Makroeinstellungen.png 781w, https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Makroeinstellungen-300x114.png 300w, https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Makroeinstellungen-768x292.png 768w, https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Makroeinstellungen-700x266.png 700w, https://robbelroot.de/wp-content/uploads/2021/08/Microsoft-Excel-Makroeinstellungen-332x126.png 332w" sizes="auto, (max-width: 781px) 100vw, 781px" /></a><figcaption>Microsoft Excel Makroeinstellungen</figcaption></figure>



<p><strong>Alternativ </strong>kannst Du zur gezeigten Methode auch für <strong>jede Mappe</strong> <strong>einzeln </strong>bestimmen, <strong>ob </strong>Du dessen <strong>Makros verwenden </strong>möchtest.</p>



<p>Diese Möglichkeit bietet Dir <strong>Excel eigentlich </strong>auch von <strong>selbst </strong>an, <strong>meist mit </strong>einem kleinen <strong>Popup</strong>.</p>



<p>Allerdings kann die bei <strong>häufiger Verwendung </strong>von Makros auch <strong>nervig </strong>werden, <strong>jedoch </strong>ist es die <strong>sicherere Variante</strong>.</p>



<h3 class="wp-block-heading">Entwicklertools einbinden</h3>



<p>Mit dem <strong>nächsten Schritt</strong> würde ich Dir auch gleichzeitig ans Herz legen, die <strong>Entwicklertools </strong>in dein <strong>Menüband </strong>von Excel <strong>einzubinden</strong>.</p>



<p>Auch hier erschaffst Du Dir so einen <strong>schnellen </strong>und <strong>einfachen Zugriff </strong>auf die eventuell <strong>notwendigen Tools</strong>.</p>



<p><strong>Öffne </strong>auch hierzu wieder die <strong>Optionen </strong>von Excel und klicke links außen auf &#8222;<strong>Menüband anpassen</strong>&#8222;.</p>



<p><strong>Danach </strong>kannst Du die <strong>Entwicklertools </strong>meist <strong>mit </strong>einer <strong>Checkbox </strong>auf der <strong>rechten Seite</strong> aktivieren.</p>



<h2 class="wp-block-heading">Excel Makro erstellen – Die Praxis</h2>



<p><strong>Nachdem </strong>Du im letzten Schritt eventuell die <strong>Entwicklertools aktivierst </strong>hast, <strong>oder </strong>bereits <strong>aktiviert hattest</strong>, nutzen wir Diese auch gleich.</p>



<p><strong>Klicke </strong>dafür in deinem <strong>Menüband </strong>auf die <strong>Entwicklertools </strong>und <strong>anschließend </strong>auf die Fläche namens <strong>Makros</strong>.</p>



<p><strong>Gebe </strong>nun einen <strong>Namen </strong>für dein neues Makro <strong>ein </strong>und bestätige Diesen danach.</p>



<p>Im <strong>nächsten Schritt </strong>wird sich dadurch der <strong>VBA-Editor öffnen</strong> und schon <strong>einige Zeilen </strong>an <strong>Code</strong> zeigen.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2021/08/Beispiel-Makro-1.png"><img loading="lazy" decoding="async" width="982" height="781" src="https://robbelroot.de/wp-content/uploads/2021/08/Beispiel-Makro-1.png" alt="Beispiel Makro 1" class="wp-image-5231" title="Beispiel Makro 1" srcset="https://robbelroot.de/wp-content/uploads/2021/08/Beispiel-Makro-1.png 982w, https://robbelroot.de/wp-content/uploads/2021/08/Beispiel-Makro-1-300x239.png 300w, https://robbelroot.de/wp-content/uploads/2021/08/Beispiel-Makro-1-768x611.png 768w, https://robbelroot.de/wp-content/uploads/2021/08/Beispiel-Makro-1-700x557.png 700w, https://robbelroot.de/wp-content/uploads/2021/08/Beispiel-Makro-1-332x264.png 332w" sizes="auto, (max-width: 982px) 100vw, 982px" /></a><figcaption>Beispiel Makro 1 – Quelle: Microsoft Dokumentation</figcaption></figure>



<p><strong>Hier </strong>könntest Du nun den <strong>Code deines Makros </strong>eintragen und z. B. durch:</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="">MsgBox("Yay, mein eigenes Makro!")</pre>



<p>eine <strong>simple Messagebox anzeigen </strong>lassen.</p>



<p><strong>Detailliertere </strong>Informationen findest Du auch in der <strong><a href="https://docs.microsoft.com/de-de/office/vba/library-reference/concepts/getting-started-with-vba-in-office" target="_blank" rel="noreferrer noopener">offiziellen Dokumentation </a></strong>von Microsoft.</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/excel-makro-erstellen/">Excel Makro erstellen</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/excel-makro-erstellen/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
	</channel>
</rss>
