<?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>guide Archive - Robert Skibbe</title>
	<atom:link href="https://robbelroot.de/blog/tag/guide/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>alias RobbelRoot – Freelance Full Stack Developer .NET</description>
	<lastBuildDate>Tue, 07 Apr 2026 11:01:10 +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>guide Archive - Robert Skibbe</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<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 fetchpriority="high" 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 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 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>VB.NET Dictionary – The Complete Guide in 2026</title>
		<link>https://robbelroot.de/blog/the-vb-net-dictionary-a-complete-guide/</link>
					<comments>https://robbelroot.de/blog/the-vb-net-dictionary-a-complete-guide/#comments</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Wed, 17 Aug 2022 14:59:23 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Visual Basic .NET (EN)]]></category>
		<category><![CDATA[Visual Basic .NET troubleshooting]]></category>
		<category><![CDATA[complete]]></category>
		<category><![CDATA[dictionary]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[hash]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[key]]></category>
		<category><![CDATA[keyvaluepair]]></category>
		<category><![CDATA[net]]></category>
		<category><![CDATA[pair]]></category>
		<category><![CDATA[value]]></category>
		<category><![CDATA[vb]]></category>
		<category><![CDATA[vbnet]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=11415</guid>

					<description><![CDATA[<p>The VB.NET Dictionary stores key-value pairs and gives you near-instant lookup speed, regardless of how many entries it holds. In this guide you&#8217;ll learn when to use it, how to add, remove and iterate over entries, and how to handle edge cases like duplicate keys safely. Comparing a Dictionary to &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/the-vb-net-dictionary-a-complete-guide/">VB.NET Dictionary – The Complete Guide in 2026</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></description>
										<content:encoded><![CDATA[


<p>The VB.NET Dictionary stores key-value pairs and gives you near-instant lookup speed, regardless of how many entries it holds. In this guide you&#8217;ll learn when to use it, how to add, remove and iterate over entries, and how to handle edge cases like duplicate keys safely.</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;">Interested?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">VB.NET development for your project?</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 work with VB.NET and C# on a daily basis. Whether it&#039;s Dictionaries, data structures or a full application – 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;letter-spacing:0.3px;transition:background .2s ease;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">Comparing a Dictionary to a list – first</h2>



<p>So as I mentioned above, we should really compare a dictionaries functionality to a generic list at first, to fully understand the dictionary itself. Let&#8217;s now create a list and add some basic entries, we will also add a class for this. I will keep the class pretty simple, just for evaluation purposes.</p>



<p>Create a new class file called &#8222;Customer.vb&#8220; and save it.</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 Customer

  Public Property Id As Integer

  Public Property Name As String

  Sub New(id As Integer, name As String)
    Me.Id = id
    Me.Name = name
  End Sub

End Class</pre>



<p>After we have created the class, we will continue by declaring a simple list property inside the forms scope. Next we need to instantiate this declared property, this will happen inside the forms constructor. In the last step, we are then going to add some customer entries/instances, where we will continue working on in a few seconds.</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 Form1

  Public Property Customers As List(Of Customer)

  Sub New()
    InitializeComponent()
    Customers = New List(Of Customer)
  End Sub

  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Customers.Add(New Customer(1, "Some Ltd."))
    Customers.Add(New Customer(2, "Nice Profit Ltd."))
    Customers.Add(New Customer(3, "Perfect Devs Ltd."))
  End Sub

End Class</pre>



<h3 class="wp-block-heading">Finding a specific customer</h3>



<p>So one first thing we could want is finding a specific customer inside the generic customer list from above. Usually this would be pretty easy if we would just like &#8222;do it&#8220;. There are two basic solutions to this, the more oldschool-ish &#8222;for each&#8220;-approach and the more modern LINQ-approach.</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="">' other code
' ...

' maybe pull this id from something like a TextBox?
Dim idToFind = 2
Dim foundCustomer As Customer
For Each customer In Customers
  If customer.Id = idToFind Then
    foundCustomer = customer
    Exit For
  End If
Next
' do something with the foundCustomer, if it has been found..</pre>



<p>Now, here is the more modern LINQ (Language Integrated Query) approach, which is basically just one single line. In the background, there&#8217;s pretty much the same happening. We&#8217;re iterating through each customer and we are using some sort of &#8222;is this the customer to be found&#8220;-function as a comparison method.</p>



<p>Want to see more LINQ in action? Take a look at <strong><a href="https://robbelroot.de/blog/how-to-use-the-csharp-linq-sum-function/" target="_blank" rel="noreferrer noopener">the C# LINQ Sum guide</a></strong> for another practical example.</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="">' other code
' ...

Dim idToFind = 2
Dim foundCustomer = Customers.SingleOrDefault(Function(x) x.Id = idToFind)
' do something with the foundCustomer, if it has been found..</pre>



<h3 class="wp-block-heading">So what&#8217;s the catch?</h3>



<p>As you might have already guessed, we need to go through each element in our list to be able to compare the corresponding id to our &#8222;idToFind&#8220;-variable. Now imagine a list being the size of like 300000 entries. See the results of my tests for those two scenarios below (having just a few entries versus having like 300k entries).</p>



<p>The first test will basically add just like 3 entries to the list and then we would like search for the customer with the id 2. It doesn&#8217;t seem like a big deal, but wait – here we are only using a rather unimportant number of data.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/08/Searching-for-a-customer-inside-a-small-list-VB-NET-Dictionary-example.png"><img loading="lazy" decoding="async" width="587" height="327" src="https://robbelroot.de/wp-content/uploads/2022/08/Searching-for-a-customer-inside-a-small-list-VB-NET-Dictionary-example.png" alt="Searching for a customer inside a small list - VB NET Dictionary example" class="wp-image-11467" title="Searching for a customer inside a small list - VB NET Dictionary example"/></a><figcaption class="wp-element-caption">Searching for a customer inside a small list &#8211; VB.NET Dictionary example</figcaption></figure>



<p>Now take a look at the second test, where we will use a lot of data. I&#8217;m using 300000 entries and I will be looking for customer id 280000.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/08/Searching-for-a-high-customer-id-inside-a-big-list-VB-NET-Dictionary-example.png"><img loading="lazy" decoding="async" width="592" height="351" src="https://robbelroot.de/wp-content/uploads/2022/08/Searching-for-a-high-customer-id-inside-a-big-list-VB-NET-Dictionary-example.png" alt="Searching for a high customer id inside a big list - VB NET Dictionary example" class="wp-image-11470" title="Searching for a high customer id inside a big list - VB NET Dictionary example"/></a><figcaption class="wp-element-caption">Searching for a high customer id inside a big list &#8211; VB.NET Dictionary example</figcaption></figure>



<p>Can you spot the drastical performance change? It&#8217;s actually insane, in my opinion! In the next section, we will compare this to actually using a dictionary for this same task. For sure, this still is a pretty low time considering us being humans. But imagine these times / performance losses being used in a server app – for sure you want your server to run as smooth as possible. One more thing is, that this time will actually increase even more, by the amount of data inside of our list / lists.</p>



<p>For the next test we are going to look at the &#8222;why&#8220;, or when you could use a dictionary instead of a list-like thingy. PS: You can also find this test project inside the <strong><a href="#downloads">downloads section</a></strong> of this post.</p>



<h2 class="wp-block-heading">When to use a VB.NET Dictionary?</h2>



<p>After the huge performance difference we have seen in the previous tests, we will now take a look at a nice opportunity to actually use the VB.NET Dictionary. The dictionary class really shines, when it comes to lookup time – well, it&#8217;s the basic thing you do within a dictionary, right? As already mentioned above, it&#8217;s just a book of key value pairs.</p>



<p>You can take an existing key, to look up the corresponding value. For sure you can also check, if the dictionary has/contains a specific key. The nice thing is, that this will work at a very nice speed/performance – even on an increasing data basis! Let&#8217;s now see the dictionary in action, when it comes to 300000 entries and looking up for example customer id 280000 again.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/08/Fast-lookup-times-using-a-VB-NET-Dictionary.png"><img loading="lazy" decoding="async" width="589" height="363" src="https://robbelroot.de/wp-content/uploads/2022/08/Fast-lookup-times-using-a-VB-NET-Dictionary.png" alt="Fast lookup times using a VB.NET Dictionary" class="wp-image-11491" title="Fast lookup times using a VB NET Dictionary"/></a><figcaption class="wp-element-caption">Fast lookup times using a VB.NET Dictionary</figcaption></figure>



<p>This is outstanding, isn&#8217;t it!? The dictionary just handled the looking up of customer with id 280000 in insanely high speed.</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 help?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Working on a .NET project and need support?</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;">Whether it’s Dictionaries, data structures or full application architecture, I work with VB.NET and C# on a daily basis. 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;letter-spacing:0.3px;transition:background .2s ease;white-space:nowrap;"
         onmouseover="this.style.background='#cf6d17'"
         onmouseout="this.style.background='#e67e22'"
      >→ Request project</a>
      
      
    </div>
  </div>
</div>
	


<h2 class="wp-block-heading">How to add values to a VB.NET Dictionary?</h2>



<p>After seeing the drastical lookup performance comparison between a simple generic list and the dictionary, it&#8217;s time for the next step. Let&#8217;s now take a look at actually adding some values to the dictionary. For this, I will switch to a more common thing everyone encounters in his life: A basic phone book.</p>



<p>First we will instantiate a new instance of the dictionary class. This will take two generic arguments, the first one states: &#8222;Hey, I want to store some collection with a key of type x&#8220;. The second argument states: &#8222;Now, I want those keys to actually look up the corresponding value of type y&#8220;.</p>



<h3 class="wp-block-heading">Adding values</h3>



<p>In our example, we will make a string (essentially a name) help us looking up the corresponding phone number. In the end we will have a string key with a matching string value, take a look at the following code. Keep in mind, that I personally prefer the type being infered by the assigned value (when it&#8217;s clear).</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 phoneBook = new Dictionary(Of String, String)
' now add some key value pairs (being names to phone numbers)
' (I just made up those numbers randomly, for sure - don't call them ;))
phoneBook.Add("John Doe", "+491122334567")
phoneBook.Add("Christine Doe", "+49188655542")
phoneBook.Add("Elon Doe", "+4948862342")</pre>



<h3 class="wp-block-heading">What happens on duplicate keys?</h3>



<p>After adding some values you might ask yourself: &#8222;But what happens, if I add the same key multiple times?&#8220;. Well, we will take a look at this in the next step. I just added a key called &#8222;key&#8220; and a value called &#8222;value&#8220; to the dictionary two times. This is what will happen:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/08/Argument-exception-when-adding-duplicate-keys-to-VB-NET-Dictionary.png"><img loading="lazy" decoding="async" width="406" height="133" src="https://robbelroot.de/wp-content/uploads/2022/08/Argument-exception-when-adding-duplicate-keys-to-VB-NET-Dictionary.png" alt="Argument exception when adding duplicate keys to VB NET Dictionary" class="wp-image-11509" title="Argument exception when adding duplicate keys to VB NET Dictionary"/></a><figcaption class="wp-element-caption">ArgumentException when adding duplicate keys to VB.NET Dictionary</figcaption></figure>



<p>You will get an &#8222;<strong><a href="https://learn.microsoft.com/en-us/dotnet/api/system.argumentexception?view=net-9.0" target="_blank" rel="noreferrer noopener">ArgumentException</a></strong>&#8220; residing in the System namespace which basically states: &#8222;Hey, you can&#8217;t add another entry with the same key called key&#8220;.</p>



<h3 class="wp-block-heading">How to get around duplicate keys in a VB.NET Dictionary?</h3>



<p>Getting around those added duplicate keys is pretty simple, we just need to use a different method on the dictionary class. The method I&#8217;m talking about is named &#8222;<strong><a href="https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.tryadd?view=net-9.0" target="_blank" rel="noreferrer noopener">TryAdd</a></strong>&#8222;. It will just try to add the specific value to the dictionary and if this works, you&#8217;ll get a &#8222;False&#8220; value back, otherwise &#8222;True&#8220;.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Dim successFullyAdded As Boolean
successfullyAdded = phoneBook.TryAdd("John Doe", "+491122334567")
' successfullyAdded will be TRUE here (the first time!)
successfullyAdded = phoneBook.TryAdd("John Doe", "+491122334567")
' successfullyAdded will be FALSE here (the second time!)</pre>



<p>Alternatively you could also check for duplicate keys beforehand using the &#8222;<strong><a href="https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.containskey?view=net-9.0" target="_blank" rel="noreferrer noopener">ContainsKey</a></strong>&#8222;-method like this.</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="">If phoneBook.ContainsKey("John Doe") Then
  ' uhoh, the dictionary already contains the name key "John Doe"
Else
  ' feel free to go!
End If</pre>



<h2 class="wp-block-heading">How to iterate over a VB.NET Dictionary?</h2>



<p>Iterating over a dictionary is pretty straightforward using a For Each loop. Each iteration gives you a KeyValuePair, which carries both the Key and the Value. This is useful when you want to go through all entries, for example to display or process them.</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="">For Each pair As KeyValuePair(Of String, String) In phoneBook
  Console.WriteLine($"Name: {pair.Key}, Phone: {pair.Value}")
Next</pre>



<h2 class="wp-block-heading">How to remove an entry from a VB.NET Dictionary?</h2>



<p>Removing an entry is done using the Remove method, just pass the key you want to drop. If the key doesn&#8217;t exist, nothing happens and no exception is thrown. You can also check the return value: it will be True if the key was found and removed, False otherwise.</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="">' removes the entry with the key "John Doe"
phoneBook.Remove("John Doe")

' or check if it was actually removed
Dim wasRemoved = phoneBook.Remove("John Doe")
If wasRemoved Then
  ' key existed and was removed
End If</pre>



<h2 class="wp-block-heading">How to get a value by key in a VB.NET Dictionary</h2>



<p>If you try to access a key that doesn&#8217;t exist using the index accessor, you&#8217;ll get a KeyNotFoundException. The safer way is to use TryGetValue instead. It returns True if the key exists and writes the value into your output variable: No exception, no crash.</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="">' risky – throws KeyNotFoundException if key doesn't exist
Dim number = phoneBook("Unknown Person")

' safe – use TryGetValue instead
Dim phoneNumber As String
If phoneBook.TryGetValue("John Doe", phoneNumber) Then
  Console.WriteLine($"Found: {phoneNumber}")
Else
  Console.WriteLine("Key not found.")
End If</pre>



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



<div class="schema-faq wp-block-yoast-faq-block"><div class="schema-faq-section" id="faq-question-1774444687823"><strong class="schema-faq-question">What is the difference between a VB.NET Dictionary and a List?</strong> <p class="schema-faq-answer">A List stores items in order and you search by index or by iterating through all items. A Dictionary stores key-value pairs and lets you look up values by key directly, which is significantly faster for large datasets, as demonstrated in this guide.</p> </div> <div class="schema-faq-section" id="faq-question-1774444696053"><strong class="schema-faq-question">How do I iterate through a VB.NET Dictionary?</strong> <p class="schema-faq-answer">Use a For Each loop over the dictionary. Each iteration gives you a KeyValuePair with a Key and Value property. Example: For Each pair As KeyValuePair(Of String, String) In phoneBook, then access pair.Key and pair.Value.</p> </div> <div class="schema-faq-section" id="faq-question-1774444710016"><strong class="schema-faq-question">What happens when I add a duplicate key to a VB.NET Dictionary?</strong> <p class="schema-faq-answer">An ArgumentException is thrown. To avoid this, use TryAdd instead of Add, it returns False if the key already exists without throwing an exception. Alternatively, check first with ContainsKey.</p> </div> <div class="schema-faq-section" id="faq-question-1775555852730"><strong class="schema-faq-question"><strong>How do I get a value by key in a VB.NET Dictionary?</strong></strong> <p class="schema-faq-answer">Use the key as an index accessor: <code>phoneBook("John Doe")</code>. To avoid a <code>KeyNotFoundException</code> on missing keys, use <code>TryGetValue</code> instead, which returns <code>False</code> if the key doesn&#8217;t exist.</p> </div> </div>



<h2 class="wp-block-heading">Summing everything up</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/08/summing-up-vb-net-dictionary.png"><img loading="lazy" decoding="async" width="640" height="360" src="https://robbelroot.de/wp-content/uploads/2022/08/summing-up-vb-net-dictionary.png" alt="Summing everything up" class="wp-image-11518" title="Summing everything up"/></a><figcaption class="wp-element-caption">Summing everything up</figcaption></figure>



<p>Coming to the end of today&#8217;s post, we will finish by summing up the things we saw about a VB.NET Dictionary. It basically is – as the name suggests – a collection of keys mapped to their corresponding values. Its biggest advantage is the fast lookup time using a key, which is pretty nice for performance/speed optimized portions of your applications. Keep in mind, that the dictionary itself doesn&#8217;t guarantee a specific iteration order everytime, as it keeps no track about that (you can take a look in the documentation for that).</p>



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



<div class="wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="https://robbelroot.de/downloads/vbnet/DictionaryGuideExample.zip" target="_blank" rel="noreferrer noopener">DictionaryGuideExample.zip</a></div>
</div>



<h2 class="wp-block-heading">Related posts</h2>



<ul class="wp-block-list">
<li><strong><a href="https://robbelroot.de/blog/vb-net-removing-items-from-listboxes/" target="_blank" rel="noreferrer noopener">VB.NET removing Items from ListBoxes in 2022</a></strong></li>



<li><strong style="color: initial;"><a href="https://robbelroot.de/blog/creating-a-vb-net-datagridview-filter-functionality/" target="_blank" rel="noreferrer noopener">Creating a VB.NET DataGridView filter functionality</a></strong></li>
</ul>
<p>Der Beitrag <a href="https://robbelroot.de/blog/the-vb-net-dictionary-a-complete-guide/">VB.NET Dictionary – 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-vb-net-dictionary-a-complete-guide/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>&#x1f575;&#xfe0f; Hacking a NET Application</title>
		<link>https://robbelroot.de/blog/hacking-a-net-application/</link>
					<comments>https://robbelroot.de/blog/hacking-a-net-application/#comments</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Wed, 12 Jan 2022 22:02:00 +0000</pubDate>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[avoid]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[credentials]]></category>
		<category><![CDATA[dangerous]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[ftp]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[hacked]]></category>
		<category><![CDATA[hacker]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[hardcode]]></category>
		<category><![CDATA[hardcoding]]></category>
		<category><![CDATA[hd]]></category>
		<category><![CDATA[help]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[password]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[user]]></category>
		<category><![CDATA[vbnet]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[vulnerable]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=7320</guid>

					<description><![CDATA[<p>Hacking User &#38; Password information from a NET Assembly So you are interested in hacking a simple NET Application with like all the nerdy stuff!? Then i&#8217;m glad to tell you, that you are very welcome, go ahead and let&#8217;s hack! This example will work for C# as well, even &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/hacking-a-net-application/">&#x1f575;&#xfe0f; Hacking a NET Application</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/01/Hacking-User-Pass-Thumbnail.png"><img loading="lazy" decoding="async" width="1920" height="1080" src="https://robbelroot.de/wp-content/uploads/2022/01/Hacking-User-Pass-Thumbnail.png" alt="" class="wp-image-7324"/></a></figure>






<h2 class="wp-block-heading" id="hacking-user-password-information-from-a-net-assembly">Hacking User &amp; Password information from a NET Assembly</h2>



<p>So you are interested in <strong>hacking a simple NET Application</strong> with like <strong>all </strong>the <strong>nerdy stuff</strong>!?</p>



<p>Then i&#8217;m glad to tell you, that you are <strong>very welcome</strong>, <strong>go </strong>ahead and <strong>let&#8217;s hack</strong>!</p>



<p>This example <strong>will work for C# as well</strong>, even it is presented with a Visual Basic NET Application.</p>



<p>In the <strong>first few lines </strong>i will <strong>write </strong>a bit <strong>about </strong>my <strong>own experience </strong>with hacking, that i experienced &#8222;on&#8220; myself. </p>



<p><strong>After that </strong>i <strong>will show </strong>you some kind of <strong>basic example </strong>application, which is like our victim.</p>



<p><strong>In </strong>the<strong> last step </strong>i will explain, <strong>which tool </strong>you would need to inspect those specific files.</p>



<p>You will also learn how to <strong>find the information</strong> you need inside those tools.</p>



<h2 class="wp-block-heading" id="liking-humour-videos-heres-the-youtube-version">Liking humour &amp; videos? Heres the YouTube version</h2>



<p><strong>If</strong> you <strong>like watching videos </strong>and <strong>having </strong>like <strong>actual </strong>live <strong>examples </strong>– i&#8217;ve also got you covered!</p>



<p>Just <strong>visit <a href="https://youtube.com/RobbelRoot" target="_blank" rel="noreferrer noopener">my YouTube channel</a></strong> <strong>or click </strong>the following <strong>video </strong>to load and watch it:</p>


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



<h2 class="wp-block-heading" id="why-knowing-how-to-hack-some-things-is-important">Why knowing how to hack some things is important</h2>



<p><strong>Even if you&#8217;re not </strong>that in the dark sitting <strong>hacker person</strong>, yet <strong>knowing </strong>about hacking <strong>is </strong>very <strong>important </strong>in terms of programming.</p>



<p>Why – you ask? Because <strong>actively hacking</strong> has <strong>obviously </strong>something really important <strong>to do with the opposite</strong>.</p>



<p><strong>Knowing how </strong>attacker actually <strong>attacks</strong>, will <strong>make </strong>you <strong>stronger in defending </strong>yourself.</p>



<p>So <strong>if </strong>you <strong>understand </strong>the <strong>concepts</strong>, you <strong>have </strong>a (better) <strong>chance to </strong>actually <strong>defend </strong>against them – right!?</p>



<p>You can see, that the old and good saying &#8222;<strong>wisdom is power</strong>&#8220; <strong>isn&#8217;t</strong> that <strong>bad </strong>at all.</p>



<p>This also <strong>counts for programming</strong> or software development as well.</p>



<h3 class="wp-block-heading" id="sometimes-learning-attacking-turns-to-defending">Sometimes learning attacking turns to defending</h3>



<p><strong>Defending against hackers </strong>in a <strong>possible matter</strong>, is like one of the basic essences.</p>



<p>I mean <strong>who wants </strong>to build <strong>application </strong>basically everyone could get like <strong>for free</strong>, or <strong>even </strong>script <strong>kiddies can </strong>crack.</p>



<p><strong>Sure there </strong>are <strong>unavoidable </strong>situations or better said <strong>different aspects</strong>, <strong>where </strong>you <strong>can&#8217;t protect</strong> yourself, or your app.</p>



<p>I <strong>had to </strong>hardly <strong>learn myself</strong>, that those aspects <strong>aren&#8217;t the real key</strong> of importance, too!</p>



<p>This is <strong>where </strong>we are about to switch to <strong>my own </strong>little <strong>story behind </strong>that whole thing.</p>



<h2 class="wp-block-heading" id="my-own-background-and-contact-points-of-hacking">My own background and contact points of hacking</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Hacking-a-NET-Application-My-Story.png"><img loading="lazy" decoding="async" width="1200" height="628" src="https://robbelroot.de/wp-content/uploads/2022/01/Hacking-a-NET-Application-My-Story.png" alt="My Story- Hacking a NET Application" class="wp-image-7341" title="My Story- Hacking a NET Application"/></a><figcaption>My Story – Hacking a NET Application</figcaption></figure>



<p><strong>Even if i don&#8217;t </strong>really <strong>know </strong>to <strong>where </strong>like i should actually <strong>start </strong>telling you, i will try to find some starting point.</p>



<p><strong>One of the things</strong>, which <strong>stuck in my mind</strong> till today – and it&#8217;s like 15 years ago – <strong>is the following</strong> thingy.</p>



<p><strong>I was a</strong> little <strong>gamer </strong>bro, who was <strong>playing </strong>his current <strong>MMO </strong>called &#8222;Silkroad Online&#8220; like insane.</p>



<p><strong>Everyone who knows </strong>about the so called &#8222;<strong>china grinders</strong>&#8220; knows what i&#8217;m talking about..</p>



<p><strong>Those games </strong>are the <strong>definition </strong>of &#8222;spend all your time&#8220;, because they are so <strong>grinding based</strong>, hence the name..</p>



<h3 class="wp-block-heading" id="a-whole-load-of-work-gone">A whole load of work – gone</h3>



<p>You are <strong>essentially slaying like 5000</strong> monsters <strong>to get </strong>almost no drops and <strong>zero </strong>exp.</p>



<p>As you can imagine there were like many <strong>scammers </strong>and <strong>fakers </strong>which <strong>tried to scam or hack your account</strong>.</p>



<p>Despite this <strong>i liked the game</strong> and i <strong>can&#8217;t</strong> exactly <strong>tell why</strong>, i think it was the chinese and dragonball like style.</p>



<p>You <strong>had </strong>like this <strong>whole chinese world </strong>built <strong>around </strong>the <strong>silkroad lore</strong> (and i really love &#8222;the&#8220; asian lore).</p>



<p><strong>Then </strong>there was this <strong>dragonball </strong>like aspect, where you <strong>can shoot your own</strong> &#8222;<strong>kamehameha</strong>&#8220; which kept me for long enough.</p>



<p><strong>In the end</strong> i <strong>spent hours </strong>and hours <strong>fighting </strong>those <strong>monsters for </strong>like almost <strong>nothing and </strong>even <strong>wasted </strong>some *cough* <strong>bucks</strong>.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Hacking-a-NET-Application-Speeding-things-up-with-a-bot.png"><img loading="lazy" decoding="async" width="1200" height="628" src="https://robbelroot.de/wp-content/uploads/2022/01/Hacking-a-NET-Application-Speeding-things-up-with-a-bot.png" alt="Speeding things up with a bot – Hacking a NET Application" class="wp-image-7352" title="Speeding things up with a bot – Hacking a NET Application"/></a><figcaption>Speeding things up with a bot – Hacking a NET Application</figcaption></figure>



<p><strong>As </strong>i <strong>always </strong>had this &#8222;hmm, i gotta <strong>find a solution</strong> for that&#8220;-mentality, i also <strong>tried to</strong> do this time.</p>



<p><strong>After all </strong>the <strong>outcome wasn&#8217;t</strong> that <strong>good </strong>in the end, but well, i think that&#8217;s the price you gotta pay, huh!?</p>



<h3 class="wp-block-heading" id="searching-for-help">Searching for help</h3>



<p>So i <strong>started searching</strong> for like helpers with leveling and <strong>found different leveling services</strong>, but they <strong>were </strong>mostly very <strong>expensive</strong>..</p>



<p><strong>Not much time after </strong>that, i <strong>found </strong>something called &#8222;<strong>bot</strong>&#8222;, which was basically just a software.</p>



<p><strong>Those </strong>were/are <strong>tools </strong>which will <strong>take </strong>the <strong>leveling aspect</strong> in their hand and basically <strong>tell your </strong>ingame <strong>character what to do</strong> – so you don&#8217;t have to.</p>



<p><strong>There was a free bot</strong> which i downloaded and installed and <strong>boom </strong>– the <strong>problem happened</strong>.</p>



<p>It <strong>did its level job pretty well</strong>, <strong>but had </strong>like an integrated <strong>trojan </strong>aspect, which <strong>spied on </strong>my <strong>credentials </strong>and <strong>transferred </strong>my <strong>data </strong>to its owner.</p>



<p>So not <strong>many days after</strong> the installation, one of my <strong>accounts was gone</strong> – yeah, i had multiple&#8230;</p>



<p><strong>This is the whole story why i started learning programming and hacking</strong> – i wanted to create my own bot to compensate my lost time and my lost account!</p>



<p><strong>Back to </strong>the main <strong>topic </strong>– hacking a NET application!</p>



<h2 class="wp-block-heading" id="how-i-started-programming-like-logins-ew">How i started programming like logins – ew</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Login-Screens-how-to-hack-a-net-application.png"><img loading="lazy" decoding="async" width="1200" height="628" src="https://robbelroot.de/wp-content/uploads/2022/01/Login-Screens-how-to-hack-a-net-application.png" alt="Login Screens - how to hack a net application" class="wp-image-7365" title="Login Screens - how to hack a net application"/></a><figcaption>Login Screens &#8211; how to hack a net application</figcaption></figure>



<p>So <strong>now the story begins</strong>, where <strong>i started programming</strong> at all and like <strong>login screens</strong>.</p>



<p>I think <strong>every beginner in programming did it like this</strong> at some point.</p>



<p><strong>On </strong>the <strong>one side </strong>you are just <strong>making your first steps</strong> and on the <strong>other side </strong>you just want to <strong>make it work</strong>.</p>



<p>You <strong>don&#8217;t have much knowledge</strong> – if any at all – about this persistence thingy called <strong>database</strong>, <strong>nor </strong>the <strong>security </strong>thingy called <strong>cryptography</strong>, etc.</p>



<p><strong>This makes you </strong>– especially at the beginning – <strong>think</strong>, that you <strong>can just do </strong>this thing, which is known as <strong>hardcoding</strong>.</p>



<p>You <strong>just put variables inside </strong>the code (or something similar) <strong>with fixed</strong> values like:</p>



<pre class="wp-block-code"><code>variableA = "ValueB"</code></pre>



<p><strong>Then </strong>you can go ahead and <strong>easily compare </strong>this <strong>value in </strong>terms of an <strong>authentication screen </strong>like:</p>



<pre class="wp-block-code"><code>user = "User"
password = "password"
if enteredUser = user and enteredPassword = password then...</code></pre>



<p><strong>So far</strong> this doesn&#8217;t seem like anything <strong>hacky</strong>, but <strong>read </strong>a few <strong>more </strong>lines and <strong>let me explain</strong>!</p>



<p><strong>One big problem </strong>is, that even <strong>if you think</strong> that <strong>only </strong>&#8222;<strong>noobs</strong>&#8220; <strong>do this</strong>, <strong>i&#8217;ve seen too many agencies</strong> and similar small firms did that as well.</p>



<p>I mean it&#8217;s <strong>one thing</strong> if you&#8217;re <strong>doing </strong>this <strong>on </strong>your <strong>own</strong>, <strong>local computer</strong>, for yourself <strong>with </strong>no <strong>customer data </strong>involved.</p>



<p>But i really think it&#8217;s <strong>something different when </strong>&#8222;<strong>companies</strong>&#8220; do things like this, <strong>knowing that </strong>it&#8217;s totally <strong>wrong</strong>!</p>



<p><strong>Especially in my work as a freelancer &amp; teacher</strong> i learned, that small business i supported, sometimes persisted on like &#8222;nah we will do it like this, it&#8217;s okay&#8220;.</p>



<p>Some <strong>other excuses</strong> i hear a lot are like &#8222;It&#8217;s <strong>only a small customer</strong>, that&#8217;s okay&#8220;, or &#8222;there&#8217;s <strong>no budget left</strong>, just do it&#8220;!</p>



<p><strong>Even </strong>if this <strong>involved software</strong> for other customers which <strong>got their software</strong> like <strong>delegated </strong>to freelancers.</p>



<h2 class="wp-block-heading" id="creating-the-sample-application-our-victim">Creating the sample application – our victim</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Login-Dialog-example-hardcoded-credentials-in-NET-application.png"><img loading="lazy" decoding="async" width="1280" height="720" src="https://robbelroot.de/wp-content/uploads/2022/01/Login-Dialog-example-hardcoded-credentials-in-NET-application.png" alt="Login Dialog example - hardcoded credentials in NET application" class="wp-image-7379" title="Login Dialog example - hardcoded credentials in NET application"/></a><figcaption>Login Dialog example &#8211; hardcoded credentials in NET application</figcaption></figure>



<p>So now <strong>let&#8217;s jump to the hacking action</strong> and see what malicous things can actually happen if you&#8217;re doing it like above yourself.</p>



<p>You can <strong>go ahead </strong>now and <strong>create a new windows forms application</strong> (dotnet Core 3.1 in the example above).</p>



<p>The <strong>first Form </strong>will be the &#8222;<strong>frmLogin</strong>&#8222;, which is – as you&#8217;ve may guessed – the <strong>form where the login will happen</strong>.</p>



<h3 class="wp-block-heading" id="basic-login-form-controls">Basic login form controls</h3>



<p><strong>Add </strong>the usual login <strong>controls like 2 textboxes for the user and the password</strong>, as well as the <strong>button to start the login</strong> process.</p>



<p><strong>Name the button</strong> – like you should always do – for example &#8222;btnLogin&#8220; and put <strong>the following code</strong> inside the handler:</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="btn-login-sub">Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
    Dim loginFailed = Not CheckLogin(tbUser.Text, tbPassword.Text)
    If loginFailed Then
        MessageBox.Show("Login failed!")
        Return
    End If
    successfullySubmitted = True
    Dim mainForm = New frmMain()
    mainForm.Show()
    Close()
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="btn-login-sub">private void btnLogin_Click(object sender, EventArgs e)
{
    var loginFailed = !CheckLogin(tbUser.Text, tbPassword.Text);
    if (loginFailed)
    {
        MessageBox.Show("Login failed!");
        Return;
    }
    successfullySubmitted = true;
    var mainForm = new frmMain();
    mainForm.Show();
    Close();
}</pre>



<p>The <strong>code will call the check &#8222;Check-Login&#8220;-function</strong> which we will declare in a second <strong>and invert </strong>the <strong>result</strong>.</p>



<p>We are <strong>doing this to</strong> use this &#8222;<strong>early return</strong>&#8222;-block in the next few lines, to display a <strong>short message</strong> and well – <strong>return </strong>early.</p>



<p><strong>Then </strong>we are <strong>setting a flag to true</strong>, to avoid closing the form, but ignore this for now, you can see it later with the complete code.</p>



<h3 class="wp-block-heading" id="the-protected-content-the-main-form">The protected content – the main form</h3>



<p><strong>Next </strong>we are <strong>creating a new</strong> &#8222;<strong>frmMain</strong>&#8220; instance <strong>and show it</strong> in the next step.</p>



<p><strong>In </strong>the <strong>last step</strong> we are <strong>closing </strong>the <strong>current form</strong>, so we are basically <strong>closing the login form</strong>, to only <strong>leave </strong>the <strong>main </strong>form open.</p>



<p><strong>Right now</strong> is the time to <strong>define </strong>the &#8222;<strong>CheckLogin</strong>&#8222;-<strong>function</strong>, before we continue adding the main form:</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="checklogin-function">Private Function CheckLogin(user As String, password As String) As Boolean
    Dim credentialsMatching = user = "User" AndAlso password = "password"
    Return credentialsMatching
End Function</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="checklogin-function">private bool CheckLogin(string user, string password)
{
    var credentialsMatching = user == "User" &amp;&amp; password == "password";
    returnn credentialsMatching;
}</pre>



<p>Now <strong>create </strong>an <strong>additional form </strong>and call it like &#8222;frmMain&#8220;, you can<strong> leave the form as it is</strong>.</p>



<p>You <strong>could add </strong>something like <strong>code to handle the closing</strong> of the app for you, <strong>but </strong>this <strong>isn&#8217;t necessary</strong>.</p>



<p><strong>Maybe </strong>you want to <strong>download </strong>the <strong>complete project</strong> down below, so you can see everything in total.</p>



<p>Currently the app <strong>should look something like this</strong>:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Hacking-NET-Application-Example-App.gif"><img loading="lazy" decoding="async" width="885" height="446" src="https://robbelroot.de/wp-content/uploads/2022/01/Hacking-NET-Application-Example-App.gif" alt="Hacking NET Application Example App" class="wp-image-7392" title="Hacking NET Application Example App"/></a><figcaption>NET Application Example App hacking</figcaption></figure>



<h2 class="wp-block-heading" id="hacking-our-sample-application">Hacking our sample application</h2>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Hacking-our-NET-sample-application-extracting-hardcoded-credentials.png"><img loading="lazy" decoding="async" width="1280" height="960" src="https://robbelroot.de/wp-content/uploads/2022/01/Hacking-our-NET-sample-application-extracting-hardcoded-credentials.png" alt="Hacking our NET sample application - extracting hardcoded credentials" class="wp-image-7396" title="Hacking our NET sample application - extracting hardcoded credentials"/></a><figcaption>Hacking our NET sample application &#8211; extracting hardcoded credentials</figcaption></figure>



<p><strong>To </strong>actually <strong>start hacking </strong>our little <strong>NET application</strong>, you <strong>need </strong>a <strong>tool</strong>, which is actually <strong>provided by </strong>the <strong>NET </strong>Framework itself.</p>



<p>So there is <strong>no big magic</strong>, <strong>or </strong>big action like &#8222;yeah you need to download x, y, z.. blabla..&#8220;.</p>



<p><strong>Everything </strong>you need, is <strong>mostly already in place</strong>, <strong>if </strong>you <strong>installed Visual Studio</strong>.</p>



<h3 class="wp-block-heading" id="the-needed-tool-ildasm">The needed tool – &#8222;ildasm&#8220;</h3>



<p>The <strong>tool needed is called</strong> &#8222;<strong>IL-Disassembler</strong>&#8220; or in short &#8222;<strong>ildasm</strong>&#8220; and resides in the &#8222;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools&#8220; folder.</p>



<p><strong>Maybe </strong>you will <strong>find </strong>the tool <strong>in </strong>a slightly <strong>different location</strong>, <strong>if </strong>you have a <strong>different version </strong>of Visual Studio, etc.</p>



<p><strong>Double click the tool</strong> to open it and the <strong>following screen </strong>will appear:</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/IL-Disassembler-ildasm-screenshot.png"><img loading="lazy" decoding="async" width="389" height="282" src="https://robbelroot.de/wp-content/uploads/2022/01/IL-Disassembler-ildasm-screenshot.png" alt="IL-Disassembler ildasm screenshot" class="wp-image-7403" title="IL-Disassembler ildasm screenshot"/></a><figcaption>IL-Disassembler ildasm screenshot</figcaption></figure>



<p>Then <strong>go ahead and select your</strong> &#8222;&lt;YourApplicationName&gt;.<strong>dll</strong>&#8222;-<strong>file </strong>with the <strong>&#8222;File-&gt;Open&#8220; menu item</strong> (sorry, i only have the german version).</p>



<p>You can <strong>find this file inside the debug folder of your app </strong>(don&#8217;t forget to start debugging at least once, so the files are created!).</p>



<p>Just a <strong>quick side note</strong>: This will <strong>also work for </strong>the <strong>release </strong>&#8222;.dll&#8220;-file!</p>



<p><strong>Expand the nodes as shown</strong> in the screenshot, then you will find the function we are looking for.</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/IL-Disassembler-ildasm-viewing-the-checklogin-function.png"><img loading="lazy" decoding="async" width="389" height="597" src="https://robbelroot.de/wp-content/uploads/2022/01/IL-Disassembler-ildasm-viewing-the-checklogin-function.png" alt="IL-Disassembler ildasm viewing the checklogin function" class="wp-image-7411" title="IL-Disassembler ildasm viewing the checklogin function"/></a><figcaption>IL-Disassembler ildasm viewing the checklogin function</figcaption></figure>



<p>If you <strong>finally double click that &#8222;CheckLogin&#8220;-function</strong>, a <strong>dialog will</strong> appear, where you can <strong>inspect the IL code</strong> for this function.</p>



<p><strong>There </strong>you will <strong>see </strong>you <strong>hardcoded credentials</strong> – <strong>congratulations, you hacked the program</strong>!</p>



<figure class="wp-block-image size-full"><a href="https://robbelroot.de/wp-content/uploads/2022/01/Finished-hacking-the-net-application-by-revealing-hardcoded-credentials.png"><img loading="lazy" decoding="async" width="624" height="394" src="https://robbelroot.de/wp-content/uploads/2022/01/Finished-hacking-the-net-application-by-revealing-hardcoded-credentials.png" alt="Finished hacking the net application by revealing hardcoded credentials" class="wp-image-7414" title="Finished hacking the net application by revealing hardcoded credentials"/></a><figcaption>Finished hacking the net application by revealing hardcoded credentials</figcaption></figure>



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



<div class="wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex">
<div class="wp-block-button"><a class="wp-block-button__link" href="https://bit.ly/hacking-a-dot-net-application-download" target="_blank" rel="noreferrer noopener">SimpleHackExample.zip</a></div>
</div>



<h2 class="wp-block-heading" id="related-posts">Related posts</h2>



<ul class="wp-block-list"><li><strong><a href="https://robbelroot.de/blog/creating-a-vb-net-datagridview-filter-functionality/" target="_blank" rel="noreferrer noopener">How to filter a DataGridView in VB NET</a></strong></li><li><strong><a href="https://robbelroot.de/blog/hacking-a-webshop/" target="_blank" rel="noreferrer noopener">Hacking a Webshop</a></strong></li><li><strong><a href="https://robbelroot.de/blog/converting-davinci-resolve-markers-to-youtube-chapters/" target="_blank" rel="noreferrer noopener">Converting DaVinci Resolve markers to YouTube chapters</a></strong></li></ul>
<p>Der Beitrag <a href="https://robbelroot.de/blog/hacking-a-net-application/">&#x1f575;&#xfe0f; Hacking a NET Application</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/hacking-a-net-application/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
	</channel>
</rss>
