<?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>Robert Skibbe, Autor bei Robert Skibbe</title>
	<atom:link href="https://robbelroot.de/blog/author/robbelroot/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>alias RobbelRoot – Freelance Full Stack Developer .NET</description>
	<lastBuildDate>Thu, 09 Apr 2026 13:17:41 +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>Robert Skibbe, Autor bei Robert Skibbe</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Is Visual Basic Dead? The Real State of VB.NET (2026)</title>
		<link>https://robbelroot.de/blog/is-visual-basic-dead/</link>
					<comments>https://robbelroot.de/blog/is-visual-basic-dead/#respond</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Thu, 09 Apr 2026 13:14:24 +0000</pubDate>
				<category><![CDATA[Legacy Modernization]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=20502</guid>

					<description><![CDATA[<p>Is Visual Basic dead? If we only look at Google Trends, the answer seems clear. But as a freelance developer who still gets regular VB.NET jobs, the real picture is more nuanced. VB.NET is in maintenance mode, Microsoft won&#8217;t add new features, and the community is shrinking. But it still &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/is-visual-basic-dead/">Is Visual Basic Dead? The Real State of VB.NET (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p><strong>Is Visual Basic dead?</strong> If we only look at Google Trends, the answer seems clear. But as a freelance developer who still gets regular VB.NET jobs, the real picture is more nuanced. VB.NET is in maintenance mode, Microsoft won&#8217;t add new features, and the community is shrinking. But it still compiles, still runs, and still pays bills. This article covers the current state of VB.NET in 2026 with real data, Microsoft&#8217;s official stance, who still uses it, and whether you should invest time in it.</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;">VB.NET project?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Need help with a VB.NET application?</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 have been developing professionally in VB.NET and C# for over 17 years. From legacy maintenance to full rewrites, I can help.</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 a project</a>
      
      
    </div>
  </div>
</div>
	





<h2 class="wp-block-heading">The short answer</h2>



<p>VB.NET is not dead in the sense that it stops working. Your existing code compiles and runs on .NET 8, .NET 9 and beyond. But it is effectively in <strong>maintenance mode</strong>: no new language features, no new frameworks like Blazor or MAUI, and a shrinking developer community. If you have a running VB.NET project, it will keep running. If you are starting something new, choose C#.</p>



<h2 class="wp-block-heading">Microsoft&#8217;s official stance</h2>



<p>In 2020, Microsoft officially announced that VB.NET will <strong>no longer receive new language features</strong>. The language will continue to be supported in .NET (including .NET 8 and .NET 9), but only for bug fixes and compatibility. New frameworks and APIs are C#-only:</p>



<ul class="wp-block-list">
<li><strong>Blazor</strong>: C# only</li>



<li><strong>.NET MAUI</strong>: C# only</li>



<li><strong>Minimal APIs</strong>: C# only</li>



<li><strong>Source generators</strong>: C# only</li>



<li><strong>WinForms / WPF</strong>: Still supported in VB.NET</li>



<li><strong>Console apps</strong>: Still supported in VB.NET</li>
</ul>



<p>This means VB.NET is not &#8222;dead&#8220; today, but it is on a clear path toward irrelevance for new projects. Microsoft maintains it so existing codebases keep working, not because they see a future in it.</p>



<h2 class="wp-block-heading">Usage data: Google Trends and real-world numbers</h2>



<p>Google Trends paints a clear picture. Comparing &#8222;Visual Basic .NET&#8220;, &#8222;VB.NET&#8220;, and &#8222;C#&#8220; over the past 12 months worldwide, VB.NET barely registers. The interest has been declining steadily for years.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://robbelroot.de/wp-content/uploads/2024/01/vbnet-dead-google-trends-2026.png" alt="Google Trends comparison showing VB.NET interest declining against C# worldwide in 2026"/><figcaption class="wp-element-caption">Google Trends: Visual Basic .NET vs C# vs VB.NET interest worldwide (March 2026)</figcaption></figure>
</div>


<p>But Google Trends is not the full story. As a freelance .NET developer, I still receive regular VB.NET project requests. Looking at my incoming programming jobs by language over the past years, VB.NET accounts for a significant share of .NET-related work:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://robbelroot.de/wp-content/uploads/2024/01/Incoming-programming-jobs-by-language-Is-VB.NET-dead.png" alt="Pie chart showing incoming programming jobs by language including VB.NET C# and PHP"/><figcaption class="wp-element-caption">Incoming programming jobs by language</figcaption></figure>
</div>


<p>The requests are surprisingly balanced between VB.NET and C# in my niche. This does not mean VB.NET is thriving globally, but it shows that <strong>real demand still exists</strong>, especially for maintaining and extending legacy applications.</p>



<h2 class="wp-block-heading">Who still uses VB.NET</h2>



<p>After 17+ years in this field, working with YouTube subscribers, website visitors, and customers, I can give a fairly clear picture of who still writes VB.NET code:</p>



<ul class="wp-block-list">
<li><strong>Hobbyists and self-taught developers</strong>: People who learned VB.NET years ago and build small tools for personal use or to automate their day jobs</li>



<li><strong>Companies with legacy codebases</strong>: Businesses running WinForms or WPF applications built 10-15 years ago that still work and generate revenue</li>



<li><strong>Automation and measurement projects</strong>: VB.NET is common in industrial automation, data logging, and measurement tools</li>



<li><strong>Excel/Office integration</strong>: VBA developers who stepped up to VB.NET for more complex tooling</li>
</ul>



<p>Honestly, most VB.NET developers I encounter are 50+ years old and many operate at a hobbyist skill level. Clean code, unit testing, and SOLID principles are the exception, not the rule. This is not VB.NET&#8217;s fault as a language. It is capable of clean, professional code. But the community that remains tends to prioritize &#8222;it works&#8220; over maintainability. If you want to write better code regardless of language, check out my <a href="https://robbelroot.de/blog/clean-code-in-der-praxis/"><strong>Clean Code guide</strong></a>.</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;">Legacy code?</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 application that needs modernizing?</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 maintain, extend, and modernize VB.NET applications. Whether it is a quick fix or a full migration to C#, I have done it many times.</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 a project</a>
      
      
    </div>
  </div>
</div>
	


<h2 class="wp-block-heading">What VB.NET is still good for</h2>



<p>Despite its declining trajectory, VB.NET has legitimate use cases:</p>



<ul class="wp-block-list">
<li><strong>Learning programming</strong>: The English-like syntax makes it one of the most approachable languages for beginners. <code>If x > 5 Then</code> reads like a sentence. For someone who has never written code, this lowers the barrier significantly.</li>



<li><strong>Maintaining existing applications</strong>: If you have a running WinForms app with 100k lines of VB.NET, rewriting it in C# just for the sake of it makes no business sense. Maintain it, extend it, and migrate incrementally if needed.</li>



<li><strong>Small internal tools</strong>: Quick automation tools, data converters, or reporting utilities where the developer already knows VB.NET.</li>



<li><strong>Prototyping</strong>: VB.NET&#8217;s WinForms designer is still one of the fastest ways to throw together a UI for testing an idea.</li>
</ul>



<p>VB.NET is perfectly capable of professional work. For example, see how to properly use a <a href="https://robbelroot.de/blog/the-vb-net-dictionary-a-complete-guide/"><strong>VB.NET Dictionary</strong></a> or how to <a href="https://robbelroot.de/blog/vbnet-write-text-file/"><strong>write text files in VB.NET</strong></a>.</p>



<h2 class="wp-block-heading">Why you should learn C# instead</h2>



<p>If you are starting fresh or considering your next step, the answer is C#. Not because VB.NET is bad, but because the ecosystem has moved on:</p>



<ul class="wp-block-list">
<li><strong>Every new .NET feature</strong> targets C# first (and often only)</li>



<li><strong>Job market</strong>: C# job listings outnumber VB.NET listings by a factor of 20+</li>



<li><strong>Community and resources</strong>: Stack Overflow answers, tutorials, NuGet packages, and blog posts overwhelmingly target C#</li>



<li><strong>Cross-platform</strong>: .NET MAUI, Blazor, ASP.NET Minimal APIs are all C#-only</li>



<li><strong>Career growth</strong>: Knowing C# opens doors to web, mobile, cloud, and game development (Unity)</li>
</ul>



<p>The good news: if you know VB.NET, learning C# is not that hard. The .NET framework is the same. The syntax is different, but the concepts (classes, events, LINQ, async/await) transfer directly. Many of the patterns you already know from VB.NET work identically. For example, <a href="https://robbelroot.de/blog/vbnet-addhandler-en/"><strong>event handling with AddHandler</strong></a> in VB.NET maps directly to C#&#8217;s <code>+=</code> operator.</p>



<h2 class="wp-block-heading">My personal take</h2>



<p>I started programming with VB.NET when I was around 13 years old. I had tried C and C++ before and quit out of frustration. VB.NET&#8217;s approachable syntax got me through the door, and I never left the world of software development. Today I work primarily in C#, but VB.NET is still part of my regular toolkit.</p>



<p>I also think VB.NET gets unfair treatment. The language itself is not the problem. It supports clean code, SOLID principles, and proper architecture. The problem is that it attracts beginners who never progress beyond &#8222;it works&#8220; code. That gives the language a bad reputation it does not fully deserve.</p>



<p>If someone asks me &#8222;Should I start with VB.NET or C#?&#8220;, my answer is always C#. But if someone asks &#8222;Is VB.NET dead?&#8220;, my honest answer is: it is slowly fading out, but it is not dead yet. And if learning VB.NET is what gets you into programming, then it served its purpose.</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;">Thinking about switching?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">I help VB.NET developers transition to C#</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;">With 17+ years in both languages, I offer 1-on-1 lessons and project-based coaching. Whether you want to modernize legacy VB code or learn C# from scratch.</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'"
      >→ Book a free intro call</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-vbdead-en-1"><strong class="schema-faq-question"><strong>Is VB.NET still supported by Microsoft?</strong></strong> <p class="schema-faq-answer">Yes, VB.NET is still supported in .NET 8 and .NET 9 for bug fixes and compatibility. However, Microsoft will not add new language features. New frameworks like Blazor, MAUI, and Minimal APIs are C#-only.</p> </div> <div class="schema-faq-section" id="faq-vbdead-en-2"><strong class="schema-faq-question"><strong>Should I learn VB.NET or C# in 2026?</strong></strong> <p class="schema-faq-answer">C#, without question. Every new .NET feature targets C# first, the job market is 20x larger, and frameworks like Blazor and MAUI only work with C#. VB.NET is fine for maintaining existing apps, but not for starting fresh.</p> </div> <div class="schema-faq-section" id="faq-vbdead-en-3"><strong class="schema-faq-question"><strong>Can I convert my VB.NET project to C#?</strong></strong> <p class="schema-faq-answer">Yes. The .NET framework is the same underneath. Tools like the <a href="https://converter.telerik.com/">Telerik Code Converter</a> can do a first pass, but complex projects need manual review. Many developers migrate incrementally, converting one module at a time while both languages coexist in the same solution.</p> </div> <div class="schema-faq-section" id="faq-vbdead-en-4"><strong class="schema-faq-question"><strong>Will VB.NET stop working in future .NET versions?</strong></strong> <p class="schema-faq-answer">Microsoft has committed to keeping VB.NET compiling and running on new .NET versions. Your existing code will not suddenly break. But you will miss out on new APIs and frameworks that are C#-only, which limits what you can build over time.</p> </div> <div class="schema-faq-section" id="faq-vbdead-en-5"><strong class="schema-faq-question"><strong>Is VB.NET good for beginners?</strong></strong> <p class="schema-faq-answer">Yes, VB.NET&#8217;s English-like syntax makes it one of the easiest languages to start with. Code like <code>If x > 5 Then</code> reads like a sentence. But plan to move to C# once you understand the basics, as VB.NET offers limited career growth.</p> </div> </div>



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



<p>Visual Basic .NET is not dead, but it is fading. Microsoft maintains it for compatibility, not for innovation. The community is shrinking, new frameworks skip it entirely, and the job market overwhelmingly favors C#. If you have existing VB.NET code, keep maintaining it. If you are starting fresh, go with C#. And if VB.NET is what got you into programming, be thankful for it and move forward. For hands-on VB.NET content, see the <a href="https://robbelroot.de/blog/vbnet-timer-en/"><strong>VB.NET Timer guide</strong></a> or the <a href="https://robbelroot.de/blog/vbnet-list-en/"><strong>VB.NET List guide</strong></a>.</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/is-visual-basic-dead/">Is Visual Basic Dead? The Real State of VB.NET (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/is-visual-basic-dead/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Ist Visual Basic tot? Der echte Stand von VB.NET (2026)</title>
		<link>https://robbelroot.de/blog/ist-visual-basic-tot/</link>
					<comments>https://robbelroot.de/blog/ist-visual-basic-tot/#respond</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Thu, 09 Apr 2026 13:14:19 +0000</pubDate>
				<category><![CDATA[Legacy-Modernisierung]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=20501</guid>

					<description><![CDATA[<p>Ist Visual Basic tot? Wenn man nur Google Trends betrachtet, scheint die Antwort klar. Aber als freiberuflicher Entwickler, der regelmäßig VB.NET-Aufträge bekommt, ist das Bild differenzierter. VB.NET befindet sich im Wartungsmodus, Microsoft wird keine neuen Features mehr hinzufügen und die Community schrumpft. Aber es kompiliert, es läuft und es bringt &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/ist-visual-basic-tot/">Ist Visual Basic tot? Der echte Stand von VB.NET (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p><strong>Ist Visual Basic tot?</strong> Wenn man nur Google Trends betrachtet, scheint die Antwort klar. Aber als freiberuflicher Entwickler, der regelmäßig VB.NET-Aufträge bekommt, ist das Bild differenzierter. VB.NET befindet sich im Wartungsmodus, Microsoft wird keine neuen Features mehr hinzufügen und die Community schrumpft. Aber es kompiliert, es läuft und es bringt noch Geld ein. Dieser Artikel zeigt den aktuellen Stand von VB.NET in 2026 mit echten Daten, Microsofts offizieller Position, wer es noch nutzt und ob es sich lohnt Zeit zu investieren.</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;">VB.NET-Projekt?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Brauchst du Hilfe mit einer VB.NET-Anwendung?</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;">Ich entwickle seit über 17 Jahren professionell in VB.NET und C#. Von Legacy-Wartung bis zum kompletten Rewrite kann ich helfen.</p>
    
    <div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;">

            <a href="https://robbelroot.de/kontakt/"
         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'"
      >→ Projekt anfragen</a>
      
      
    </div>
  </div>
</div>
	





<h2 class="wp-block-heading">Die kurze Antwort</h2>



<p>VB.NET ist nicht tot in dem Sinne, dass es aufhört zu funktionieren. Dein vorhandener Code kompiliert und läuft auf .NET 8, .NET 9 und darüber hinaus. Aber es befindet sich effektiv im <strong>Wartungsmodus</strong>: keine neuen Sprachfeatures, keine neuen Frameworks wie Blazor oder MAUI und eine schrumpfende Entwickler-Community. Wenn du ein laufendes VB.NET-Projekt hast, wird es weiter laufen. Wenn du etwas Neues startest, wähle C#.</p>



<h2 class="wp-block-heading">Microsofts offizielle Position</h2>



<p>2020 hat Microsoft offiziell angekündigt, dass VB.NET <strong>keine neuen Sprachfeatures</strong> mehr erhalten wird. Die Sprache wird weiterhin in .NET unterstützt (einschließlich .NET 8 und .NET 9), aber nur für Bugfixes und Kompatibilität. Neue Frameworks und APIs sind C#-exklusiv:</p>



<ul class="wp-block-list">
<li><strong>Blazor</strong>: nur C#</li>



<li><strong>.NET MAUI</strong>: nur C#</li>



<li><strong>Minimal APIs</strong>: nur C#</li>



<li><strong>Source Generators</strong>: nur C#</li>



<li><strong>WinForms / WPF</strong>: weiterhin mit VB.NET nutzbar</li>



<li><strong>Konsolen-Apps</strong>: weiterhin mit VB.NET nutzbar</li>
</ul>



<p>Das bedeutet: VB.NET ist heute nicht &#8222;tot&#8220;, aber es befindet sich auf einem klaren Weg in die Bedeutungslosigkeit für neue Projekte. Microsoft pflegt es, damit bestehende Codebasen weiter funktionieren, nicht weil sie eine Zukunft darin sehen.</p>



<h2 class="wp-block-heading">Nutzungsdaten: Google Trends und echte Zahlen</h2>



<p>Google Trends zeigt ein deutliches Bild. Vergleicht man &#8222;Visual Basic .NET&#8220;, &#8222;VB.NET&#8220; und &#8222;C#&#8220; über die letzten 12 Monate weltweit, registriert VB.NET kaum noch. Das Interesse sinkt seit Jahren stetig.</p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://robbelroot.de/wp-content/uploads/2024/01/vbnet-dead-google-trends-2026.png" alt="Google Trends Vergleich zeigt sinkendes VB.NET-Interesse gegenüber C# weltweit in 2026"/><figcaption class="wp-element-caption">Google Trends: Visual Basic .NET vs C# vs VB.NET Interesse weltweit (März 2026)</figcaption></figure>
</div>


<p>Aber Google Trends ist nicht die ganze Geschichte. Als freiberuflicher .NET-Entwickler erhalte ich weiterhin regelmäßig VB.NET-Projektanfragen. Betrachtet man meine eingehenden Programmieraufträge nach Sprache über die letzten Jahre, macht VB.NET einen signifikanten Anteil der .NET-bezogenen Arbeit aus:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://robbelroot.de/wp-content/uploads/2024/01/Incoming-programming-jobs-by-language-Is-VB.NET-dead.png" alt="Kreisdiagramm mit eingehenden Programmieraufträgen nach Sprache inklusive VB.NET C# und PHP"/><figcaption class="wp-element-caption">Eingehende Programmieraufträge nach Sprache</figcaption></figure>
</div>


<p>Die Anfragen sind in meiner Nische überraschend ausgewogen zwischen VB.NET und C#. Das bedeutet nicht, dass VB.NET global floriert, aber es zeigt, dass <strong>echte Nachfrage noch existiert</strong>, besonders für die Wartung und Erweiterung von Legacy-Anwendungen.</p>



<h2 class="wp-block-heading">Wer nutzt VB.NET noch</h2>



<p>Nach über 17 Jahren in diesem Bereich, im Austausch mit YouTube-Zuschauern, Website-Besuchern und Kunden, kann ich ein recht klares Bild zeichnen, wer noch VB.NET-Code schreibt:</p>



<ul class="wp-block-list">
<li><strong>Hobby-Entwickler und Autodidakten</strong>: Menschen, die VB.NET vor Jahren gelernt haben und kleine Tools für den persönlichen Gebrauch bauen oder ihren Arbeitsalltag automatisieren</li>



<li><strong>Unternehmen mit Legacy-Codebasen</strong>: Firmen, die WinForms- oder WPF-Anwendungen betreiben, die vor 10-15 Jahren gebaut wurden und immer noch funktionieren und Umsatz generieren</li>



<li><strong>Automatisierungs- und Messprojekte</strong>: VB.NET ist verbreitet bei industrieller Automatisierung, Datenerfassung und Messwerkzeugen</li>



<li><strong>Excel/Office-Integration</strong>: VBA-Entwickler, die für komplexere Tooling-Aufgaben zu VB.NET gewechselt sind</li>
</ul>



<p>Ehrlich gesagt: Die meisten VB.NET-Entwickler, denen ich begegne, sind über 50 und viele arbeiten auf Hobby-Niveau. Clean Code, Unit Tests und SOLID-Prinzipien sind die Ausnahme, nicht die Regel. Das ist aber nicht VB.NETs Schuld als Sprache. Es ist zu sauberem, professionellem Code fähig. Aber die verbleibende Community priorisiert tendenziell &#8222;es funktioniert&#8220; über Wartbarkeit. Wenn du unabhängig von der Sprache besseren Code schreiben willst, sieh dir meinen <a href="https://robbelroot.de/blog/clean-code-in-der-praxis/"><strong>Clean Code Guide</strong></a> an.</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;">Legacy-Code?</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-Anwendung die modernisiert werden muss?</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;">Ich warte, erweitere und modernisiere VB.NET-Anwendungen. Ob schnelle Reparatur oder komplette Migration zu C#, ich habe es vielfach gemacht.</p>
    
    <div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;">

            <a href="https://robbelroot.de/kontakt/"
         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'"
      >→ Projekt anfragen</a>
      
      
    </div>
  </div>
</div>
	


<h2 class="wp-block-heading">Wofür VB.NET noch gut ist</h2>



<p>Trotz des abnehmenden Trends hat VB.NET legitime Einsatzbereiche:</p>



<ul class="wp-block-list">
<li><strong>Programmieren lernen</strong>: Die englisch-ähnliche Syntax macht es zu einer der zugänglichsten Sprachen für Einsteiger. <code>If x > 5 Then</code> liest sich wie ein Satz. Für jemanden, der noch nie Code geschrieben hat, senkt das die Einstiegshürde erheblich.</li>



<li><strong>Bestehende Anwendungen warten</strong>: Wenn du eine laufende WinForms-App mit 100.000 Zeilen VB.NET hast, macht ein Rewrite in C# nur um des Rewrite willen keinen geschäftlichen Sinn. Pflege sie, erweitere sie und migriere inkrementell, wenn nötig.</li>



<li><strong>Kleine interne Tools</strong>: Schnelle Automatisierungs-Tools, Datenkonverter oder Reporting-Werkzeuge, bei denen der Entwickler bereits VB.NET kennt.</li>



<li><strong>Prototyping</strong>: VB.NETs WinForms-Designer ist immer noch eine der schnellsten Möglichkeiten, eine UI zum Testen einer Idee zusammenzubauen.</li>
</ul>



<p>VB.NET ist durchaus in der Lage für professionelle Arbeit. Siehe zum Beispiel wie man ein <a href="https://robbelroot.de/blog/vbnet-dapper/"><strong>VB.NET Dapper Setup</strong></a> nutzt oder wie man <a href="https://robbelroot.de/blog/vbnet-textdatei-schreiben/"><strong>Textdateien in VB.NET schreibt</strong></a>.</p>



<h2 class="wp-block-heading">Warum du lieber C# lernen solltest</h2>



<p>Wenn du frisch anfängst oder deinen nächsten Schritt planst, ist die Antwort C#. Nicht weil VB.NET schlecht ist, sondern weil das Ökosystem weitergezogen ist:</p>



<ul class="wp-block-list">
<li><strong>Jedes neue .NET-Feature</strong> zielt zuerst auf C# ab (und oft ausschließlich)</li>



<li><strong>Arbeitsmarkt</strong>: C#-Stellenangebote übertreffen VB.NET um den Faktor 20+</li>



<li><strong>Community und Ressourcen</strong>: Stack-Overflow-Antworten, Tutorials, NuGet-Pakete und Blogposts zielen überwiegend auf C#</li>



<li><strong>Cross-Platform</strong>: .NET MAUI, Blazor, ASP.NET Minimal APIs sind alle C#-exklusiv</li>



<li><strong>Karrierewachstum</strong>: C#-Kenntnisse öffnen Türen zu Web, Mobile, Cloud und Game Development (Unity)</li>
</ul>



<p>Die gute Nachricht: Wenn du VB.NET kannst, ist C# lernen nicht so schwer. Das .NET Framework ist dasselbe. Die Syntax ist anders, aber die Konzepte (Klassen, Events, LINQ, Async/Await) übertragen sich direkt. Viele Muster die du bereits aus VB.NET kennst funktionieren identisch. Zum Beispiel lässt sich <a href="https://robbelroot.de/blog/vbnet-addhandler/"><strong>Event-Handling mit AddHandler</strong></a> in VB.NET direkt auf C#&#8217;s <code>+=</code>-Operator übertragen.</p>



<h2 class="wp-block-heading">Meine persönliche Einschätzung</h2>



<p>Ich habe mit etwa 13 Jahren angefangen, mit VB.NET zu programmieren. Vorher hatte ich C und C++ ausprobiert und aus Frustration aufgegeben. VB.NETs zugängliche Syntax hat mir den Einstieg ermöglicht und ich habe die Welt der Softwareentwicklung nie wieder verlassen. Heute arbeite ich hauptsächlich in C#, aber VB.NET ist immer noch Teil meines regelmäßigen Werkzeugkastens.</p>



<p>Ich finde auch, dass VB.NET unfair behandelt wird. Die Sprache selbst ist nicht das Problem. Sie unterstützt Clean Code, SOLID-Prinzipien und saubere Architektur. Das Problem ist, dass sie Einsteiger anzieht, die nie über &#8222;es funktioniert&#8220;-Code hinauskommen. Das gibt der Sprache einen schlechten Ruf, den sie nicht vollständig verdient.</p>



<p>Wenn mich jemand fragt &#8222;Soll ich mit VB.NET oder C# anfangen?&#8220;, ist meine Antwort immer C#. Aber wenn jemand fragt &#8222;Ist VB.NET tot?&#8220;, ist meine ehrliche Antwort: Es schwindet langsam, aber es ist noch nicht tot. Und wenn VB.NET lernen der Weg ist, der dich zum Programmieren bringt, dann hat es seinen Zweck erfüllt.</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;">Umstieg geplant?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Ich helfe VB.NET-Entwicklern beim Wechsel zu C#</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;">Mit über 17 Jahren Erfahrung in beiden Sprachen biete ich 1-zu-1-Unterricht und projektbasiertes Coaching an. Ob du Legacy-VB-Code modernisieren oder C# von Grund auf lernen willst.</p>
    
    <div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;">

            <a href="https://robbelroot.de/kontakt/"
         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'"
      >→ Projekt anfragen</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-vbdead-de-1"><strong class="schema-faq-question"><strong>Wird VB.NET noch von Microsoft unterstützt?</strong></strong> <p class="schema-faq-answer">Ja, VB.NET wird in .NET 8 und .NET 9 weiterhin für Bugfixes und Kompatibilität unterstützt. Microsoft wird jedoch keine neuen Sprachfeatures mehr hinzufügen. Neue Frameworks wie Blazor, MAUI und Minimal APIs sind C#-exklusiv.</p> </div> <div class="schema-faq-section" id="faq-vbdead-de-2"><strong class="schema-faq-question"><strong>Sollte ich 2026 VB.NET oder C# lernen?</strong></strong> <p class="schema-faq-answer">C#, ohne Frage. Jedes neue .NET-Feature zielt auf C# ab, der Arbeitsmarkt ist 20x größer und Frameworks wie Blazor und MAUI funktionieren nur mit C#. VB.NET ist in Ordnung für die Wartung bestehender Apps, aber nicht für Neuprojekte.</p> </div> <div class="schema-faq-section" id="faq-vbdead-de-3"><strong class="schema-faq-question"><strong>Kann ich mein VB.NET-Projekt nach C# konvertieren?</strong></strong> <p class="schema-faq-answer">Ja. Das .NET Framework ist unter der Haube dasselbe. Tools wie der <a href="https://converter.telerik.com/">Telerik Code Converter</a> können einen ersten Durchlauf machen, aber komplexe Projekte brauchen manuelle Überprüfung. Viele Entwickler migrieren inkrementell, ein Modul nach dem anderen, während beide Sprachen in derselben Solution koexistieren.</p> </div> <div class="schema-faq-section" id="faq-vbdead-de-4"><strong class="schema-faq-question"><strong>Wird VB.NET in zukünftigen .NET-Versionen aufhören zu funktionieren?</strong></strong> <p class="schema-faq-answer">Microsoft hat zugesagt, VB.NET auf neuen .NET-Versionen kompilier- und lauffähig zu halten. Dein vorhandener Code wird nicht plötzlich brechen. Aber du wirst neue APIs und Frameworks verpassen, die C#-exklusiv sind, was langfristig einschränkt, was du bauen kannst.</p> </div> <div class="schema-faq-section" id="faq-vbdead-de-5"><strong class="schema-faq-question"><strong>Ist VB.NET gut für Anfänger?</strong></strong> <p class="schema-faq-answer">Ja, VB.NETs englisch-ähnliche Syntax macht es zu einer der einfachsten Sprachen für den Einstieg. Code wie <code>If x > 5 Then</code> liest sich wie ein Satz. Plane aber den Umstieg auf C#, sobald du die Grundlagen verstehst, da VB.NET eingeschränkte Karrieremöglichkeiten bietet.</p> </div> </div>



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



<p>Visual Basic .NET ist nicht tot, aber es schwindet. Microsoft pflegt es für Kompatibilität, nicht für Innovation. Die Community schrumpft, neue Frameworks überspringen es komplett und der Arbeitsmarkt favorisiert C# überwältigend. Wenn du bestehenden VB.NET-Code hast, pflege ihn weiter. Wenn du neu anfängst, nimm C#. Und wenn VB.NET dich zum Programmieren gebracht hat, sei dankbar dafür und geh weiter. Für praktische VB.NET-Inhalte, siehe den <a href="https://robbelroot.de/blog/vbnet-timer/"><strong>VB.NET Timer Guide</strong></a> oder den <a href="https://robbelroot.de/blog/vbnet-list/"><strong>VB.NET List Guide</strong></a>.</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/ist-visual-basic-tot/">Ist Visual Basic tot? Der echte Stand von VB.NET (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/ist-visual-basic-tot/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>VB.NET WhatsApp Nachricht senden per Cloud API (2026)</title>
		<link>https://robbelroot.de/blog/vbnet-whatsapp-nachricht-senden/</link>
					<comments>https://robbelroot.de/blog/vbnet-whatsapp-nachricht-senden/#respond</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Wed, 08 Apr 2026 22:30:59 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Visual Basic .NET]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=20494</guid>

					<description><![CDATA[<p>Du kannst WhatsApp-Nachrichten aus VB.NET senden, indem du die offizielle WhatsApp Cloud API mit einem einfachen HttpClient-Request nutzt. Keine externe Bibliothek nötig. Dieser Guide behandelt Setup, Text-Nachrichten, Template-Nachrichten, API-Antworten, Massenversand und eine Twilio-Alternative mit vollständigen Code-Beispielen. Was du brauchst Bevor du Code schreibst, brauchst du drei Dinge von Meta: Meta &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-whatsapp-nachricht-senden/">VB.NET WhatsApp Nachricht senden per Cloud API (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Du kannst <strong>WhatsApp-Nachrichten aus VB.NET senden</strong>, indem du die offizielle WhatsApp Cloud API mit einem einfachen <code>HttpClient</code>-Request nutzt. Keine externe Bibliothek nötig. Dieser Guide behandelt Setup, Text-Nachrichten, Template-Nachrichten, API-Antworten, Massenversand und eine Twilio-Alternative mit vollständigen Code-Beispielen.</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;">.NET-Hilfe gesucht?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Du baust ein Benachrichtigungssystem?</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;">Ich entwickle seit über 17 Jahren professionell in VB.NET und C#. Von WhatsApp-Integrationen bis zur kompletten Desktop-Lösung kann ich helfen.</p>
    
    <div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;">

            <a href="https://robbelroot.de/kontakt/"
         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'"
      >→ Projekt anfragen</a>
      
      
    </div>
  </div>
</div>
	





<h2 class="wp-block-heading">Was du brauchst</h2>



<p>Bevor du Code schreibst, brauchst du drei Dinge von Meta:</p>



<ol class="wp-block-list">
<li><strong>Meta Business Account</strong> mit einer registrierten App auf <a href="https://developers.facebook.com/" target="_blank" rel="noopener">developers.facebook.com</a></li>



<li><strong>Phone Number ID</strong> aus dem WhatsApp-Bereich in deinem App-Dashboard</li>



<li><strong>Access Token</strong> (temporär zum Testen, permanent über System User für Produktion)</li>
</ol>



<p>Meta stellt eine kostenlose Test-Rufnummer und fünf Test-Empfänger bereit. Du kannst während der Entwicklung echte Nachrichten ohne Kosten senden.</p>



<h2 class="wp-block-heading">So funktioniert die WhatsApp Cloud API</h2>



<p>Die WhatsApp Cloud API ist eine REST API, die von Meta gehostet wird. Deine VB.NET-Anwendung sendet einen HTTP-POST-Request mit JSON-Body an Metas Server. Meta liefert die Nachricht dann an die WhatsApp-App des Empfängers. Der Ablauf:</p>



<ol class="wp-block-list">
<li>Deine App sendet einen POST-Request an <code>https://graph.facebook.com/v20.0/{phone_number_id}/messages</code></li>



<li>Meta prüft deinen Token, die Rufnummer und das Nachrichtenformat</li>



<li>Meta stellt die Nachricht über WhatsApp-Server zu</li>



<li>Du erhältst eine JSON-Antwort mit der Nachrichten-ID oder einem Fehler</li>
</ol>



<p>Eine wichtige Regel: Du kannst nur <strong>Template-Nachrichten</strong> an Nutzer senden, die dir in den letzten 24 Stunden nicht geschrieben haben. Freitext-Nachrichten sind nur innerhalb eines 24-Stunden-Gesprächsfensters erlaubt. Für die meisten Benachrichtigungs-Szenarien (Bestellbestätigungen, Alerts, Erinnerungen) sind Template-Nachrichten der richtige Weg.</p>



<h2 class="wp-block-heading">Textnachricht senden</h2>



<p>Das einfachste Beispiel. Es sendet eine Klartext-Nachricht an einen einzelnen Empfänger innerhalb eines aktiven Gesprächsfensters:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Imports System.Net.Http
Imports System.Text

Private Async Function SendWhatsAppMessage(recipientPhone As String, message As String) As Task(Of Boolean)
    Dim phoneNumberId As String = "YOUR_PHONE_NUMBER_ID"
    Dim accessToken As String = "YOUR_ACCESS_TOKEN"
    Dim url As String = $"https://graph.facebook.com/v20.0/{phoneNumberId}/messages"

    Dim json As String = "{" &amp;
        """messaging_product"": ""whatsapp""," &amp;
        """to"": """ &amp; recipientPhone &amp; """," &amp;
        """type"": ""text""," &amp;
        """text"": {""body"": """ &amp; message &amp; """}" &amp;
        "}"

    Using client As New HttpClient()
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " &amp; accessToken)
        Dim content As New StringContent(json, Encoding.UTF8, "application/json")
        Dim response = Await client.PostAsync(url, content)
        Return response.IsSuccessStatusCode
    End Using
End Function</pre>



<p>Aufruf per Button-Klick oder beliebigem Event-Handler:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Async Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
    Dim success = Await SendWhatsAppMessage("491234567890", "Deine Bestellung wurde versendet.")

    If success Then
        lblStatus.Text = "Nachricht gesendet."
    Else
        lblStatus.Text = "Nachricht konnte nicht gesendet werden."
    End If
End Sub</pre>



<p>Die Rufnummer muss die Landesvorwahl ohne Pluszeichen oder führende Nullen enthalten. Für eine deutsche Nummer wie +49 123 4567890 verwendest du <code>491234567890</code>.</p>



<h2 class="wp-block-heading">Template-Nachricht senden</h2>



<p>Template-Nachrichten sind vorab genehmigte Nachrichtenformate, die du in deinem Meta Business Dashboard erstellst. Sie sind erforderlich, wenn du die erste Nachricht an einen Nutzer sendest oder außerhalb des 24-Stunden-Fensters kommunizierst:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Async Function SendTemplateMessage(recipientPhone As String, templateName As String) As Task(Of Boolean)
    Dim phoneNumberId As String = "YOUR_PHONE_NUMBER_ID"
    Dim accessToken As String = "YOUR_ACCESS_TOKEN"
    Dim url As String = $"https://graph.facebook.com/v20.0/{phoneNumberId}/messages"

    Dim json As String = "{" &amp;
        """messaging_product"": ""whatsapp""," &amp;
        """to"": """ &amp; recipientPhone &amp; """," &amp;
        """type"": ""template""," &amp;
        """template"": {" &amp;
            """name"": """ &amp; templateName &amp; """," &amp;
            """language"": {""code"": ""de""}" &amp;
        "}" &amp;
        "}"

    Using client As New HttpClient()
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " &amp; accessToken)
        Dim content As New StringContent(json, Encoding.UTF8, "application/json")
        Dim response = Await client.PostAsync(url, content)
        Return response.IsSuccessStatusCode
    End Using
End Function</pre>



<p>Meta stellt ein Standard-Template namens <code>hello_world</code> zum Testen bereit. Eigene Templates erstellst du im WhatsApp-Manager-Bereich deines Meta Business Dashboards. Templates können Variablen wie <code>{{1}}</code> enthalten, die du beim Senden mit dynamischen Inhalten füllst.</p>



<h2 class="wp-block-heading">Template-Nachricht mit Variablen</h2>



<p>Die meisten echten Templates enthalten Platzhalter für Kundennamen, Bestellnummern oder Termine. So sendest du ein Template mit variablen Parametern:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Async Function SendOrderConfirmation(phone As String, customerName As String, orderId As String) As Task(Of Boolean)
    Dim phoneNumberId As String = "YOUR_PHONE_NUMBER_ID"
    Dim accessToken As String = "YOUR_ACCESS_TOKEN"
    Dim url As String = $"https://graph.facebook.com/v20.0/{phoneNumberId}/messages"

    ' Template "bestellbestaetigung" mit zwei Body-Parametern
    Dim json As String = "{" &amp;
        """messaging_product"": ""whatsapp""," &amp;
        """to"": """ &amp; phone &amp; """," &amp;
        """type"": ""template""," &amp;
        """template"": {" &amp;
            """name"": ""bestellbestaetigung""," &amp;
            """language"": {""code"": ""de""}," &amp;
            """components"": [{" &amp;
                """type"": ""body""," &amp;
                """parameters"": [" &amp;
                    "{""type"": ""text"", ""text"": """ &amp; customerName &amp; """}," &amp;
                    "{""type"": ""text"", ""text"": """ &amp; orderId &amp; """}" &amp;
                "]" &amp;
            "}]" &amp;
        "}" &amp;
        "}"

    Using client As New HttpClient()
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " &amp; accessToken)
        Dim content As New StringContent(json, Encoding.UTF8, "application/json")
        Dim response = Await client.PostAsync(url, content)
        Return response.IsSuccessStatusCode
    End Using
End Function</pre>



<p>Die Parameter füllen die <code>{{1}}</code>-, <code>{{2}}</code>-Platzhalter in deinem Template der Reihe nach. Stelle sicher, dass die Anzahl der Parameter mit den Erwartungen des Templates übereinstimmt.</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;">Projekt in Planung?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Brauchst du ein fertiges Benachrichtigungssystem?</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;">Von WhatsApp-Alerts bis zur kompletten Desktop-App mit Datenbankanbindung. Ich entwerfe Software, die hält. Lass uns über dein Projekt sprechen.</p>
    
    <div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;">

            <a href="https://robbelroot.de/kontakt/"
         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'"
      >→ Projekt anfragen</a>
      
      
    </div>
  </div>
</div>
	


<h2 class="wp-block-heading">API-Antwort auswerten</h2>



<p>Eine erfolgreiche Antwort enthält ein JSON-Objekt mit der Nachrichten-ID. Ein Fehler gibt ein strukturiertes Fehlerobjekt zurück. So liest du beides aus:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Async Function SendAndLog(recipientPhone As String, message As String) As Task
    Dim phoneNumberId As String = "YOUR_PHONE_NUMBER_ID"
    Dim accessToken As String = "YOUR_ACCESS_TOKEN"
    Dim url As String = $"https://graph.facebook.com/v20.0/{phoneNumberId}/messages"

    Dim json As String = "{" &amp;
        """messaging_product"": ""whatsapp""," &amp;
        """to"": """ &amp; recipientPhone &amp; """," &amp;
        """type"": ""text""," &amp;
        """text"": {""body"": """ &amp; message &amp; """}" &amp;
        "}"

    Using client As New HttpClient()
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " &amp; accessToken)
        Dim content As New StringContent(json, Encoding.UTF8, "application/json")
        Dim response = Await client.PostAsync(url, content)
        Dim body = Await response.Content.ReadAsStringAsync()

        If response.IsSuccessStatusCode Then
            ' body enthält: {"messaging_product":"whatsapp","contacts":[...],"messages":[{"id":"wamid.xxx"}]}
            Console.WriteLine("Gesendet. Antwort: " &amp; body)
        Else
            ' body enthält: {"error":{"message":"...","type":"...","code":100,...}}
            Console.WriteLine("Fehler " &amp; response.StatusCode.ToString() &amp; ": " &amp; body)
        End If
    End Using
End Function</pre>



<p>Für Produktionsanwendungen speichere die Antwort in einer Log-Datei zum Debuggen. Siehe den <a href="https://robbelroot.de/blog/vbnet-textdatei-schreiben/"><strong>VB.NET Textdatei schreiben Guide</strong></a> für Logging-Muster.</p>



<h2 class="wp-block-heading">An mehrere Empfänger senden</h2>



<p>Die WhatsApp API akzeptiert einen Empfänger pro Request. Um an mehrere Nummern zu senden, iterierst du über eine <a href="https://robbelroot.de/blog/vbnet-list/"><strong>VB.NET List</strong></a> von Rufnummern:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Async Function SendToMultiple(phones As List(Of String), message As String) As Task
    Dim successCount As Integer = 0
    Dim failCount As Integer = 0

    For Each phone In phones
        Dim success = Await SendWhatsAppMessage(phone, message)

        If success Then
            successCount += 1
        Else
            failCount += 1
        End If

        ' Rate-Limit einhalten: max 80 Nachrichten pro Sekunde
        Await Task.Delay(50)
    Next

    Console.WriteLine($"Gesendet: {successCount}, Fehlgeschlagen: {failCount}")
End Function</pre>



<p>Das <code>Task.Delay(50)</code> fügt eine kleine Pause zwischen den Requests ein, um innerhalb des API-Rate-Limits zu bleiben. Bei großen Batches (Tausende von Nachrichten) solltest du die Nachrichten in eine Queue stellen und im Hintergrund verarbeiten.</p>



<h2 class="wp-block-heading">Zugangsdaten sicher speichern</h2>



<p>Schreibe deinen Access Token nie fest in den Quellcode. Für Desktop-Anwendungen speicherst du Zugangsdaten in einer externen Config-Datei oder Umgebungsvariablen:</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="">' Aus App.config oder Umgebungsvariable lesen
Dim accessToken As String = Environment.GetEnvironmentVariable("WHATSAPP_TOKEN")
Dim phoneNumberId As String = Environment.GetEnvironmentVariable("WHATSAPP_PHONE_ID")

If String.IsNullOrEmpty(accessToken) OrElse String.IsNullOrEmpty(phoneNumberId) Then
    MessageBox.Show("WhatsApp-Zugangsdaten nicht konfiguriert.", "Konfigurationsfehler",
        MessageBoxButtons.OK, MessageBoxIcon.Error)
    Return
End If</pre>



<p>Setze Umgebungsvariablen auf der Maschine, auf der deine App läuft, oder verwende <code>My.Settings</code> mit benutzerbezogenen Einstellungen für Einzelbenutzer-Konfiguration.</p>



<h2 class="wp-block-heading">Twilio als Alternative</h2>



<p>Wenn du ein einfacheres SDK gegenüber rohen HTTP-Requests bevorzugst, bietet Twilio eine WhatsApp-Integration mit einem .NET-NuGet-Paket. Installiere <code>Twilio</code> via NuGet:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Imports Twilio
Imports Twilio.Rest.Api.V2010.Account

' Einmalig beim App-Start initialisieren
TwilioClient.Init("YOUR_ACCOUNT_SID", "YOUR_AUTH_TOKEN")

' Nachricht senden
Dim msg = MessageResource.Create(
    body:="Deine Bestellung wurde versendet.",
    from:=New Twilio.Types.PhoneNumber("whatsapp:+14155238886"),
    [to]:=New Twilio.Types.PhoneNumber("whatsapp:+491234567890")
)

Console.WriteLine("Message SID: " &amp; msg.Sid)</pre>



<p>Twilio kostet Geld pro Nachricht, übernimmt aber Rate-Limiting, Retries und Zustellverfolgung für dich. Die direkte Meta API ist kostenlos (du zahlst nur für Conversations über das Freitier hinaus), aber du machst alles selbst.</p>



<h2 class="wp-block-heading">Häufige Fehler</h2>



<h3 class="wp-block-heading">Freitext außerhalb des 24-Stunden-Fensters senden</h3>



<p>Die API gibt Fehlercode 131047 zurück, wenn du eine Textnachricht an jemanden sendest, der dir in den letzten 24 Stunden nicht geschrieben hat. Verwende stattdessen eine Template-Nachricht. Template-Nachrichten funktionieren jederzeit und sind der Standard-Ansatz für Benachrichtigungen.</p>



<h3 class="wp-block-heading">Falsches Rufnummernformat</h3>



<p>Die API erwartet die vollständige internationale Nummer ohne Pluszeichen, Leerzeichen oder Bindestriche. <code>491234567890</code> ist korrekt. <code>+49 123 456 7890</code>, <code>01234567890</code> oder <code>0049-123-4567890</code> schlagen fehl. Bereinige alle Formatierung vor dem Senden:</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 cleanPhone = phone.Replace("+", "").Replace(" ", "").Replace("-", "")</pre>



<h3 class="wp-block-heading">Access Token fest im Code</h3>



<p>Temporäre Tokens laufen nach 24 Stunden ab. Wenn du einen fest einträgst und vergisst ihn zu aktualisieren, hört deine App leise auf zu senden. Verwende für Produktion einen permanenten System-User-Token und speichere ihn in Umgebungsvariablen oder einer sicheren Config-Datei, nie im Quellcode.</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;">Interessiert?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Erfahrenen .NET-Entwickler gesucht?</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;">Ich übernehme dein Projekt, von API-Integrationen bis zur kompletten Desktop-Anwendung. Schreib mir einfach eine Nachricht.</p>
    
    <div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;">

            <a href="https://robbelroot.de/kontakt/"
         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'"
      >→ Projekt anfragen</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-whatsapp-de-1"><strong class="schema-faq-question"><strong>Ist die WhatsApp Business API kostenlos?</strong></strong> <p class="schema-faq-answer">Meta bietet 1.000 kostenlose Service-Conversations pro Monat. Darüber hinaus zahlst du pro Conversation (nicht pro Nachricht). Template-Nachrichten für Benachrichtigungen kosten eine kleine Gebühr pro Conversation, abhängig vom Land. Entwicklung und Tests mit der Sandbox-Nummer sind kostenlos.</p> </div> <div class="schema-faq-section" id="faq-whatsapp-de-2"><strong class="schema-faq-question"><strong>Kann ich WhatsApp-Nachrichten aus VB.NET ohne offizielle API senden?</strong></strong> <p class="schema-faq-answer">Technisch könntest du WhatsApp Web mit Selenium automatisieren, aber das verstößt gegen die WhatsApp-Nutzungsbedingungen und kann zur Sperrung deiner Nummer führen. Die offizielle Cloud API oder ein Anbieter wie Twilio sind die einzigen zuverlässigen und konformen Optionen.</p> </div> <div class="schema-faq-section" id="faq-whatsapp-de-3"><strong class="schema-faq-question"><strong>Was ist der Unterschied zwischen Textnachricht und Template-Nachricht?</strong></strong> <p class="schema-faq-answer">Eine Textnachricht ist frei formulierter Inhalt, den du nur während eines aktiven 24-Stunden-Gesprächsfensters senden kannst. Eine Template-Nachricht ist ein vorab genehmigtes Format, das in deinem Meta-Dashboard registriert ist und jederzeit gesendet werden kann, auch an Nutzer die dir nicht zuerst geschrieben haben.</p> </div> <div class="schema-faq-section" id="faq-whatsapp-de-4"><strong class="schema-faq-question"><strong>Brauche ich eine spezielle Rufnummer für die WhatsApp API?</strong></strong> <p class="schema-faq-answer">Du brauchst eine Rufnummer, die nicht bereits bei WhatsApp oder der WhatsApp Business App registriert ist. Meta stellt eine kostenlose Testnummer für die Entwicklung bereit. Für Produktion registrierst du eine dedizierte Business-Nummer im Meta Business Dashboard.</p> </div> <div class="schema-faq-section" id="faq-whatsapp-de-5"><strong class="schema-faq-question"><strong>Kann ich auch WhatsApp-Nachrichten in VB.NET empfangen?</strong></strong> <p class="schema-faq-answer">Ja, aber dafür brauchst du einen Webhook. Meta sendet eingehende Nachrichten an einen öffentlichen HTTPS-Endpunkt, den du konfigurierst. Für eine Desktop-VB.NET-App brauchst du eine Server-Komponente (ASP.NET oder eine Cloud-Funktion), die den Webhook empfängt und Nachrichten an deine App weiterleitet.</p> </div> </div>



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



<p>WhatsApp-Nachrichten aus VB.NET senden läuft über einen einzigen <code>HttpClient.PostAsync</code>-Aufruf an Metas Cloud API. Verwende Template-Nachrichten für Benachrichtigungen, speichere deinen Token sicher und bereinige Rufnummern vor dem Senden. Für einfachere Integration zu höheren Kosten gibt es Twilio als NuGet-Paket. Zum Loggen von API-Antworten in eine Datei, siehe den <a href="https://robbelroot.de/blog/vbnet-textdatei-schreiben/"><strong>VB.NET Textdatei schreiben Guide</strong></a>.</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-whatsapp-nachricht-senden/">VB.NET WhatsApp Nachricht senden per Cloud API (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vbnet-whatsapp-nachricht-senden/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>VB.NET Send WhatsApp Message via Cloud API (2026)</title>
		<link>https://robbelroot.de/blog/vbnet-send-whatsapp-message/</link>
					<comments>https://robbelroot.de/blog/vbnet-send-whatsapp-message/#respond</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Wed, 08 Apr 2026 22:30:55 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Visual Basic .NET (EN)]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=20495</guid>

					<description><![CDATA[<p>You can send WhatsApp messages from VB.NET using the official WhatsApp Cloud API and a simple HttpClient request. No third-party library required. This guide covers setup, sending text messages, template messages, handling responses, batch sending, and a Twilio alternative with complete code examples. What you need Before writing any code, &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-send-whatsapp-message/">VB.NET Send WhatsApp Message via Cloud API (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You can <strong>send WhatsApp messages from VB.NET</strong> using the official WhatsApp Cloud API and a simple <code>HttpClient</code> request. No third-party library required. This guide covers setup, sending text messages, template messages, handling responses, batch sending, and a Twilio alternative with complete code examples.</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 .NET help?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Building a notification system?</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 have been developing .NET applications professionally for over 17 years. From WhatsApp integrations to complete desktop solutions, I can help.</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 a project</a>
      
      
    </div>
  </div>
</div>
	





<h2 class="wp-block-heading">What you need</h2>



<p>Before writing any code, you need three things from Meta:</p>



<ol class="wp-block-list">
<li><strong>Meta Business Account</strong> with a registered app at <a href="https://developers.facebook.com/" target="_blank" rel="noopener">developers.facebook.com</a></li>



<li><strong>Phone Number ID</strong> from the WhatsApp section in your app dashboard</li>



<li><strong>Access Token</strong> (temporary for testing, permanent via System User for production)</li>
</ol>



<p>Meta provides a free test phone number and five test recipient numbers. You can send real messages during development without any cost.</p>



<h2 class="wp-block-heading">How the WhatsApp Cloud API works</h2>



<p>The WhatsApp Cloud API is a REST API hosted by Meta. Your VB.NET application sends an HTTP POST request with a JSON body to Meta&#8217;s servers. Meta then delivers the message to the recipient&#8217;s WhatsApp app. The flow is:</p>



<ol class="wp-block-list">
<li>Your app sends a POST request to <code>https://graph.facebook.com/v20.0/{phone_number_id}/messages</code></li>



<li>Meta validates your token, phone number, and message format</li>



<li>Meta delivers the message via WhatsApp servers</li>



<li>You receive a JSON response with the message ID or an error</li>
</ol>



<p>There is one important rule: you can only send <strong>template messages</strong> to users who have not messaged you in the last 24 hours. Free-form text messages are only allowed within a 24-hour conversation window. For most notification use cases (order confirmations, alerts, reminders), template messages are what you need.</p>



<h2 class="wp-block-heading">Sending a text message</h2>



<p>This is the simplest example. It sends a plain text message to a single recipient inside an active conversation window:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Imports System.Net.Http
Imports System.Text

Private Async Function SendWhatsAppMessage(recipientPhone As String, message As String) As Task(Of Boolean)
    Dim phoneNumberId As String = "YOUR_PHONE_NUMBER_ID"
    Dim accessToken As String = "YOUR_ACCESS_TOKEN"
    Dim url As String = $"https://graph.facebook.com/v20.0/{phoneNumberId}/messages"

    Dim json As String = "{" &amp;
        """messaging_product"": ""whatsapp""," &amp;
        """to"": """ &amp; recipientPhone &amp; """," &amp;
        """type"": ""text""," &amp;
        """text"": {""body"": """ &amp; message &amp; """}" &amp;
        "}"

    Using client As New HttpClient()
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " &amp; accessToken)
        Dim content As New StringContent(json, Encoding.UTF8, "application/json")
        Dim response = Await client.PostAsync(url, content)
        Return response.IsSuccessStatusCode
    End Using
End Function</pre>



<p>Call it from a button click or any event handler:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Async Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
    Dim success = Await SendWhatsAppMessage("491234567890", "Your order has been shipped.")

    If success Then
        lblStatus.Text = "Message sent."
    Else
        lblStatus.Text = "Failed to send message."
    End If
End Sub</pre>



<p>The phone number must include the country code without a plus sign or leading zeros. For a German number like +49 123 4567890, use <code>491234567890</code>.</p>



<h2 class="wp-block-heading">Sending a template message</h2>



<p>Template messages are pre-approved message formats that you create in your Meta Business dashboard. They are required for sending the first message to a user or for messages outside the 24-hour window:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Async Function SendTemplateMessage(recipientPhone As String, templateName As String) As Task(Of Boolean)
    Dim phoneNumberId As String = "YOUR_PHONE_NUMBER_ID"
    Dim accessToken As String = "YOUR_ACCESS_TOKEN"
    Dim url As String = $"https://graph.facebook.com/v20.0/{phoneNumberId}/messages"

    Dim json As String = "{" &amp;
        """messaging_product"": ""whatsapp""," &amp;
        """to"": """ &amp; recipientPhone &amp; """," &amp;
        """type"": ""template""," &amp;
        """template"": {" &amp;
            """name"": """ &amp; templateName &amp; """," &amp;
            """language"": {""code"": ""en_US""}" &amp;
        "}" &amp;
        "}"

    Using client As New HttpClient()
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " &amp; accessToken)
        Dim content As New StringContent(json, Encoding.UTF8, "application/json")
        Dim response = Await client.PostAsync(url, content)
        Return response.IsSuccessStatusCode
    End Using
End Function</pre>



<p>Meta provides a default template called <code>hello_world</code> for testing. Create your own templates in the WhatsApp Manager section of your Meta Business dashboard. Templates can include variables like <code>{{1}}</code> that you fill with dynamic content at send time.</p>



<h2 class="wp-block-heading">Template message with variables</h2>



<p>Most real templates include placeholders for customer names, order numbers, or dates. Here is how to send a template with variable parameters:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Async Function SendOrderConfirmation(phone As String, customerName As String, orderId As String) As Task(Of Boolean)
    Dim phoneNumberId As String = "YOUR_PHONE_NUMBER_ID"
    Dim accessToken As String = "YOUR_ACCESS_TOKEN"
    Dim url As String = $"https://graph.facebook.com/v20.0/{phoneNumberId}/messages"

    ' Template "order_confirmation" with two body parameters
    Dim json As String = "{" &amp;
        """messaging_product"": ""whatsapp""," &amp;
        """to"": """ &amp; phone &amp; """," &amp;
        """type"": ""template""," &amp;
        """template"": {" &amp;
            """name"": ""order_confirmation""," &amp;
            """language"": {""code"": ""en_US""}," &amp;
            """components"": [{" &amp;
                """type"": ""body""," &amp;
                """parameters"": [" &amp;
                    "{""type"": ""text"", ""text"": """ &amp; customerName &amp; """}," &amp;
                    "{""type"": ""text"", ""text"": """ &amp; orderId &amp; """}" &amp;
                "]" &amp;
            "}]" &amp;
        "}" &amp;
        "}"

    Using client As New HttpClient()
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " &amp; accessToken)
        Dim content As New StringContent(json, Encoding.UTF8, "application/json")
        Dim response = Await client.PostAsync(url, content)
        Return response.IsSuccessStatusCode
    End Using
End Function</pre>



<p>The parameters fill the <code>{{1}}</code>, <code>{{2}}</code> placeholders in your template in order. Make sure the number of parameters matches what the template expects.</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;">Project in mind?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Need a complete notification system?</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;">From WhatsApp alerts to full desktop applications with database integration. I design software that lasts. Let&#039;s talk about your project.</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 a project</a>
      
      
    </div>
  </div>
</div>
	


<h2 class="wp-block-heading">Reading the API response</h2>



<p>A successful response returns a JSON object with the message ID. An error returns a structured error object. Here is how to read both:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Async Function SendAndLog(recipientPhone As String, message As String) As Task
    Dim phoneNumberId As String = "YOUR_PHONE_NUMBER_ID"
    Dim accessToken As String = "YOUR_ACCESS_TOKEN"
    Dim url As String = $"https://graph.facebook.com/v20.0/{phoneNumberId}/messages"

    Dim json As String = "{" &amp;
        """messaging_product"": ""whatsapp""," &amp;
        """to"": """ &amp; recipientPhone &amp; """," &amp;
        """type"": ""text""," &amp;
        """text"": {""body"": """ &amp; message &amp; """}" &amp;
        "}"

    Using client As New HttpClient()
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " &amp; accessToken)
        Dim content As New StringContent(json, Encoding.UTF8, "application/json")
        Dim response = Await client.PostAsync(url, content)
        Dim body = Await response.Content.ReadAsStringAsync()

        If response.IsSuccessStatusCode Then
            ' body contains: {"messaging_product":"whatsapp","contacts":[...],"messages":[{"id":"wamid.xxx"}]}
            Console.WriteLine("Sent. Response: " &amp; body)
        Else
            ' body contains: {"error":{"message":"...","type":"...","code":100,...}}
            Console.WriteLine("Error " &amp; response.StatusCode.ToString() &amp; ": " &amp; body)
        End If
    End Using
End Function</pre>



<p>For production applications, log the response body to a file for debugging. See the <a href="https://robbelroot.de/blog/vbnet-write-text-file/"><strong>VB.NET write text file guide</strong></a> for file logging patterns.</p>



<h2 class="wp-block-heading">Sending to multiple recipients</h2>



<p>The WhatsApp API accepts one recipient per request. To send to multiple numbers, loop through a <a href="https://robbelroot.de/blog/vbnet-list-en/"><strong>VB.NET List</strong></a> of phone numbers:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Async Function SendToMultiple(phones As List(Of String), message As String) As Task
    Dim successCount As Integer = 0
    Dim failCount As Integer = 0

    For Each phone In phones
        Dim success = Await SendWhatsAppMessage(phone, message)

        If success Then
            successCount += 1
        Else
            failCount += 1
        End If

        ' Respect rate limits: max 80 messages per second for Business API
        Await Task.Delay(50)
    Next

    Console.WriteLine($"Sent: {successCount}, Failed: {failCount}")
End Function</pre>



<p>The <code>Task.Delay(50)</code> adds a small pause between requests to stay within the API rate limit. For large batches (thousands of messages), consider queuing messages and processing them in the background.</p>



<h2 class="wp-block-heading">Storing credentials safely</h2>



<p>Never hardcode your access token in source code. For desktop applications, store credentials in an external config file or environment variables:</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="">' Read from App.config or environment variable
Dim accessToken As String = Environment.GetEnvironmentVariable("WHATSAPP_TOKEN")
Dim phoneNumberId As String = Environment.GetEnvironmentVariable("WHATSAPP_PHONE_ID")

If String.IsNullOrEmpty(accessToken) OrElse String.IsNullOrEmpty(phoneNumberId) Then
    MessageBox.Show("WhatsApp credentials not configured.", "Configuration Error",
        MessageBoxButtons.OK, MessageBoxIcon.Error)
    Return
End If</pre>



<p>Set environment variables on the machine running your app, or use <code>My.Settings</code> with user-scoped settings for per-user configuration.</p>



<h2 class="wp-block-heading">Using Twilio as an alternative</h2>



<p>If you prefer a simpler SDK over raw HTTP requests, Twilio offers a WhatsApp integration with a .NET NuGet package. Install <code>Twilio</code> via NuGet, then:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Imports Twilio
Imports Twilio.Rest.Api.V2010.Account

' Initialize once at app startup
TwilioClient.Init("YOUR_ACCOUNT_SID", "YOUR_AUTH_TOKEN")

' Send a message
Dim msg = MessageResource.Create(
    body:="Your order has been shipped.",
    from:=New Twilio.Types.PhoneNumber("whatsapp:+14155238886"),
    [to]:=New Twilio.Types.PhoneNumber("whatsapp:+491234567890")
)

Console.WriteLine("Message SID: " &amp; msg.Sid)</pre>



<p>Twilio costs money per message but handles rate limiting, retries, and delivery tracking for you. The direct Meta API is free (you only pay for conversations after the free tier), but you handle everything yourself.</p>



<h2 class="wp-block-heading">Common mistakes</h2>



<h3 class="wp-block-heading">Sending free-form text outside the 24-hour window</h3>



<p>The API returns error code 131047 if you try to send a text message to someone who has not messaged you in the last 24 hours. Use a template message instead. Template messages work anytime and are the standard approach for notifications.</p>



<h3 class="wp-block-heading">Wrong phone number format</h3>



<p>The API expects the full international number without a plus sign, spaces, or dashes. <code>491234567890</code> is correct. <code>+49 123 456 7890</code>, <code>01234567890</code>, or <code>0049-123-4567890</code> will fail. Strip all formatting before sending:</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 cleanPhone = phone.Replace("+", "").Replace(" ", "").Replace("-", "")</pre>



<h3 class="wp-block-heading">Hardcoding the access token</h3>



<p>Temporary tokens expire after 24 hours. If you hardcode one and forget to update it, your app silently stops sending. Use a permanent System User token for production and store it in environment variables or a secure config file, never in source code.</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;">Looking for an experienced .NET developer?</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 take on your project, from API integrations to complete desktop applications. 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 a project</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-whatsapp-en-1"><strong class="schema-faq-question"><strong>Is the WhatsApp Business API free?</strong></strong> <p class="schema-faq-answer">Meta offers 1,000 free service conversations per month. Beyond that, you pay per conversation (not per message). Template messages for notifications cost a small fee per conversation, varying by country. Development and testing with the sandbox number is free.</p> </div> <div class="schema-faq-section" id="faq-whatsapp-en-2"><strong class="schema-faq-question"><strong>Can I send WhatsApp messages from VB.NET without the official API?</strong></strong> <p class="schema-faq-answer">Technically you could automate WhatsApp Web with Selenium, but this violates WhatsApp&#8217;s terms of service and can get your number banned. The official Cloud API or a provider like Twilio are the only reliable and compliant options.</p> </div> <div class="schema-faq-section" id="faq-whatsapp-en-3"><strong class="schema-faq-question"><strong>What is the difference between a text message and a template message?</strong></strong> <p class="schema-faq-answer">A text message is free-form content you can only send during an active 24-hour conversation window. A template message is a pre-approved format registered in your Meta dashboard that can be sent anytime, including to users who have not contacted you first.</p> </div> <div class="schema-faq-section" id="faq-whatsapp-en-4"><strong class="schema-faq-question"><strong>Do I need a special phone number for the WhatsApp API?</strong></strong> <p class="schema-faq-answer">You need a phone number that is not already registered with WhatsApp or WhatsApp Business App. Meta provides a free test number for development. For production, register a dedicated business number in the Meta Business dashboard.</p> </div> <div class="schema-faq-section" id="faq-whatsapp-en-5"><strong class="schema-faq-question"><strong>Can I receive WhatsApp messages in VB.NET too?</strong></strong> <p class="schema-faq-answer">Yes, but it requires a webhook. Meta sends incoming messages to a public HTTPS endpoint you configure. For a desktop VB.NET app, you would need a server component (ASP.NET or a cloud function) that receives the webhook and forwards messages to your app.</p> </div> </div>



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



<p>Sending WhatsApp messages from VB.NET comes down to a single <code>HttpClient.PostAsync</code> call to Meta&#8217;s Cloud API. Use template messages for notifications, store your token securely, and clean phone numbers before sending. For simpler integration at higher cost, Twilio wraps the same functionality in a NuGet package. For logging API responses to a file, see the <a href="https://robbelroot.de/blog/vbnet-write-text-file/"><strong>VB.NET write text file guide</strong></a>.</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-send-whatsapp-message/">VB.NET Send WhatsApp Message via Cloud API (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vbnet-send-whatsapp-message/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>VB.NET MsgBox – Meldungsdialoge einfach erklärt (2026)</title>
		<link>https://robbelroot.de/blog/vbnet-msgbox/</link>
					<comments>https://robbelroot.de/blog/vbnet-msgbox/#respond</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Wed, 08 Apr 2026 22:15:07 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Visual Basic .NET]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=20487</guid>

					<description><![CDATA[<p>Die VB.NET MsgBox-Funktion zeigt eine Meldung an und gibt zurück, welchen Button der Benutzer geklickt hat. Sie eignet sich für schnelle Hinweise, Bestätigungen und Ja/Nein-Abfragen. Dieser Guide behandelt Syntax, Button-Kombinationen, Icons, Rückgabewerte, den Unterschied zwischen MsgBox und MessageBox.Show und wann du was verwenden solltest. MsgBox vs. MessageBox.Show VB.NET bietet zwei &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-msgbox/">VB.NET MsgBox – Meldungsdialoge einfach erklärt (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Die <strong>VB.NET MsgBox</strong>-Funktion zeigt eine Meldung an und gibt zurück, welchen Button der Benutzer geklickt hat. Sie eignet sich für schnelle Hinweise, Bestätigungen und Ja/Nein-Abfragen. Dieser Guide behandelt Syntax, Button-Kombinationen, Icons, Rückgabewerte, den Unterschied zwischen <code>MsgBox</code> und <code>MessageBox.Show</code> und wann du was verwenden solltest.</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;">.NET-Hilfe gesucht?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Du baust eine Desktop-Anwendung?</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;">Ich entwickle seit über 17 Jahren professionell in VB.NET und C#. Von Meldungsdialogen bis zur kompletten WinForms-Anwendung kann ich helfen.</p>
    
    <div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;">

            <a href="https://robbelroot.de/kontakt/"
         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'"
      >→ Projekt anfragen</a>
      
      
    </div>
  </div>
</div>
	





<h2 class="wp-block-heading">MsgBox vs. MessageBox.Show</h2>



<p>VB.NET bietet zwei Wege, eine Meldung anzuzeigen. Beide öffnen denselben Windows-Dialog, unterscheiden sich aber in Herkunft und API-Stil:</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="">' VB.NET-Stil (aus Microsoft.VisualBasic Namespace)
MsgBox("Datei gespeichert.", MsgBoxStyle.Information, "Erfolg")

' .NET Framework-Stil (aus System.Windows.Forms)
MessageBox.Show("Datei gespeichert.", "Erfolg", MessageBoxButtons.OK, MessageBoxIcon.Information)</pre>



<figure class="wp-block-table"><table><thead><tr><th>Aspekt</th><th>MsgBox</th><th>MessageBox.Show</th></tr></thead><tbody><tr><td>Namespace</td><td><code>Microsoft.VisualBasic</code></td><td><code>System.Windows.Forms</code></td></tr><tr><td>In C# verfügbar</td><td>Nein (nur VB.NET)</td><td>Ja</td></tr><tr><td>Rückgabetyp</td><td><code>MsgBoxResult</code></td><td><code>DialogResult</code></td></tr><tr><td>Button/Icon-Enums</td><td><code>MsgBoxStyle</code> (kombinierbar)</td><td>Getrennte Enums für Buttons und Icons</td></tr><tr><td>Parameter-Reihenfolge</td><td>Nachricht, Stil, Titel</td><td>Nachricht, Titel, Buttons, Icon</td></tr></tbody></table></figure>



<p><code>MsgBox</code> ist ein VB.NET-Wrapper um die Win32-<code>MessageBox</code>-API. <code>MessageBox.Show</code> ist die .NET-Framework-Klasse, die in allen .NET-Sprachen funktioniert. Beide erzeugen exakt dasselbe Dialog-Fenster. Wenn dein Projekt rein VB.NET ist, funktioniert beides. Wenn du Code mit C#-Entwicklern teilst oder .NET-Konventionen folgst, ist <code>MessageBox.Show</code> die bessere Wahl.</p>



<h2 class="wp-block-heading">MsgBox Syntax</h2>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Dim result As MsgBoxResult = MsgBox(
    Prompt,            ' Der Nachrichtentext (erforderlich)
    Buttons Or Icon,   ' MsgBoxStyle-Flags (optional)
    Title              ' Fenstertitel (optional)
)</pre>



<p>Der erste Parameter ist die Nachricht. Der zweite kombiniert Button- und Icon-Stile mit <code>Or</code>. Der dritte setzt den Fenstertitel. Nur der erste Parameter ist erforderlich.</p>



<h2 class="wp-block-heading">Einfache Meldung</h2>



<p>Die einfachste MsgBox mit nur einer Nachricht und dem Standard-OK-Button:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">MsgBox("Die Datei wurde gespeichert.")</pre>



<p>Mit Titel und Informations-Icon:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">MsgBox("Die Datei wurde gespeichert.", MsgBoxStyle.Information, "Erfolg")</pre>



<h2 class="wp-block-heading">Ja/Nein-Bestätigung</h2>



<p>Dem Benutzer eine Ja/Nein-Frage stellen und auf die Antwort reagieren:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Dim result = MsgBox(
    "Möchtest du diesen Datensatz löschen?",
    MsgBoxStyle.YesNo Or MsgBoxStyle.Question,
    "Löschen bestätigen")

If result = MsgBoxResult.Yes Then
    DeleteRecord()
End If</pre>



<p>Kombiniere Button-Stil und Icon-Stil mit <code>Or</code>. Der Rückgabewert sagt dir, welcher Button geklickt wurde.</p>



<h2 class="wp-block-heading">Ja/Nein/Abbrechen</h2>



<p>Für ungespeicherte Änderungen drei Optionen anbieten:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Dim result = MsgBox(
    "Du hast ungespeicherte Änderungen. Vor dem Schließen speichern?",
    MsgBoxStyle.YesNoCancel Or MsgBoxStyle.Exclamation,
    "Ungespeicherte Änderungen")

Select Case result
    Case MsgBoxResult.Yes
        SaveDocument()
        Me.Close()
    Case MsgBoxResult.No
        Me.Close()
    Case MsgBoxResult.Cancel
        ' Nichts tun, auf dem Form bleiben
End Select</pre>



<h2 class="wp-block-heading">Alle Button-Stile</h2>



<figure class="wp-block-table"><table><thead><tr><th>MsgBoxStyle</th><th>Angezeigte Buttons</th><th>Mögliche Ergebnisse</th></tr></thead><tbody><tr><td><code>OKOnly</code> (Standard)</td><td>OK</td><td><code>Ok</code></td></tr><tr><td><code>OKCancel</code></td><td>OK, Abbrechen</td><td><code>Ok</code>, <code>Cancel</code></td></tr><tr><td><code>YesNo</code></td><td>Ja, Nein</td><td><code>Yes</code>, <code>No</code></td></tr><tr><td><code>YesNoCancel</code></td><td>Ja, Nein, Abbrechen</td><td><code>Yes</code>, <code>No</code>, <code>Cancel</code></td></tr><tr><td><code>RetryCancel</code></td><td>Wiederholen, Abbrechen</td><td><code>Retry</code>, <code>Cancel</code></td></tr><tr><td><code>AbortRetryIgnore</code></td><td>Abbrechen, Wiederholen, Ignorieren</td><td><code>Abort</code>, <code>Retry</code>, <code>Ignore</code></td></tr></tbody></table></figure>



<h2 class="wp-block-heading">Alle Icon-Stile</h2>



<figure class="wp-block-table"><table><thead><tr><th>MsgBoxStyle</th><th>Icon</th><th>Einsatz</th></tr></thead><tbody><tr><td><code>Information</code></td><td>Blauer Info-Kreis</td><td>Statusmeldungen, Bestätigungen</td></tr><tr><td><code>Question</code></td><td>Blaues Fragezeichen</td><td>Ja/Nein-Abfragen</td></tr><tr><td><code>Exclamation</code></td><td>Gelbes Warndreieck</td><td>Warnungen, ungespeicherte Änderungen</td></tr><tr><td><code>Critical</code></td><td>Roter Fehlerkreis</td><td>Fehler, kritische Probleme</td></tr></tbody></table></figure>


<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;">Projekt in Planung?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Brauchst du eine fertige WinForms-Anwendung?</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;">Von Meldungsdialogen bis zur kompletten datengetriebenen Desktop-App: Ich entwerfe Software, die hält. Lass uns über dein Projekt sprechen.</p>
    
    <div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;">

            <a href="https://robbelroot.de/kontakt/"
         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'"
      >→ Projekt anfragen</a>
      
      
    </div>
  </div>
</div>
	


<h2 class="wp-block-heading">Standard-Button ändern</h2>



<p>Standardmäßig ist der erste Button fokussiert. Du kannst das ändern, um versehentliche Klicks auf destruktive Aktionen zu vermeiden:</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="">' "Nein" standardmäßig fokussieren, damit nicht versehentlich gelöscht wird
Dim result = MsgBox(
    "Alle Datensätze endgültig löschen?",
    MsgBoxStyle.YesNo Or MsgBoxStyle.Critical Or MsgBoxStyle.DefaultButton2,
    "Warnung")

If result = MsgBoxResult.Yes Then
    DeleteAllRecords()
End If</pre>



<p><code>DefaultButton2</code> fokussiert den zweiten Button (Nein). Verwende <code>DefaultButton3</code> für den dritten Button bei Drei-Button-Dialogen.</p>



<h2 class="wp-block-heading">Dieselben Beispiele mit MessageBox.Show</h2>



<p>Hier die gleichen Muster mit der .NET-Variante <code>MessageBox.Show</code> zum Vergleichen:</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="">' Einfache Meldung
MessageBox.Show("Die Datei wurde gespeichert.", "Erfolg",
    MessageBoxButtons.OK, MessageBoxIcon.Information)

' Ja/Nein-Bestätigung
Dim result As DialogResult = MessageBox.Show(
    "Möchtest du diesen Datensatz löschen?", "Löschen bestätigen",
    MessageBoxButtons.YesNo, MessageBoxIcon.Question)

If result = DialogResult.Yes Then
    DeleteRecord()
End If

' Ja/Nein/Abbrechen mit Standard-Button
Dim result2 As DialogResult = MessageBox.Show(
    "Vor dem Schließen speichern?", "Ungespeicherte Änderungen",
    MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning,
    MessageBoxDefaultButton.Button2)

Select Case result2
    Case DialogResult.Yes
        SaveDocument()
        Me.Close()
    Case DialogResult.No
        Me.Close()
    Case DialogResult.Cancel
        ' Auf dem Form bleiben
End Select</pre>



<p>Die Funktion ist identisch. <code>MessageBox.Show</code> verwendet getrennte Enums (<code>MessageBoxButtons</code>, <code>MessageBoxIcon</code>, <code>MessageBoxDefaultButton</code>) statt Flags mit <code>Or</code> zu kombinieren. Der Rückgabetyp ist <code>DialogResult</code> statt <code>MsgBoxResult</code>.</p>



<h2 class="wp-block-heading">Wann was verwenden</h2>



<p>Verwende <code>MsgBox</code>, wenn:</p>



<ul class="wp-block-list">
<li>Dein Projekt <strong>rein VB.NET</strong> ist und du kürzere Syntax bevorzugst</li>



<li>Du <strong>schnell prototypen</strong> willst und minimalen Code brauchst</li>
</ul>



<p>Verwende <code>MessageBox.Show</code>, wenn:</p>



<ul class="wp-block-list">
<li>Deine Codebasis <strong>mit C#-Entwicklern geteilt</strong> wird</li>



<li>Du <strong>.NET-Konventionen</strong> folgen willst</li>



<li>Du den <strong>Owner-Window-Parameter</strong> brauchst (um den Dialog über einem bestimmten Form zu halten)</li>



<li>Dein Code <strong>portierbar</strong> zu .NET 5+ / .NET 8+ Projekten sein soll</li>
</ul>



<h2 class="wp-block-heading">Komplettes Beispiel: Speichern-vor-Schließen-Muster</h2>



<p>Ein realistisches Beispiel, das vor dem Schließen eines Forms zum Speichern auffordert. Dieses Muster funktioniert in jedem Texteditor, Dateneingabe-Form oder Einstellungsfenster:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private _hasChanges As Boolean = False

Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
    _hasChanges = True
End Sub

Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    If Not _hasChanges Then Return

    Dim result = MsgBox(
        "Du hast ungespeicherte Änderungen. Jetzt speichern?",
        MsgBoxStyle.YesNoCancel Or MsgBoxStyle.Exclamation Or MsgBoxStyle.DefaultButton1,
        "Ungespeicherte Änderungen")

    Select Case result
        Case MsgBoxResult.Yes
            SaveToFile()
        Case MsgBoxResult.Cancel
            e.Cancel = True  ' Schließen verhindern
    End Select
End Sub

Private Sub SaveToFile()
    File.WriteAllText("data.txt", TextBox1.Text, Encoding.UTF8)
    _hasChanges = False
End Sub</pre>



<p>Mit <code>e.Cancel = True</code> im <code>FormClosing</code>-Event wird das Schließen des Forms verhindert. Der Benutzer bleibt auf dem Form und kann weiter arbeiten. Mehr zum Schreiben von Dateien findest du im <a href="https://robbelroot.de/blog/vbnet-textdatei-schreiben/"><strong>VB.NET Textdatei schreiben Guide</strong></a>.</p>



<h2 class="wp-block-heading">Häufige Fehler</h2>



<h3 class="wp-block-heading">Rückgabewert ignorieren</h3>



<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="">' SCHLECHT - fragt Ja/Nein, ignoriert aber die Antwort
MsgBox("Löschen?", MsgBoxStyle.YesNo)
DeleteRecord()

' GUT - prüfen, welcher Button geklickt wurde
If MsgBox("Löschen?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
    DeleteRecord()
End If</pre>



<h3 class="wp-block-heading">MsgBox mit VBScript-MsgBox verwechseln</h3>



<p>Die VB.NET-<code>MsgBox</code>-Funktion lebt in <code>Microsoft.VisualBasic.Interaction</code> und gibt <code>MsgBoxResult</code> zurück. Die VBScript-<code>MsgBox</code> gibt ganzzahlige Werte zurück (1 für OK, 6 für Ja, usw.). Sie sehen ähnlich aus, laufen aber in komplett unterschiedlichen Umgebungen. In VB.NET immer gegen das <code>MsgBoxResult</code>-Enum vergleichen, nie gegen Magic Numbers.</p>



<h3 class="wp-block-heading">MsgBox in einem Hintergrund-Thread verwenden</h3>



<p>Sowohl <code>MsgBox</code> als auch <code>MessageBox.Show</code> müssen vom UI-Thread aus aufgerufen werden. Wenn du sie aus einem Hintergrund-Thread oder <code>Task</code> aufrufst, kann der Dialog hinter anderen Fenstern erscheinen oder Cross-Thread-Exceptions auslösen. Verwende <code>Me.Invoke()</code>, um den Aufruf auf den UI-Thread zu marshallen.</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;">Interessiert?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Erfahrenen .NET-Entwickler gesucht?</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;">Ich übernehme dein Projekt, von Benutzerdialogen bis zur fertigen Desktop-Anwendung. Schreib mir einfach eine Nachricht.</p>
    
    <div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;">

            <a href="https://robbelroot.de/kontakt/"
         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'"
      >→ Projekt anfragen</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-msgbox-de-1"><strong class="schema-faq-question"><strong>Was ist der Unterschied zwischen MsgBox und MessageBox.Show?</strong></strong> <p class="schema-faq-answer"><code>MsgBox</code> ist eine VB.NET-Komfortfunktion aus dem <code>Microsoft.VisualBasic</code>-Namespace. <code>MessageBox.Show</code> ist die .NET-Framework-Klasse aus <code>System.Windows.Forms</code>. Beide erzeugen denselben Dialog. <code>MsgBox</code> gibt <code>MsgBoxResult</code> zurück, <code>MessageBox.Show</code> gibt <code>DialogResult</code> zurück.</p> </div> <div class="schema-faq-section" id="faq-msgbox-de-2"><strong class="schema-faq-question"><strong>Wie zeige ich eine Ja/Nein-MsgBox in VB.NET?</strong></strong> <p class="schema-faq-answer">Verwende <code>MsgBox("Deine Frage", MsgBoxStyle.YesNo)</code> und vergleiche das Ergebnis mit <code>MsgBoxResult.Yes</code> oder <code>MsgBoxResult.No</code>. Füge <code>Or MsgBoxStyle.Question</code> hinzu für ein Fragezeichen-Icon.</p> </div> <div class="schema-faq-section" id="faq-msgbox-de-3"><strong class="schema-faq-question"><strong>Wie ändere ich den Standard-Button in MsgBox?</strong></strong> <p class="schema-faq-answer">Füge <code>MsgBoxStyle.DefaultButton2</code> oder <code>DefaultButton3</code> zum Stil-Parameter hinzu. Das verschiebt den initialen Fokus auf den zweiten bzw. dritten Button und verhindert versehentliche Klicks auf destruktive Aktionen.</p> </div> <div class="schema-faq-section" id="faq-msgbox-de-4"><strong class="schema-faq-question"><strong>Ist VB.NET MsgBox dasselbe wie VBScript MsgBox?</strong></strong> <p class="schema-faq-answer">Nein. VB.NET <code>MsgBox</code> gibt ein typisiertes <code>MsgBoxResult</code>-Enum zurück. VBScript <code>MsgBox</code> gibt ganzzahlige Konstanten zurück (1 für OK, 6 für Ja, usw.). Sie sehen ähnlich aus, laufen aber in komplett unterschiedlichen Umgebungen.</p> </div> <div class="schema-faq-section" id="faq-msgbox-de-5"><strong class="schema-faq-question"><strong>Kann ich MsgBox in einem Hintergrund-Thread verwenden?</strong></strong> <p class="schema-faq-answer">Nicht direkt. Sowohl <code>MsgBox</code> als auch <code>MessageBox.Show</code> sollten vom UI-Thread aufgerufen werden. Aus einem Hintergrund-Thread verwende <code>Me.Invoke()</code>, um den Aufruf auf den UI-Thread zu marshallen.</p> </div> </div>



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



<p>Die <code>MsgBox</code>-Funktion gibt dir schnelle Meldungsdialoge mit einer Zeile Code. Kombiniere Button- und Icon-Stile mit <code>Or</code>, prüfe immer den Rückgabewert bei Ja/Nein-Abfragen und verwende <code>DefaultButton2</code> vor destruktiven Aktionen. Wenn du .NET-Standardcode bevorzugst, nutze <code>MessageBox.Show</code> mit getrennten Enums für dasselbe Ergebnis. Für dynamisches Event-Handling schau dir den <a href="https://robbelroot.de/blog/vbnet-addhandler/"><strong>VB.NET AddHandler Guide</strong></a> an. Zum Schreiben von Dateien nach einem Speichern-Dialog siehe den <a href="https://robbelroot.de/blog/vbnet-textdatei-schreiben/"><strong>VB.NET Textdatei schreiben Guide</strong></a>.</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-msgbox/">VB.NET MsgBox – Meldungsdialoge einfach erklärt (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vbnet-msgbox/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>VB.NET MsgBox and MessageBox.Show – Complete Guide (2026)</title>
		<link>https://robbelroot.de/blog/vbnet-msgbox-en/</link>
					<comments>https://robbelroot.de/blog/vbnet-msgbox-en/#respond</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Wed, 08 Apr 2026 22:15:00 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Visual Basic .NET (EN)]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=20488</guid>

					<description><![CDATA[<p>The VB.NET MsgBox function displays a message box and returns which button the user clicked. It is quick to use for alerts, confirmations, and yes/no prompts. This guide covers syntax, button combinations, icons, return values, the difference between MsgBox and MessageBox.Show, and when to use which. MsgBox vs. MessageBox.Show VB.NET &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-msgbox-en/">VB.NET MsgBox and MessageBox.Show – Complete Guide (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>The <strong>VB.NET MsgBox</strong> function displays a message box and returns which button the user clicked. It is quick to use for alerts, confirmations, and yes/no prompts. This guide covers syntax, button combinations, icons, return values, the difference between <code>MsgBox</code> and <code>MessageBox.Show</code>, and when to use which.</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 .NET help?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Building a desktop application?</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&#039;ve been developing professionally in VB.NET and C# for over 17 years. From message boxes to complete WinForms applications, I can help.</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 a project</a>
      
      
    </div>
  </div>
</div>
	





<h2 class="wp-block-heading">MsgBox vs. MessageBox.Show</h2>



<p>VB.NET offers two ways to display a message box. Both open the same Windows dialog, but they differ in origin and API style:</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="">' VB.NET-style (from Microsoft.VisualBasic namespace)
MsgBox("File saved.", MsgBoxStyle.Information, "Success")

' .NET Framework-style (from System.Windows.Forms)
MessageBox.Show("File saved.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information)</pre>



<figure class="wp-block-table"><table><thead><tr><th>Aspect</th><th>MsgBox</th><th>MessageBox.Show</th></tr></thead><tbody><tr><td>Namespace</td><td><code>Microsoft.VisualBasic</code></td><td><code>System.Windows.Forms</code></td></tr><tr><td>Available in C#</td><td>No (VB.NET only)</td><td>Yes</td></tr><tr><td>Return type</td><td><code>MsgBoxResult</code></td><td><code>DialogResult</code></td></tr><tr><td>Button/icon enums</td><td><code>MsgBoxStyle</code> (combinable)</td><td>Separate enums for buttons and icons</td></tr><tr><td>Parameter order</td><td>Message, Style, Title</td><td>Message, Title, Buttons, Icon</td></tr></tbody></table></figure>



<p><code>MsgBox</code> is a VB.NET convenience wrapper around the Win32 <code>MessageBox</code> API. <code>MessageBox.Show</code> is the .NET Framework class that works across all .NET languages. Both produce the exact same dialog window. If your project is purely VB.NET, either works fine. If you share code with C# developers or follow .NET conventions, <code>MessageBox.Show</code> is the better choice.</p>



<h2 class="wp-block-heading">MsgBox syntax</h2>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Dim result As MsgBoxResult = MsgBox(
    Prompt,          ' The message text (required)
    Buttons Or Icon, ' MsgBoxStyle flags (optional)
    Title            ' Window title (optional)
)</pre>



<p>The first parameter is the message. The second combines button and icon styles with <code>Or</code>. The third sets the window title. Only the first parameter is required.</p>



<h2 class="wp-block-heading">Simple message</h2>



<p>The simplest MsgBox with just a message and the default OK button:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">MsgBox("The file has been saved.")</pre>



<p>With a title and information icon:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">MsgBox("The file has been saved.", MsgBoxStyle.Information, "Success")</pre>



<h2 class="wp-block-heading">Yes/No confirmation</h2>



<p>Ask the user a yes/no question and react to their choice:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Dim result = MsgBox(
    "Do you want to delete this record?",
    MsgBoxStyle.YesNo Or MsgBoxStyle.Question,
    "Confirm deletion")

If result = MsgBoxResult.Yes Then
    DeleteRecord()
End If</pre>



<p>Combine button style and icon style with <code>Or</code>. The return value tells you which button was clicked.</p>



<h2 class="wp-block-heading">Yes/No/Cancel</h2>



<p>For unsaved changes, offer three options:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Dim result = MsgBox(
    "You have unsaved changes. Save before closing?",
    MsgBoxStyle.YesNoCancel Or MsgBoxStyle.Exclamation,
    "Unsaved changes")

Select Case result
    Case MsgBoxResult.Yes
        SaveDocument()
        Me.Close()
    Case MsgBoxResult.No
        Me.Close()
    Case MsgBoxResult.Cancel
        ' Do nothing, stay on the form
End Select</pre>



<h2 class="wp-block-heading">All button styles</h2>



<figure class="wp-block-table"><table><thead><tr><th>MsgBoxStyle</th><th>Buttons shown</th><th>Possible results</th></tr></thead><tbody><tr><td><code>OKOnly</code> (default)</td><td>OK</td><td><code>Ok</code></td></tr><tr><td><code>OKCancel</code></td><td>OK, Cancel</td><td><code>Ok</code>, <code>Cancel</code></td></tr><tr><td><code>YesNo</code></td><td>Yes, No</td><td><code>Yes</code>, <code>No</code></td></tr><tr><td><code>YesNoCancel</code></td><td>Yes, No, Cancel</td><td><code>Yes</code>, <code>No</code>, <code>Cancel</code></td></tr><tr><td><code>RetryCancel</code></td><td>Retry, Cancel</td><td><code>Retry</code>, <code>Cancel</code></td></tr><tr><td><code>AbortRetryIgnore</code></td><td>Abort, Retry, Ignore</td><td><code>Abort</code>, <code>Retry</code>, <code>Ignore</code></td></tr></tbody></table></figure>



<h2 class="wp-block-heading">All icon styles</h2>



<figure class="wp-block-table"><table><thead><tr><th>MsgBoxStyle</th><th>Icon</th><th>Use case</th></tr></thead><tbody><tr><td><code>Information</code></td><td>Blue info circle</td><td>Status messages, confirmations</td></tr><tr><td><code>Question</code></td><td>Blue question mark</td><td>Yes/No prompts</td></tr><tr><td><code>Exclamation</code></td><td>Yellow warning triangle</td><td>Warnings, unsaved changes</td></tr><tr><td><code>Critical</code></td><td>Red error circle</td><td>Errors, critical failures</td></tr></tbody></table></figure>


<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;">Planning a project?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Need a polished WinForms application?</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;">From message dialogs to complete data-driven desktop apps: I design software that lasts. Let&#039;s talk about your project.</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 a project</a>
      
      
    </div>
  </div>
</div>
	


<h2 class="wp-block-heading">Setting the default button</h2>



<p>By default, the first button is focused. You can change this to prevent accidental clicks on a destructive action:</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="">' Focus "No" by default so the user doesn't accidentally delete
Dim result = MsgBox(
    "Delete all records permanently?",
    MsgBoxStyle.YesNo Or MsgBoxStyle.Critical Or MsgBoxStyle.DefaultButton2,
    "Warning")

If result = MsgBoxResult.Yes Then
    DeleteAllRecords()
End If</pre>



<p><code>DefaultButton2</code> focuses the second button (No). Use <code>DefaultButton3</code> for the third button in three-button dialogs.</p>



<h2 class="wp-block-heading">The same examples with MessageBox.Show</h2>



<p>Here are the same patterns using the .NET <code>MessageBox.Show</code> equivalent, so you can compare:</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="">' Simple message
MessageBox.Show("The file has been saved.", "Success",
    MessageBoxButtons.OK, MessageBoxIcon.Information)

' Yes/No confirmation
Dim result As DialogResult = MessageBox.Show(
    "Do you want to delete this record?", "Confirm deletion",
    MessageBoxButtons.YesNo, MessageBoxIcon.Question)

If result = DialogResult.Yes Then
    DeleteRecord()
End If

' Yes/No/Cancel with default button
Dim result2 As DialogResult = MessageBox.Show(
    "Save before closing?", "Unsaved changes",
    MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning,
    MessageBoxDefaultButton.Button2)

Select Case result2
    Case DialogResult.Yes
        SaveDocument()
        Me.Close()
    Case DialogResult.No
        Me.Close()
    Case DialogResult.Cancel
        ' Stay on the form
End Select</pre>



<p>The functionality is identical. <code>MessageBox.Show</code> uses separate enums (<code>MessageBoxButtons</code>, <code>MessageBoxIcon</code>, <code>MessageBoxDefaultButton</code>) instead of combining flags with <code>Or</code>. The return type is <code>DialogResult</code> instead of <code>MsgBoxResult</code>.</p>



<h2 class="wp-block-heading">When to use which</h2>



<p>Use <code>MsgBox</code> when:</p>



<ul class="wp-block-list">
<li>Your project is <strong>VB.NET only</strong> and you prefer shorter syntax</li>



<li>You are <strong>prototyping quickly</strong> and want minimal code</li>
</ul>



<p>Use <code>MessageBox.Show</code> when:</p>



<ul class="wp-block-list">
<li>Your codebase is <strong>shared with C# developers</strong></li>



<li>You want to follow <strong>.NET conventions</strong></li>



<li>You need the <strong>owner window parameter</strong> (to keep the dialog on top of a specific form)</li>



<li>You want your code to be <strong>portable</strong> to .NET 5+ / .NET 8+ projects</li>
</ul>



<h2 class="wp-block-heading">Complete example: save-before-close pattern</h2>



<p>A realistic example that asks to save before closing a form. This pattern works in any text editor, data entry form, or settings window:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private _hasChanges As Boolean = False

Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
    _hasChanges = True
End Sub

Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    If Not _hasChanges Then Return

    Dim result = MsgBox(
        "You have unsaved changes. Save now?",
        MsgBoxStyle.YesNoCancel Or MsgBoxStyle.Exclamation Or MsgBoxStyle.DefaultButton1,
        "Unsaved changes")

    Select Case result
        Case MsgBoxResult.Yes
            SaveToFile()
        Case MsgBoxResult.Cancel
            e.Cancel = True  ' Prevent closing
    End Select
End Sub

Private Sub SaveToFile()
    File.WriteAllText("data.txt", TextBox1.Text, Encoding.UTF8)
    _hasChanges = False
End Sub</pre>



<p>Setting <code>e.Cancel = True</code> in the <code>FormClosing</code> event prevents the form from closing. The user stays on the form and can continue editing. For more on writing files, see the <a href="https://robbelroot.de/blog/vbnet-write-text-file/"><strong>VB.NET Write Text File guide</strong></a>.</p>



<h2 class="wp-block-heading">Common mistakes</h2>



<h3 class="wp-block-heading">Ignoring the return value</h3>



<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="">' BAD - asks Yes/No but ignores the answer
MsgBox("Delete?", MsgBoxStyle.YesNo)
DeleteRecord()

' GOOD - check which button was clicked
If MsgBox("Delete?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
    DeleteRecord()
End If</pre>



<h3 class="wp-block-heading">Confusing MsgBox with VBScript MsgBox</h3>



<p>The VB.NET <code>MsgBox</code> function lives in <code>Microsoft.VisualBasic.Interaction</code> and returns <code>MsgBoxResult</code>. The VBScript <code>MsgBox</code> returns integer values (1 for OK, 6 for Yes, etc.). They look similar but live in completely different environments. In VB.NET, always compare against the <code>MsgBoxResult</code> enum, never against magic numbers.</p>



<h3 class="wp-block-heading">Using MsgBox in a background thread</h3>



<p>Both <code>MsgBox</code> and <code>MessageBox.Show</code> must be called from the UI thread. If you call them from a background thread or <code>Task</code>, the dialog may appear behind other windows or cause cross-thread exceptions. Use <code>Me.Invoke()</code> to marshal the call to the UI thread if needed.</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 expert support?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Looking for an experienced .NET developer?</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&#039;ll take on your project, from user dialogs to finished desktop applications. Just drop 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 a project</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-msgbox-en-1"><strong class="schema-faq-question"><strong>What is the difference between MsgBox and MessageBox.Show?</strong></strong> <p class="schema-faq-answer"><code>MsgBox</code> is a VB.NET convenience function from the <code>Microsoft.VisualBasic</code> namespace. <code>MessageBox.Show</code> is the .NET Framework class from <code>System.Windows.Forms</code>. Both produce the same dialog. <code>MsgBox</code> uses <code>MsgBoxResult</code>, while <code>MessageBox.Show</code> uses <code>DialogResult</code>.</p> </div> <div class="schema-faq-section" id="faq-msgbox-en-2"><strong class="schema-faq-question"><strong>How do I show a Yes/No message box in VB.NET?</strong></strong> <p class="schema-faq-answer">Use <code>MsgBox("Your question", MsgBoxStyle.YesNo)</code> and compare the result to <code>MsgBoxResult.Yes</code> or <code>MsgBoxResult.No</code>. Add <code>Or MsgBoxStyle.Question</code> for a question mark icon.</p> </div> <div class="schema-faq-section" id="faq-msgbox-en-3"><strong class="schema-faq-question"><strong>How do I change the default button in MsgBox?</strong></strong> <p class="schema-faq-answer">Add <code>MsgBoxStyle.DefaultButton2</code> or <code>DefaultButton3</code> to the style parameter. This moves the initial focus to the second or third button, preventing accidental clicks on destructive actions.</p> </div> <div class="schema-faq-section" id="faq-msgbox-en-4"><strong class="schema-faq-question"><strong>Is VB.NET MsgBox the same as VBScript MsgBox?</strong></strong> <p class="schema-faq-answer">No. VB.NET <code>MsgBox</code> returns a typed <code>MsgBoxResult</code> enum. VBScript <code>MsgBox</code> returns integer constants (1 for OK, 6 for Yes, etc.). They look similar but run in completely different environments.</p> </div> <div class="schema-faq-section" id="faq-msgbox-en-5"><strong class="schema-faq-question"><strong>Can I use MsgBox in a background thread?</strong></strong> <p class="schema-faq-answer">Not directly. Both <code>MsgBox</code> and <code>MessageBox.Show</code> should be called from the UI thread. From a background thread, use <code>Me.Invoke()</code> to marshal the call to the UI thread first.</p> </div> </div>



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



<p>The <code>MsgBox</code> function gives you quick message dialogs with one line of code. Combine button styles and icon styles with <code>Or</code>, always check the return value for Yes/No prompts, and use <code>DefaultButton2</code> before destructive actions. If you prefer .NET-standard code, use <code>MessageBox.Show</code> with separate enums for the same result. For handling button events dynamically, see the <a href="https://robbelroot.de/blog/vbnet-addhandler-en/"><strong>VB.NET AddHandler guide</strong></a>. For writing files after a save prompt, check the <a href="https://robbelroot.de/blog/vbnet-write-text-file/"><strong>VB.NET Write Text File guide</strong></a>.</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-msgbox-en/">VB.NET MsgBox and MessageBox.Show – Complete Guide (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vbnet-msgbox-en/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>VB.NET AddHandler – Wire Events at Runtime (2026)</title>
		<link>https://robbelroot.de/blog/vbnet-addhandler-en/</link>
					<comments>https://robbelroot.de/blog/vbnet-addhandler-en/#respond</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Wed, 08 Apr 2026 21:53:35 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Visual Basic .NET (EN)]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=20482</guid>

					<description><![CDATA[<p>The VB.NET AddHandler statement connects events to methods at runtime instead of wiring them statically with the Handles keyword. This is essential when you create controls dynamically or need to assign event handlers based on conditions. This guide covers the syntax, the difference from Handles, dynamic controls, RemoveHandler, custom events, &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-addhandler-en/">VB.NET AddHandler – Wire Events at Runtime (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>The <strong>VB.NET AddHandler</strong> statement connects events to methods at runtime instead of wiring them statically with the <code>Handles</code> keyword. This is essential when you create controls dynamically or need to assign event handlers based on conditions. This guide covers the syntax, the difference from <code>Handles</code>, dynamic controls, <code>RemoveHandler</code>, custom events, and common mistakes.</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 .NET help?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Building a desktop application?</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&#039;ve been developing professionally in VB.NET and C# for over 17 years. From event handling to complete WinForms applications, I can help.</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 a project</a>
      
      
    </div>
  </div>
</div>
	





<h2 class="wp-block-heading">Handles vs. AddHandler</h2>



<p>In WinForms there are two ways to connect an event to a method:</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="">' Way 1: Handles clause (static, at design time)
Private Sub BtnSave_Click(sender As Object, e As EventArgs) Handles BtnSave.Click
    ' Automatically wired by the designer
End Sub

' Way 2: AddHandler (dynamic, at runtime)
AddHandler BtnSave.Click, AddressOf BtnSave_Click

Private Sub BtnSave_Click(sender As Object, e As EventArgs)
    ' No "Handles" needed
End Sub</pre>



<p>The <code>Handles</code> clause only works with controls that exist at design time. <code>AddHandler</code> works anywhere, including controls you create through code. As soon as you generate controls dynamically, <code>AddHandler</code> is the only option.</p>



<h2 class="wp-block-heading">AddHandler syntax</h2>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">AddHandler Object.Event, AddressOf MethodName</pre>



<ul class="wp-block-list">
<li><code>Object.Event</code> is the event you want to subscribe to (e.g. <code>Button1.Click</code>)</li>



<li><code>AddressOf</code> returns a reference to the method that should be called</li>



<li>The method signature must match the event (e.g. <code>sender As Object, e As EventArgs</code>)</li>
</ul>



<h2 class="wp-block-heading">Basic example</h2>



<p>A button click using <code>AddHandler</code> instead of <code>Handles</code>:</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
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        AddHandler BtnGreet.Click, AddressOf BtnGreet_Click
    End Sub

    Private Sub BtnGreet_Click(sender As Object, e As EventArgs)
        MessageBox.Show("Hello!")
    End Sub
End Class</pre>



<p>Notice that <code>BtnGreet_Click</code> has no <code>Handles</code> clause at the end. The connection is made entirely through <code>AddHandler</code> in the <code>Load</code> event.</p>



<h2 class="wp-block-heading">Creating dynamic controls</h2>



<p>The most common use case for <code>AddHandler</code>: controls are created through code and need event handlers. Here is an example with dynamically created buttons:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim categories = New List(Of String) From {
        "Personal", "Business", "Archive"
    }

    For Each category In categories
        Dim btn As New Button()
        btn.Text = category
        btn.Size = New Size(120, 40)
        btn.Margin = New Padding(5)
        AddHandler btn.Click, AddressOf CategoryButton_Click
        FlowLayoutPanel1.Controls.Add(btn)
    Next
End Sub

Private Sub CategoryButton_Click(sender As Object, e As EventArgs)
    Dim btn = DirectCast(sender, Button)
    MessageBox.Show($"Category: {btn.Text}")
End Sub</pre>



<p>Every button gets the same click handler. Use <code>DirectCast(sender, Button)</code> to determine which button was clicked. This scales to any number of controls without needing a separate handler for each one.</p>



<h2 class="wp-block-heading">Complete example: numpad keyboard</h2>



<p>A realistic example that creates a virtual numpad keyboard at runtime. Each key button is connected to a shared handler via <code>AddHandler</code>:</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
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim keys = New List(Of String) From {
            "7", "8", "9",
            "4", "5", "6",
            "1", "2", "3",
            "0", "00", ","
        }

        For Each key In keys
            Dim btn As New Button()
            btn.Text = key
            btn.Size = New Size(50, 50)
            btn.FlatStyle = FlatStyle.Flat
            btn.FlatAppearance.BorderSize = 1
            btn.BackColor = Color.White
            btn.Font = New Font("Segoe UI", 12, FontStyle.Bold)
            AddHandler btn.Click, AddressOf NumpadButton_Click
            FlowLayoutPanel1.Controls.Add(btn)
        Next
    End Sub

    Private Sub NumpadButton_Click(sender As Object, e As EventArgs)
        Dim btn = DirectCast(sender, Button)
        TextBox1.Text &amp;= btn.Text
    End Sub
End Class</pre>



<p>You only need a <code>FlowLayoutPanel</code> (about 180 x 260 pixels) and a <code>TextBox</code> on the form. The buttons are created entirely through code, no designer work needed.</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;">Planning a project?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Need a polished WinForms application?</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;">From event handling to complete data-driven desktop apps: I design software that lasts. Let&#039;s talk about your project.</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 a project</a>
      
      
    </div>
  </div>
</div>
	


<h2 class="wp-block-heading">RemoveHandler: disconnecting events</h2>



<p>Use <code>RemoveHandler</code> to disconnect the event binding. This is important to avoid memory leaks when removing controls at runtime:</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="">' Assign handler
AddHandler btn.Click, AddressOf Button_Click

' Remove handler
RemoveHandler btn.Click, AddressOf Button_Click</pre>



<p>Use <code>RemoveHandler</code> whenever you:</p>



<ul class="wp-block-list">
<li><strong>Remove</strong> dynamic controls (e.g. when closing a tab)</li>



<li>Want to <strong>swap</strong> a handler (remove first, then add)</li>



<li>Want to prevent an event from <strong>firing multiple times</strong></li>
</ul>



<h2 class="wp-block-heading">Multiple events, one handler</h2>



<p>A single handler can process multiple events. This is especially useful for forms with many similar controls:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    AddHandler TxtName.TextChanged, AddressOf ValidateField
    AddHandler TxtEmail.TextChanged, AddressOf ValidateField
    AddHandler TxtPhone.TextChanged, AddressOf ValidateField
End Sub

Private Sub ValidateField(sender As Object, e As EventArgs)
    Dim txt = DirectCast(sender, TextBox)
    If String.IsNullOrWhiteSpace(txt.Text) Then
        txt.BackColor = Color.MistyRose
    Else
        txt.BackColor = Color.White
    End If
End Sub</pre>



<p>All three text boxes share the <code>ValidateField</code> handler. The <code>sender</code> parameter identifies which text box changed.</p>



<h2 class="wp-block-heading">Custom events with AddHandler</h2>



<p>You can also define your own events and subscribe to them with <code>AddHandler</code>. This is useful for loosely coupled communication between classes:</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 FileWatcher
    Public Event FileChanged(filePath As String)

    Public Sub CheckForChanges()
        ' Check logic...
        RaiseEvent FileChanged("C:\data\config.xml")
    End Sub
End Class

' In the form:
Private WithEvents watcher As New FileWatcher()

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    AddHandler watcher.FileChanged, AddressOf OnFileChanged
End Sub

Private Sub OnFileChanged(filePath As String)
    MessageBox.Show($"File changed: {filePath}")
End Sub</pre>



<p>The class uses <code>RaiseEvent</code> to trigger the event. The subscriber reacts through <code>AddHandler</code>. This keeps the <code>FileWatcher</code> class independent from the form.</p>



<h2 class="wp-block-heading">Common mistakes</h2>



<h3 class="wp-block-heading">Handler registered multiple times</h3>



<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="">' BAD - each click adds another handler
Private Sub BtnRefresh_Click(sender As Object, e As EventArgs) Handles BtnRefresh.Click
    AddHandler Timer1.Tick, AddressOf Timer1_Tick
End Sub

' GOOD - register handler once in Load
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    AddHandler Timer1.Tick, AddressOf Timer1_Tick
End Sub</pre>



<p>Calling <code>AddHandler</code> multiple times for the same event and method causes the method to execute multiple times. Register handlers in <code>Load</code> or call <code>RemoveHandler</code> first. For more on timers, see the <a href="https://robbelroot.de/blog/vbnet-timer-en/"><strong>VB.NET Timer guide</strong></a>.</p>



<h3 class="wp-block-heading">Wrong method signature</h3>



<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="">' BAD - parameters don't match the event
Private Sub Button_Click(text As String)
End Sub

' GOOD - signature matches the Click event
Private Sub Button_Click(sender As Object, e As EventArgs)
End Sub</pre>



<p>The method must have exactly the parameter types the event expects. For <code>Click</code>, that is <code>(sender As Object, e As EventArgs)</code>. The compiler will report an error if the signature does not match.</p>



<h3 class="wp-block-heading">Forgetting RemoveHandler for dynamic controls</h3>



<p>If you remove controls with <code>Controls.Remove()</code> but don&#8217;t disconnect the handler, the reference keeps the object in memory. Always call <code>RemoveHandler</code> before removing a dynamic control.</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 expert support?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Looking for an experienced .NET developer?</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&#039;ll take on your project, from event handling to finished desktop applications. Just drop 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 a project</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-addhandler-en-1"><strong class="schema-faq-question"><strong>What is the difference between Handles and AddHandler?</strong></strong> <p class="schema-faq-answer"><code>Handles</code> connects an event to a method statically at design time. <code>AddHandler</code> connects an event dynamically at runtime. For controls created through code, <code>AddHandler</code> is the only option.</p> </div> <div class="schema-faq-section" id="faq-addhandler-en-2"><strong class="schema-faq-question"><strong>Can I call AddHandler multiple times for the same event?</strong></strong> <p class="schema-faq-answer">Yes, but the handler will execute multiple times. If that is not what you want, call <code>RemoveHandler</code> first or register the handler only once in the <code>Load</code> event.</p> </div> <div class="schema-faq-section" id="faq-addhandler-en-3"><strong class="schema-faq-question"><strong>When do I need RemoveHandler?</strong></strong> <p class="schema-faq-answer">Whenever you remove dynamic controls, want to swap handlers, or need to prevent an event from firing multiple times. Without <code>RemoveHandler</code> you risk memory leaks.</p> </div> <div class="schema-faq-section" id="faq-addhandler-en-4"><strong class="schema-faq-question"><strong>Can one handler process multiple events?</strong></strong> <p class="schema-faq-answer">Yes. Use <code>AddHandler</code> multiple times with different controls but the same method. The <code>sender</code> parameter tells you which control triggered the event.</p> </div> <div class="schema-faq-section" id="faq-addhandler-en-5"><strong class="schema-faq-question"><strong>What does AddressOf mean in VB.NET?</strong></strong> <p class="schema-faq-answer"><code>AddressOf</code> creates a delegate, which is a typed reference to a method. It is used with <code>AddHandler</code> to tell the event which method to call when the event is raised.</p> </div> </div>



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



<p>The <code>AddHandler</code> statement makes event handling in VB.NET flexible. Use it for dynamically created controls, when you need to assign or swap handlers at runtime, and for custom events in your classes. Remember to call <code>RemoveHandler</code> when removing controls, and register handlers only once to avoid multiple executions. For related topics, check out the <a href="https://robbelroot.de/blog/vbnet-timer-en/"><strong>VB.NET Timer guide</strong></a> and the <a href="https://robbelroot.de/blog/vbnet-list-en/"><strong>VB.NET List guide</strong></a>.</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-addhandler-en/">VB.NET AddHandler – Wire Events at Runtime (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vbnet-addhandler-en/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>VB.NET FolderBrowserDialog – Pick Folders Easily (2026)</title>
		<link>https://robbelroot.de/blog/vbnet-folderbrowserdialog-en/</link>
					<comments>https://robbelroot.de/blog/vbnet-folderbrowserdialog-en/#respond</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Wed, 08 Apr 2026 21:28:21 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Visual Basic .NET (EN)]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=20476</guid>

					<description><![CDATA[<p>The VB.NET FolderBrowserDialog lets users pick a folder from the file system before your application processes its contents. It displays the standard Windows folder picker, returns the selected path, and optionally restricts the browsing root. This guide covers setup, root folder configuration, new-folder creation, batch processing, and common pitfalls. What &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-folderbrowserdialog-en/">VB.NET FolderBrowserDialog – Pick Folders Easily (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>The <strong>VB.NET FolderBrowserDialog</strong> lets users pick a folder from the file system before your application processes its contents. It displays the standard Windows folder picker, returns the selected path, and optionally restricts the browsing root. This guide covers setup, root folder configuration, new-folder creation, batch processing, and common pitfalls.</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 .NET help?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Building a desktop application?</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&#039;ve been developing professionally in VB.NET and C# for over 17 years. From folder dialogs to complete WinForms applications, I can help.</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 a project</a>
      
      
    </div>
  </div>
</div>
	





<h2 class="wp-block-heading">What is the FolderBrowserDialog?</h2>



<p>The <code>FolderBrowserDialog</code> is a WinForms control from <code>System.Windows.Forms</code>. When you call <code>ShowDialog()</code>, it opens the Windows folder picker. The user navigates the folder tree, selects a folder, and clicks OK. Your code then reads the full folder path from the <code>SelectedPath</code> property.</p>



<p>Use it when:</p>



<ul class="wp-block-list">
<li>The user should <strong>choose an output folder</strong> for exports, backups, or reports</li>



<li>Your application needs to <strong>batch-process all files</strong> inside a directory</li>



<li>The user should <strong>pick an installation or working directory</strong></li>



<li>You want to let the user <strong>create a new folder</strong> on the fly</li>
</ul>



<p>If the user should pick a single file instead, use the <a href="https://robbelroot.de/blog/vbnet-openfiledialog-en/"><strong>OpenFileDialog</strong></a>. To save a file to a specific location, use the <a href="https://robbelroot.de/blog/vbnet-savefiledialog-en/"><strong>SaveFileDialog</strong></a>.</p>



<h2 class="wp-block-heading">Basic example</h2>



<p>The simplest FolderBrowserDialog that displays the selected path:</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="">Using dlg As New FolderBrowserDialog()
    dlg.Description = "Select a folder"

    If dlg.ShowDialog() = DialogResult.OK Then
        MessageBox.Show($"Selected: {dlg.SelectedPath}")
    End If
End Using</pre>



<p>The <code>Using</code> block disposes the dialog after use. <code>ShowDialog()</code> returns <code>DialogResult.OK</code> when the user confirms, or <code>DialogResult.Cancel</code> when they close the dialog. Always check the result before using the path.</p>



<h2 class="wp-block-heading">Setting the root folder</h2>



<p>The <code>RootFolder</code> property restricts which top-level node the dialog shows. It accepts values from <code>Environment.SpecialFolder</code>:</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="">Using dlg As New FolderBrowserDialog()
    ' Only show folders inside Desktop
    dlg.RootFolder = Environment.SpecialFolder.Desktop
    dlg.Description = "Select a project folder"

    If dlg.ShowDialog() = DialogResult.OK Then
        Dim folder As String = dlg.SelectedPath
    End If
End Using</pre>



<p>Common values for <code>RootFolder</code>:</p>



<ul class="wp-block-list">
<li><code>Environment.SpecialFolder.Desktop</code> (default) shows the full tree starting from Desktop</li>



<li><code>Environment.SpecialFolder.MyComputer</code> shows all drives</li>



<li><code>Environment.SpecialFolder.MyDocuments</code> limits browsing to the Documents folder</li>
</ul>



<h2 class="wp-block-heading">Pre-selecting a folder</h2>



<p>Use <code>SelectedPath</code> to pre-select a folder when the dialog opens. This is useful when the user already chose a folder earlier and you want to remember 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="">Using dlg As New FolderBrowserDialog()
    dlg.Description = "Select export folder"
    dlg.SelectedPath = "C:\Users\Public\Documents"

    If dlg.ShowDialog() = DialogResult.OK Then
        Dim exportFolder As String = dlg.SelectedPath
    End If
End Using</pre>



<p>The dialog opens with that folder already highlighted. If the path does not exist, the dialog falls back to the root.</p>



<h2 class="wp-block-heading">Hiding the New Folder button</h2>



<p>By default, the dialog includes a &#8222;Make New Folder&#8220; button. If the user should only pick an existing folder, disable 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="">Using dlg As New FolderBrowserDialog()
    dlg.Description = "Select an existing folder"
    dlg.ShowNewFolderButton = False

    If dlg.ShowDialog() = DialogResult.OK Then
        Dim folder As String = dlg.SelectedPath
    End If
End Using</pre>



<p>Set <code>ShowNewFolderButton = False</code> for read-only operations like importing files. Keep it <code>True</code> (the default) when the user might need to create a destination folder for exports.</p>



<h2 class="wp-block-heading">Complete example: batch-processing files</h2>



<p>A realistic example that lets the user pick a folder and then processes all text files inside 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="">Imports System.IO
Imports System.Text

Private Sub BtnImport_Click(sender As Object, e As EventArgs) Handles BtnImport.Click
    Using dlg As New FolderBrowserDialog()
        dlg.Description = "Select folder with text files"
        dlg.ShowNewFolderButton = False

        If dlg.ShowDialog() = DialogResult.OK Then
            Dim files() As String = Directory.GetFiles(
                dlg.SelectedPath, "*.txt")

            For Each filePath In files
                Dim content As String = File.ReadAllText(
                    filePath, Encoding.UTF8)
                ' Process each file...
            Next

            MessageBox.Show($"{files.Length} files processed.")
        End If
    End Using
End Sub</pre>



<p><code>Directory.GetFiles()</code> returns all matching files in the selected folder. Use the second parameter for pattern matching, e.g. <code>"*.csv"</code> or <code>"*.xml"</code>. For more on reading text files, see the <a href="https://robbelroot.de/blog/vbnet-read-text-file/"><strong>VB.NET Read Text File guide</strong></a>.</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;">Planning a project?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Need a polished WinForms application?</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;">From file dialogs to complete data-driven desktop apps: I design software that lasts. Let&#039;s talk about your project.</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 a project</a>
      
      
    </div>
  </div>
</div>
	


<h2 class="wp-block-heading">Including subfolders</h2>



<p>To process files recursively, add <code>SearchOption.AllDirectories</code>:</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 dlg.ShowDialog() = DialogResult.OK Then
    Dim files() As String = Directory.GetFiles(
        dlg.SelectedPath, "*.txt", SearchOption.AllDirectories)

    For Each filePath In files
        Dim relativePath As String = filePath.Replace(
            dlg.SelectedPath & "\", "")
        ' Process file with relative path info...
    Next
End If</pre>



<p>This searches the selected folder and all its subfolders. Be careful with large directory trees, as this can take a while if there are thousands of files.</p>



<h2 class="wp-block-heading">Using Environment.SpecialFolder</h2>



<p>You can combine the dialog with <code>Environment.GetFolderPath()</code> to pre-select common system folders. You can also use the <a href="https://robbelroot.de/blog/vbnet-application-path-en/"><strong>application path</strong></a> as the starting point:</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="">' Start in Documents
Using dlg As New FolderBrowserDialog()
    dlg.SelectedPath = Environment.GetFolderPath(
        Environment.SpecialFolder.MyDocuments)

    If dlg.ShowDialog() = DialogResult.OK Then
        ' Use dlg.SelectedPath...
    End If
End Using

' Start in the application directory
Using dlg As New FolderBrowserDialog()
    dlg.SelectedPath = Application.StartupPath

    If dlg.ShowDialog() = DialogResult.OK Then
        ' Use dlg.SelectedPath...
    End If
End Using</pre>



<h2 class="wp-block-heading">All important properties at a glance</h2>



<figure class="wp-block-table"><table><thead><tr><th>Property</th><th>Default</th><th>Purpose</th></tr></thead><tbody><tr><td><code>Description</code></td><td>(empty)</td><td>Text shown above the folder tree</td></tr><tr><td><code>SelectedPath</code></td><td>(empty)</td><td>Pre-selected folder / selected folder after dialog</td></tr><tr><td><code>RootFolder</code></td><td>Desktop</td><td>Top-level node of the folder tree</td></tr><tr><td><code>ShowNewFolderButton</code></td><td>True</td><td>Show or hide the &#8222;Make New Folder&#8220; button</td></tr></tbody></table></figure>



<p>The FolderBrowserDialog has fewer properties than the <a href="https://robbelroot.de/blog/vbnet-openfiledialog-en/"><strong>OpenFileDialog</strong></a> because it only deals with folders, not files. There is no <code>Filter</code> or <code>Multiselect</code> property.</p>



<h2 class="wp-block-heading">Common mistakes</h2>



<h3 class="wp-block-heading">Using the path without checking DialogResult</h3>



<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="">' BAD - SelectedPath is empty if user cancels
dlg.ShowDialog()
Dim files = Directory.GetFiles(dlg.SelectedPath)

' GOOD - check the result first
If dlg.ShowDialog() = DialogResult.OK Then
    Dim files = Directory.GetFiles(dlg.SelectedPath)
End If</pre>



<h3 class="wp-block-heading">Confusing RootFolder and SelectedPath</h3>



<p><code>RootFolder</code> limits which folders the user can see. <code>SelectedPath</code> pre-selects a folder within the visible tree. If you set <code>RootFolder = MyDocuments</code>, the user cannot navigate outside of Documents. If you only want to suggest a starting point but allow full navigation, use <code>SelectedPath</code> instead.</p>



<h3 class="wp-block-heading">Forgetting the Using block</h3>



<p>Like all WinForms dialogs, the FolderBrowserDialog holds unmanaged resources. Without <code>Using</code>, those resources stay in memory until the garbage collector runs. Always wrap it in a <code>Using</code> block.</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 expert support?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Looking for an experienced .NET developer?</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&#039;ll take on your project, from file operations to finished desktop applications. Just drop 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 a project</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-folderbrowser-en-1"><strong class="schema-faq-question"><strong>How do I open a FolderBrowserDialog in VB.NET?</strong></strong> <p class="schema-faq-answer">Create a <code>New FolderBrowserDialog()</code> inside a <code>Using</code> block, optionally set <code>Description</code>, then call <code>ShowDialog()</code>. Check if the result equals <code>DialogResult.OK</code> before reading <code>dlg.SelectedPath</code>.</p> </div> <div class="schema-faq-section" id="faq-folderbrowser-en-2"><strong class="schema-faq-question"><strong>How do I set the default folder in FolderBrowserDialog?</strong></strong> <p class="schema-faq-answer">Set <code>dlg.SelectedPath</code> to the desired folder path before calling <code>ShowDialog()</code>. The dialog opens with that folder highlighted. Do not confuse this with <code>RootFolder</code>, which restricts the visible tree.</p> </div> <div class="schema-faq-section" id="faq-folderbrowser-en-3"><strong class="schema-faq-question"><strong>Can I hide the New Folder button?</strong></strong> <p class="schema-faq-answer">Yes. Set <code>dlg.ShowNewFolderButton = False</code> before calling <code>ShowDialog()</code>. This is useful for read-only operations where the user should only select an existing folder.</p> </div> <div class="schema-faq-section" id="faq-folderbrowser-en-4"><strong class="schema-faq-question"><strong>What is the difference between RootFolder and SelectedPath?</strong></strong> <p class="schema-faq-answer"><code>RootFolder</code> limits the top-level node the user can browse, restricting navigation. <code>SelectedPath</code> pre-selects a folder within the visible tree without restricting navigation. Use <code>SelectedPath</code> when you want a starting point but full access.</p> </div> <div class="schema-faq-section" id="faq-folderbrowser-en-5"><strong class="schema-faq-question"><strong>Can the user select multiple folders?</strong></strong> <p class="schema-faq-answer">No. The built-in <code>FolderBrowserDialog</code> only supports selecting a single folder. If you need multiple folder selection, you would need to call the dialog multiple times or use a custom solution.</p> </div> </div>



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



<p>The <code>FolderBrowserDialog</code> gives your VB.NET application a native folder picker with minimal code. Set <code>SelectedPath</code> to suggest a starting folder, use <code>RootFolder</code> to restrict navigation, and hide the New Folder button with <code>ShowNewFolderButton = False</code> when the user should only select existing folders. After the dialog closes, combine <code>SelectedPath</code> with <code>Directory.GetFiles()</code> to process folder contents. For picking individual files, use the <a href="https://robbelroot.de/blog/vbnet-openfiledialog-en/"><strong>OpenFileDialog</strong></a>. To save files, see the <a href="https://robbelroot.de/blog/vbnet-savefiledialog-en/"><strong>SaveFileDialog</strong></a>.</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-folderbrowserdialog-en/">VB.NET FolderBrowserDialog – Pick Folders Easily (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vbnet-folderbrowserdialog-en/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>VB.NET FolderBrowserDialog – Ordner auswählen (2026)</title>
		<link>https://robbelroot.de/blog/vbnet-folderbrowserdialog/</link>
					<comments>https://robbelroot.de/blog/vbnet-folderbrowserdialog/#respond</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Wed, 08 Apr 2026 21:28:17 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Visual Basic .NET]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=20475</guid>

					<description><![CDATA[<p>Der VB.NET FolderBrowserDialog lässt den Benutzer einen Ordner aus dem Dateisystem auswählen, bevor deine Anwendung dessen Inhalte verarbeitet. Er zeigt den Standard-Windows-Ordnerdialog an, gibt den gewählten Pfad zurück und kann den sichtbaren Bereich optional einschränken. Dieser Guide behandelt Einrichtung, Stammordner-Konfiguration, Ordnererstellung, Batch-Verarbeitung und häufige Fehler. Was ist der FolderBrowserDialog? Der &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-folderbrowserdialog/">VB.NET FolderBrowserDialog – Ordner auswählen (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Der <strong>VB.NET FolderBrowserDialog</strong> lässt den Benutzer einen Ordner aus dem Dateisystem auswählen, bevor deine Anwendung dessen Inhalte verarbeitet. Er zeigt den Standard-Windows-Ordnerdialog an, gibt den gewählten Pfad zurück und kann den sichtbaren Bereich optional einschränken. Dieser Guide behandelt Einrichtung, Stammordner-Konfiguration, Ordnererstellung, Batch-Verarbeitung und häufige Fehler.</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;">.NET-Hilfe gesucht?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Du baust eine Desktop-Anwendung?</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;">Ich entwickle seit über 17 Jahren professionell in VB.NET und C#. Von Ordnerdialogen bis zur kompletten WinForms-Anwendung kann ich helfen.</p>
    
    <div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;">

            <a href="https://robbelroot.de/kontakt/"
         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'"
      >→ Projekt anfragen</a>
      
      
    </div>
  </div>
</div>
	





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



<p>Der <code>FolderBrowserDialog</code> ist ein WinForms-Control aus <code>System.Windows.Forms</code>. Beim Aufruf von <code>ShowDialog()</code> öffnet sich der Windows-Ordnerdialog. Der Benutzer navigiert durch den Ordnerbaum, wählt einen Ordner aus und klickt OK. Dein Code erhält dann den vollständigen Ordnerpfad über die Eigenschaft <code>SelectedPath</code>.</p>



<p>Verwende ihn, wenn:</p>



<ul class="wp-block-list">
<li>Der Benutzer einen <strong>Ausgabeordner</strong> für Exporte, Backups oder Berichte wählen soll</li>



<li>Deine Anwendung <strong>alle Dateien eines Verzeichnisses</strong> verarbeiten muss</li>



<li>Der Benutzer ein <strong>Installations- oder Arbeitsverzeichnis</strong> auswählen soll</li>



<li>Der Benutzer <strong>einen neuen Ordner anlegen</strong> können soll</li>
</ul>



<p>Falls der Benutzer stattdessen eine einzelne Datei auswählen soll, verwende den <a href="https://robbelroot.de/blog/vbnet-openfiledialog/"><strong>OpenFileDialog</strong></a>. Zum Speichern einer Datei an einem bestimmten Ort verwende den <a href="https://robbelroot.de/blog/vbnet-savefiledialog/"><strong>SaveFileDialog</strong></a>.</p>



<h2 class="wp-block-heading">Einfaches Beispiel</h2>



<p>Der einfachste FolderBrowserDialog, der den gewählten Pfad anzeigt:</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="">Using dlg As New FolderBrowserDialog()
    dlg.Description = "Ordner auswählen"

    If dlg.ShowDialog() = DialogResult.OK Then
        MessageBox.Show($"Gewählt: {dlg.SelectedPath}")
    End If
End Using</pre>



<p>Der <code>Using</code>-Block gibt den Dialog nach der Verwendung frei. <code>ShowDialog()</code> gibt <code>DialogResult.OK</code> zurück, wenn der Benutzer bestätigt, oder <code>DialogResult.Cancel</code>, wenn er den Dialog schließt. Prüfe immer das Ergebnis, bevor du den Pfad verwendest.</p>



<h2 class="wp-block-heading">Stammordner einschränken</h2>



<p>Die <code>RootFolder</code>-Eigenschaft legt fest, welcher Knotenpunkt als oberste Ebene im Dialog angezeigt wird. Sie akzeptiert Werte aus <code>Environment.SpecialFolder</code>:</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="">Using dlg As New FolderBrowserDialog()
    ' Nur Ordner innerhalb des Desktops anzeigen
    dlg.RootFolder = Environment.SpecialFolder.Desktop
    dlg.Description = "Projektordner auswählen"

    If dlg.ShowDialog() = DialogResult.OK Then
        Dim folder As String = dlg.SelectedPath
    End If
End Using</pre>



<p>Gängige Werte für <code>RootFolder</code>:</p>



<ul class="wp-block-list">
<li><code>Environment.SpecialFolder.Desktop</code> (Standard) zeigt den kompletten Baum ab dem Desktop</li>



<li><code>Environment.SpecialFolder.MyComputer</code> zeigt alle Laufwerke</li>



<li><code>Environment.SpecialFolder.MyDocuments</code> beschränkt das Browsen auf den Dokumente-Ordner</li>
</ul>



<h2 class="wp-block-heading">Ordner vorauswählen</h2>



<p>Verwende <code>SelectedPath</code>, um beim Öffnen des Dialogs einen Ordner vorzuwählen. Das ist nützlich, wenn der Benutzer zuvor bereits einen Ordner gewählt hat und du dir den merken willst:</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="">Using dlg As New FolderBrowserDialog()
    dlg.Description = "Exportordner auswählen"
    dlg.SelectedPath = "C:\Users\Public\Documents"

    If dlg.ShowDialog() = DialogResult.OK Then
        Dim exportFolder As String = dlg.SelectedPath
    End If
End Using</pre>



<p>Der Dialog öffnet sich mit diesem Ordner bereits markiert. Falls der Pfad nicht existiert, springt der Dialog zum Stammordner zurück.</p>



<h2 class="wp-block-heading">Neuer-Ordner-Button ausblenden</h2>



<p>Standardmäßig enthält der Dialog einen &#8222;Neuen Ordner erstellen&#8220;-Button. Wenn der Benutzer nur einen existierenden Ordner auswählen soll, deaktiviere ihn:</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="">Using dlg As New FolderBrowserDialog()
    dlg.Description = "Vorhandenen Ordner auswählen"
    dlg.ShowNewFolderButton = False

    If dlg.ShowDialog() = DialogResult.OK Then
        Dim folder As String = dlg.SelectedPath
    End If
End Using</pre>



<p>Setze <code>ShowNewFolderButton = False</code> für reine Leseoperationen wie den Import von Dateien. Lass ihn auf <code>True</code> (Standard), wenn der Benutzer eventuell einen Zielordner für Exporte anlegen muss.</p>



<h2 class="wp-block-heading">Komplettes Beispiel: Dateien im Batch verarbeiten</h2>



<p>Ein realistisches Beispiel, das den Benutzer einen Ordner auswählen lässt und dann alle Textdateien darin verarbeitet:</p>



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

Private Sub BtnImportieren_Click(sender As Object, e As EventArgs) Handles BtnImportieren.Click
    Using dlg As New FolderBrowserDialog()
        dlg.Description = "Ordner mit Textdateien auswählen"
        dlg.ShowNewFolderButton = False

        If dlg.ShowDialog() = DialogResult.OK Then
            Dim files() As String = Directory.GetFiles(
                dlg.SelectedPath, "*.txt")

            For Each filePath In files
                Dim content As String = File.ReadAllText(
                    filePath, Encoding.UTF8)
                ' Jede Datei verarbeiten...
            Next

            MessageBox.Show($"{files.Length} Dateien verarbeitet.")
        End If
    End Using
End Sub</pre>



<p><code>Directory.GetFiles()</code> gibt alle passenden Dateien im gewählten Ordner zurück. Verwende den zweiten Parameter für Muster, z.B. <code>"*.csv"</code> oder <code>"*.xml"</code>. Mehr zum Lesen von Textdateien findest du im <a href="https://robbelroot.de/blog/vbnet-textdatei-einlesen/"><strong>VB.NET Textdatei einlesen Guide</strong></a>.</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;">Projekt in Planung?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Brauchst du eine fertige WinForms-Anwendung?</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;">Von Dateidialogen bis zur kompletten datengetriebenen Desktop-App: Ich entwerfe Software, die hält. Lass uns über dein Projekt sprechen.</p>
    
    <div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;">

            <a href="https://robbelroot.de/kontakt/"
         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'"
      >→ Projekt anfragen</a>
      
      
    </div>
  </div>
</div>
	


<h2 class="wp-block-heading">Unterordner einbeziehen</h2>



<p>Um Dateien rekursiv zu verarbeiten, füge <code>SearchOption.AllDirectories</code> hinzu:</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 dlg.ShowDialog() = DialogResult.OK Then
    Dim files() As String = Directory.GetFiles(
        dlg.SelectedPath, "*.txt", SearchOption.AllDirectories)

    For Each filePath In files
        Dim relativePath As String = filePath.Replace(
            dlg.SelectedPath & "\", "")
        ' Datei mit relativem Pfad verarbeiten...
    Next
End If</pre>



<p>Das durchsucht den gewählten Ordner und alle seine Unterordner. Sei vorsichtig bei großen Verzeichnisbäumen, da dies bei Tausenden von Dateien eine Weile dauern kann.</p>



<h2 class="wp-block-heading">Environment.SpecialFolder verwenden</h2>



<p>Du kannst den Dialog mit <code>Environment.GetFolderPath()</code> kombinieren, um gängige Systemordner vorzuwählen. Du kannst auch den <a href="https://robbelroot.de/blog/vbnet-application-path/"><strong>Anwendungspfad</strong></a> als Startpunkt verwenden:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">' In Dokumente starten
Using dlg As New FolderBrowserDialog()
    dlg.SelectedPath = Environment.GetFolderPath(
        Environment.SpecialFolder.MyDocuments)

    If dlg.ShowDialog() = DialogResult.OK Then
        ' dlg.SelectedPath verwenden...
    End If
End Using

' Im Anwendungsverzeichnis starten
Using dlg As New FolderBrowserDialog()
    dlg.SelectedPath = Application.StartupPath

    If dlg.ShowDialog() = DialogResult.OK Then
        ' dlg.SelectedPath verwenden...
    End If
End Using</pre>



<h2 class="wp-block-heading">Alle wichtigen Eigenschaften im Überblick</h2>



<figure class="wp-block-table"><table><thead><tr><th>Eigenschaft</th><th>Standard</th><th>Zweck</th></tr></thead><tbody><tr><td><code>Description</code></td><td>(leer)</td><td>Text über dem Ordnerbaum</td></tr><tr><td><code>SelectedPath</code></td><td>(leer)</td><td>Vorgewählter / gewählter Ordner nach dem Dialog</td></tr><tr><td><code>RootFolder</code></td><td>Desktop</td><td>Oberstes Element im Ordnerbaum</td></tr><tr><td><code>ShowNewFolderButton</code></td><td>True</td><td>&#8222;Neuen Ordner erstellen&#8220;-Button ein- oder ausblenden</td></tr></tbody></table></figure>



<p>Der FolderBrowserDialog hat weniger Eigenschaften als der <a href="https://robbelroot.de/blog/vbnet-openfiledialog/"><strong>OpenFileDialog</strong></a>, weil er nur Ordner und keine Dateien behandelt. Es gibt keine <code>Filter</code>&#8211; oder <code>Multiselect</code>-Eigenschaft.</p>



<h2 class="wp-block-heading">Häufige Fehler</h2>



<h3 class="wp-block-heading">Pfad verwenden ohne DialogResult zu prüfen</h3>



<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="">' SCHLECHT - SelectedPath ist leer, wenn der Benutzer abbricht
dlg.ShowDialog()
Dim files = Directory.GetFiles(dlg.SelectedPath)

' GUT - Ergebnis zuerst prüfen
If dlg.ShowDialog() = DialogResult.OK Then
    Dim files = Directory.GetFiles(dlg.SelectedPath)
End If</pre>



<h3 class="wp-block-heading">RootFolder und SelectedPath verwechseln</h3>



<p><code>RootFolder</code> schränkt ein, welche Ordner der Benutzer sehen kann. <code>SelectedPath</code> wählt einen Ordner innerhalb des sichtbaren Baums vor. Wenn du <code>RootFolder = MyDocuments</code> setzt, kann der Benutzer nicht aus den Dokumenten herausnavigieren. Wenn du nur einen Startpunkt vorschlagen, aber volle Navigation erlauben willst, verwende stattdessen <code>SelectedPath</code>.</p>



<h3 class="wp-block-heading">Using-Block vergessen</h3>



<p>Wie alle WinForms-Dialoge hält der FolderBrowserDialog unverwaltete Ressourcen. Ohne <code>Using</code> bleiben diese Ressourcen im Speicher, bis der Garbage Collector läuft. Wickle ihn immer in einen <code>Using</code>-Block ein.</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;">Interessiert?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Erfahrenen .NET-Entwickler gesucht?</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;">Ich übernehme dein Projekt, von Dateioperationen bis zur fertigen Desktop-Anwendung. Schreib mir einfach eine Nachricht.</p>
    
    <div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center;">

            <a href="https://robbelroot.de/kontakt/"
         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'"
      >→ Projekt anfragen</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-folderbrowser-de-1"><strong class="schema-faq-question"><strong>Wie öffne ich einen FolderBrowserDialog in VB.NET?</strong></strong> <p class="schema-faq-answer">Erstelle einen <code>New FolderBrowserDialog()</code> in einem <code>Using</code>-Block, setze optional <code>Description</code> und rufe <code>ShowDialog()</code> auf. Prüfe, ob das Ergebnis <code>DialogResult.OK</code> ist, bevor du <code>dlg.SelectedPath</code> verwendest.</p> </div> <div class="schema-faq-section" id="faq-folderbrowser-de-2"><strong class="schema-faq-question"><strong>Wie setze ich den Standardordner im FolderBrowserDialog?</strong></strong> <p class="schema-faq-answer">Setze <code>dlg.SelectedPath</code> auf den gewünschten Ordnerpfad, bevor du <code>ShowDialog()</code> aufrufst. Der Dialog öffnet sich mit diesem Ordner markiert. Verwechsle das nicht mit <code>RootFolder</code>, das den sichtbaren Baum einschränkt.</p> </div> <div class="schema-faq-section" id="faq-folderbrowser-de-3"><strong class="schema-faq-question"><strong>Kann ich den Neuer-Ordner-Button ausblenden?</strong></strong> <p class="schema-faq-answer">Ja. Setze <code>dlg.ShowNewFolderButton = False</code> vor dem Aufruf von <code>ShowDialog()</code>. Das ist nützlich für reine Leseoperationen, bei denen der Benutzer nur einen bestehenden Ordner auswählen soll.</p> </div> <div class="schema-faq-section" id="faq-folderbrowser-de-4"><strong class="schema-faq-question"><strong>Was ist der Unterschied zwischen RootFolder und SelectedPath?</strong></strong> <p class="schema-faq-answer"><code>RootFolder</code> begrenzt das oberste Element, das der Benutzer durchsuchen kann, und schränkt die Navigation ein. <code>SelectedPath</code> wählt einen Ordner innerhalb des sichtbaren Baums vor, ohne die Navigation einzuschränken. Verwende <code>SelectedPath</code>, wenn du einen Startpunkt willst, aber vollen Zugriff erlauben möchtest.</p> </div> <div class="schema-faq-section" id="faq-folderbrowser-de-5"><strong class="schema-faq-question"><strong>Kann der Benutzer mehrere Ordner auswählen?</strong></strong> <p class="schema-faq-answer">Nein. Der eingebaute <code>FolderBrowserDialog</code> unterstützt nur die Auswahl eines einzelnen Ordners. Für die Auswahl mehrerer Ordner müsstest du den Dialog mehrfach aufrufen oder eine eigene Lösung implementieren.</p> </div> </div>



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



<p>Der <code>FolderBrowserDialog</code> gibt deiner VB.NET-Anwendung einen nativen Ordnerdialog mit minimalem Code. Setze <code>SelectedPath</code> um einen Startordner vorzuschlagen, verwende <code>RootFolder</code> um die Navigation einzuschränken, und blende den Neuer-Ordner-Button mit <code>ShowNewFolderButton = False</code> aus, wenn der Benutzer nur existierende Ordner wählen soll. Nach dem Dialog kombiniere <code>SelectedPath</code> mit <code>Directory.GetFiles()</code> um den Ordnerinhalt zu verarbeiten. Für die Auswahl einzelner Dateien verwende den <a href="https://robbelroot.de/blog/vbnet-openfiledialog/"><strong>OpenFileDialog</strong></a>. Zum Speichern von Dateien siehe den <a href="https://robbelroot.de/blog/vbnet-savefiledialog/"><strong>SaveFileDialog</strong></a>.</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-folderbrowserdialog/">VB.NET FolderBrowserDialog – Ordner auswählen (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vbnet-folderbrowserdialog/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>VB.NET OpenFileDialog – Open Files with Dialog (2026)</title>
		<link>https://robbelroot.de/blog/vbnet-openfiledialog-en/</link>
					<comments>https://robbelroot.de/blog/vbnet-openfiledialog-en/#respond</comments>
		
		<dc:creator><![CDATA[Robert Skibbe]]></dc:creator>
		<pubDate>Wed, 08 Apr 2026 21:16:14 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Visual Basic .NET (EN)]]></category>
		<guid isPermaLink="false">https://robbelroot.de/?p=20470</guid>

					<description><![CDATA[<p>The VB.NET OpenFileDialog lets users pick one or more files to open before your application reads them. It handles path selection, file type filtering, and file-exists validation in a single control. This guide covers setup, filters, multi-select, common patterns, and integration with actual file reading. What is the OpenFileDialog? The &#8230;</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-openfiledialog-en/">VB.NET OpenFileDialog – Open Files with Dialog (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>The <strong>VB.NET OpenFileDialog</strong> lets users pick one or more files to open before your application reads them. It handles path selection, file type filtering, and file-exists validation in a single control. This guide covers setup, filters, multi-select, common patterns, and integration with actual file reading.</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 .NET help?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Building a desktop application?</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&#039;ve been developing professionally in VB.NET and C# for over 17 years. From file dialogs to complete WinForms applications, I can help.</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 a project</a>
      
      
    </div>
  </div>
</div>
	





<h2 class="wp-block-heading">What is the OpenFileDialog?</h2>



<p>The <code>OpenFileDialog</code> is a WinForms control from <code>System.Windows.Forms</code>. When you call <code>ShowDialog()</code>, it opens the standard Windows &#8222;Open&#8220; dialog. The user navigates to a folder, picks a file, and clicks Open. Your code then receives the full file path through the <code>FileName</code> property.</p>



<p>Use it when:</p>



<ul class="wp-block-list">
<li>The user should <strong>choose which file to open</strong> (imports, config files, images)</li>



<li>You need a <strong>file type filter</strong> (e.g. only .txt, .csv, or .png)</li>



<li>You want <strong>built-in validation</strong> that the selected file actually exists</li>



<li>You need to let the user <strong>select multiple files</strong> at once</li>
</ul>



<p>If you need the user to pick a save destination instead, use the <a href="https://robbelroot.de/blog/vbnet-savefiledialog-en/"><strong>SaveFileDialog</strong></a>.</p>



<h2 class="wp-block-heading">Basic example</h2>



<p>The simplest OpenFileDialog that reads a text file:</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="">Using dlg As New OpenFileDialog()
    dlg.Filter = "Text files (*.txt)|*.txt"
    dlg.Title = "Open text file"

    If dlg.ShowDialog() = DialogResult.OK Then
        Dim content As String = File.ReadAllText(dlg.FileName)
        TextBox1.Text = content
    End If
End Using</pre>



<p>The <code>Using</code> block disposes the dialog after use. <code>ShowDialog()</code> returns <code>DialogResult.OK</code> when the user clicks Open, or <code>DialogResult.Cancel</code> when they close the dialog. Always check the result before reading.</p>



<h2 class="wp-block-heading">Setting up file type filters</h2>



<p>The <code>Filter</code> property controls which file types appear in the dropdown. The syntax is identical to the <a href="https://robbelroot.de/blog/vbnet-savefiledialog-en/"><strong>SaveFileDialog</strong></a>:</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="">' Single filter
dlg.Filter = "Text files (*.txt)|*.txt"

' Multiple filters
dlg.Filter = "Text files (*.txt)|*.txt|CSV files (*.csv)|*.csv|All files (*.*)|*.*"

' Pre-select the second filter (1-based index)
dlg.FilterIndex = 2

' Allow multiple extensions in one filter
dlg.Filter = "Images (*.png;*.jpg;*.gif)|*.png;*.jpg;*.gif"</pre>



<p>To combine multiple extensions in a single filter entry, separate them with semicolons inside the pattern part: <code>*.png;*.jpg;*.gif</code>. The user sees one &#8222;Images&#8220; dropdown entry that matches all three types.</p>



<h2 class="wp-block-heading">Setting the default folder</h2>



<pre class="EnlighterJSRAW" data-enlighter-language="visualbasic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Using dlg As New OpenFileDialog()
    ' Start in the user's Documents folder
    dlg.InitialDirectory = Environment.GetFolderPath(
        Environment.SpecialFolder.MyDocuments)

    dlg.Filter = "CSV files (*.csv)|*.csv"

    If dlg.ShowDialog() = DialogResult.OK Then
        Dim content As String = File.ReadAllText(dlg.FileName)
    End If
End Using</pre>



<p>Common choices for <code>InitialDirectory</code>:</p>



<ul class="wp-block-list">
<li><code>Environment.SpecialFolder.MyDocuments</code> for user documents</li>



<li><code>Environment.SpecialFolder.Desktop</code> for the desktop</li>



<li>The <a href="https://robbelroot.de/blog/vbnet-application-path-en/"><strong>application path</strong></a> for files next to the executable</li>
</ul>



<p>If you don&#8217;t set <code>InitialDirectory</code>, the dialog remembers the last folder the user navigated to during the current session.</p>



<h2 class="wp-block-heading">Selecting multiple files</h2>



<p>Set <code>Multiselect = True</code> to let the user select more than one file. The selected paths are available through <code>FileNames</code> (plural):</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="">Using dlg As New OpenFileDialog()
    dlg.Filter = "Images (*.png;*.jpg)|*.png;*.jpg"
    dlg.Multiselect = True
    dlg.Title = "Select images to import"

    If dlg.ShowDialog() = DialogResult.OK Then
        For Each filePath In dlg.FileNames
            Dim img As Image = Image.FromFile(filePath)
            ' Process each image...
        Next

        MessageBox.Show($"{dlg.FileNames.Length} files selected.")
    End If
End Using</pre>



<p>The user holds Ctrl to pick individual files, or Shift to select a range. <code>FileName</code> (singular) still returns the first selected file; <code>FileNames</code> returns all of them as a <code>String()</code> array.</p>



<h2 class="wp-block-heading">Complete example: reading a text file</h2>



<p>A realistic example that reads a text file with encoding support, using <a href="https://robbelroot.de/blog/vbnet-read-text-file/"><strong>ReadAllText</strong></a>:</p>



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

Private Sub BtnOpen_Click(sender As Object, e As EventArgs) Handles BtnOpen.Click
    Using dlg As New OpenFileDialog()
        dlg.Title = "Open report"
        dlg.Filter = "Text files (*.txt)|*.txt|CSV files (*.csv)|*.csv|All files (*.*)|*.*"
        dlg.InitialDirectory = Environment.GetFolderPath(
            Environment.SpecialFolder.MyDocuments)

        If dlg.ShowDialog() = DialogResult.OK Then
            Dim content As String = File.ReadAllText(dlg.FileName, Encoding.UTF8)
            TextBox1.Text = content
            Me.Text = $"Editor - {Path.GetFileName(dlg.FileName)}"
        End If
    End Using
End Sub</pre>



<p>Specify <code>Encoding.UTF8</code> when reading text files to correctly handle special characters. <code>Path.GetFileName()</code> extracts just the file name from the full path, which is useful for setting the window title.</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;">Planning a project?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Need a polished WinForms application?</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;">From file dialogs to complete data-driven desktop apps: I design software that lasts. Let&#039;s talk about your project.</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 a project</a>
      
      
    </div>
  </div>
</div>
	


<h2 class="wp-block-heading">Reading binary files (images, PDFs)</h2>



<p>OpenFileDialog works the same way for binary content. Only the read method changes:</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="">' Load an image into a PictureBox
Using dlg As New OpenFileDialog()
    dlg.Filter = "Images (*.png;*.jpg;*.bmp)|*.png;*.jpg;*.bmp"

    If dlg.ShowDialog() = DialogResult.OK Then
        PictureBox1.Image = Image.FromFile(dlg.FileName)
    End If
End Using

' Read a file as byte array
Using dlg As New OpenFileDialog()
    dlg.Filter = "All files (*.*)|*.*"

    If dlg.ShowDialog() = DialogResult.OK Then
        Dim bytes() As Byte = File.ReadAllBytes(dlg.FileName)
        ' Process bytes...
    End If
End Using</pre>



<h2 class="wp-block-heading">Reading large files with StreamReader</h2>



<p>For large files or line-by-line processing, use a <code>StreamReader</code> with the path from the dialog:</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="">Using dlg As New OpenFileDialog()
    dlg.Filter = "CSV files (*.csv)|*.csv"

    If dlg.ShowDialog() = DialogResult.OK Then
        Using reader As New StreamReader(dlg.FileName, Encoding.UTF8)
            Dim lineNumber As Integer = 0
            While Not reader.EndOfStream
                Dim line As String = reader.ReadLine()
                lineNumber += 1
                ' Process each line...
            End While
        End Using
    End If
End Using</pre>



<p>The <code>StreamReader</code> approach is more memory-efficient for large files because it reads line by line instead of loading the entire file into memory. For more on reading text files, see the <a href="https://robbelroot.de/blog/vbnet-read-text-file/"><strong>VB.NET Read Text File guide</strong></a>.</p>



<h2 class="wp-block-heading">All important properties at a glance</h2>



<figure class="wp-block-table"><table><thead><tr><th>Property</th><th>Default</th><th>Purpose</th></tr></thead><tbody><tr><td><code>Filter</code></td><td>(empty)</td><td>File type dropdown entries</td></tr><tr><td><code>FilterIndex</code></td><td>1</td><td>Pre-selected filter (1-based)</td></tr><tr><td><code>FileName</code></td><td>(empty)</td><td>Selected file path after dialog closes</td></tr><tr><td><code>FileNames</code></td><td>(empty)</td><td>All selected paths when Multiselect is True</td></tr><tr><td><code>InitialDirectory</code></td><td>(empty)</td><td>Starting folder</td></tr><tr><td><code>Multiselect</code></td><td>False</td><td>Allow selecting multiple files</td></tr><tr><td><code>CheckFileExists</code></td><td>True</td><td>Reject paths that don&#8217;t exist</td></tr><tr><td><code>CheckPathExists</code></td><td>True</td><td>Reject invalid folder paths</td></tr><tr><td><code>Title</code></td><td>&#8222;Open&#8220;</td><td>Dialog window title</td></tr><tr><td><code>ReadOnlyChecked</code></td><td>False</td><td>Pre-check the &#8222;Open as read-only&#8220; checkbox</td></tr></tbody></table></figure>



<h2 class="wp-block-heading">Common mistakes</h2>



<h3 class="wp-block-heading">Reading without checking DialogResult</h3>



<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="">' BAD - FileName is empty if user cancels
dlg.ShowDialog()
Dim content = File.ReadAllText(dlg.FileName)

' GOOD - check the result first
If dlg.ShowDialog() = DialogResult.OK Then
    Dim content = File.ReadAllText(dlg.FileName)
End If</pre>



<h3 class="wp-block-heading">Using FileName instead of FileNames with Multiselect</h3>



<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="">' BAD - only gets the first file when Multiselect is True
dlg.Multiselect = True
If dlg.ShowDialog() = DialogResult.OK Then
    Dim content = File.ReadAllText(dlg.FileName)  ' only first file!
End If

' GOOD - iterate all selected files
If dlg.ShowDialog() = DialogResult.OK Then
    For Each path In dlg.FileNames
        Dim content = File.ReadAllText(path)
    Next
End If</pre>



<h3 class="wp-block-heading">Forgetting the Using block</h3>



<p>The OpenFileDialog holds unmanaged resources (a Windows COM object). Without <code>Using</code>, those resources stay in memory until the garbage collector runs. Always wrap it in a <code>Using</code> block.</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 expert support?</div>
    
        <p style="margin:0 0 10px 0;font-size:clamp(17px,4vw,21px);font-weight:700;color:#ffffff;line-height:1.35;">Looking for an experienced .NET developer?</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&#039;ll take on your project, from file operations to finished desktop applications. Just drop 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 a project</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-openfile-en-1"><strong class="schema-faq-question"><strong>How do I open an OpenFileDialog in VB.NET?</strong></strong> <p class="schema-faq-answer">Create a <code>New OpenFileDialog()</code> inside a <code>Using</code> block, set the <code>Filter</code> property, then call <code>ShowDialog()</code>. Check if the result equals <code>DialogResult.OK</code> before reading from <code>dlg.FileName</code>.</p> </div> <div class="schema-faq-section" id="faq-openfile-en-2"><strong class="schema-faq-question"><strong>How do I select multiple files with OpenFileDialog?</strong></strong> <p class="schema-faq-answer">Set <code>dlg.Multiselect = True</code> before calling <code>ShowDialog()</code>. The user can then hold Ctrl or Shift to select several files. Access all paths through <code>dlg.FileNames</code> (plural).</p> </div> <div class="schema-faq-section" id="faq-openfile-en-3"><strong class="schema-faq-question"><strong>How do I filter file types in OpenFileDialog?</strong></strong> <p class="schema-faq-answer">Set the <code>Filter</code> property with the pattern <code>Description|*.ext</code>. For multiple types, separate with pipes: <code>"Text (*.txt)|*.txt|CSV (*.csv)|*.csv"</code>. Combine extensions with semicolons: <code>"Images (*.png;*.jpg)|*.png;*.jpg"</code>.</p> </div> <div class="schema-faq-section" id="faq-openfile-en-4"><strong class="schema-faq-question"><strong>Does OpenFileDialog actually read the file?</strong></strong> <p class="schema-faq-answer">No. The dialog only lets the user pick a file path. You are responsible for reading the file yourself using methods like <code>File.ReadAllText()</code>, <code>File.ReadAllBytes()</code>, or a StreamReader with the path from <code>dlg.FileName</code>.</p> </div> <div class="schema-faq-section" id="faq-openfile-en-5"><strong class="schema-faq-question"><strong>What is the difference between OpenFileDialog and SaveFileDialog?</strong></strong> <p class="schema-faq-answer">OpenFileDialog lets the user pick an existing file to read, with file-exists validation built in. SaveFileDialog lets the user pick a destination for writing a new file, with overwrite confirmation. Both return the selected path through <code>FileName</code>.</p> </div> </div>



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



<p>The <code>OpenFileDialog</code> gives your VB.NET application a native file-open experience with minimal code. Set a <code>Filter</code> for file types, enable <code>Multiselect</code> for batch operations, and always check <code>DialogResult.OK</code> before reading. For the actual file reading, use <code>File.ReadAllText()</code> for text or <code>File.ReadAllBytes()</code> for binary data. Need to save files instead? The <a href="https://robbelroot.de/blog/vbnet-savefiledialog-en/"><strong>SaveFileDialog</strong></a> follows the same pattern. For more on reading text files, see the <a href="https://robbelroot.de/blog/vbnet-read-text-file/"><strong>VB.NET Read Text File guide</strong></a>.</p>
<p>Der Beitrag <a href="https://robbelroot.de/blog/vbnet-openfiledialog-en/">VB.NET OpenFileDialog – Open Files with Dialog (2026)</a> erschien zuerst auf <a href="https://robbelroot.de">Robert Skibbe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://robbelroot.de/blog/vbnet-openfiledialog-en/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
