WPF: How to fix MessageBox, WindowsFormsHost and other controls not using visual styles in C# and VB

So you've just created a WPF (Windows Presentation Foundation) app, designed a UI in XAML (Extensible Application Markup Language) and programmed a button to show a MessageBox. You then run the app on a modern version of Windows and show the MessageBox, only to realise that the MessageBox looks like it's showing on Windows 95 or some other older version of Windows! And this happens, even when running the app on Windows 11; the latest version of Windows. Believe it or not, this is not a bug - and it happens to other controls as well, such as the ColorDialog control from the System.Windows.Forms namespace and even Windows Forms controls shown in the WindowsFormsHost. The reason this occurs is because WPF apps do not opt in to GDI visual styles by default. GDI (Graphics Driver Interface) has been around since the initial release of Windows and is used for rendering graphics. All of the above mentioned controls that have this issue use GDI, including the Windows Forms ones because Windows Forms uses GDI to render its content. When GDI controls are rendered without visual styles, they use that old Windows 95 - ME look, also know as the Windows classic style since Windows XP. WPF on the other hand, has its own rendering engine and its own visual style system separate from GDI and WPF does not does not revert to the Windows classic style if the app hasn't opted into GDI visual styles. That being said, the MessageBox control in the System.Windows namespace still uses GDI and not WPF to render the MessageBox's content.

A WPF app. Note the Windows Forms controls and MessageBox are using the Windows classic style
A WPF app. Note the Windows Forms controls and MessageBox are using the Windows classic style.

Tip: You may notice in the above screenshot that the WPF controls look like they would on Windows 10, even though it's running on Windows 11. See here for more information.

The fix

Luckily, the fix for most of these issues is as simple as one line of code. There's a function in the System.Windows.Forms namespace called EnableVisualStyles. Simply call this function when your app starts up and your app will opt into visual styles - ColorDialogs, WindowsFormsHosts and other controls will now look much more native to the operating system the app is running on. You could call this function on the Startup event in App.xaml.cs/Application.xaml.vb.

C#:

Forms.Application.EnableVisualStyles();


VB:

Forms.Application.EnableVisualStyles()


Note: If you get errors and you are using .Net Framework, go to the solution explorer, right click References under your project,  click Add Reference..., select Assemblies, search up Forms and add  'System.Windows.Forms'. If you are using .Net Core and have this issue, right click the project file and select 'Edit Project File' and add ' <UseWindowsForms>true</UseWindowsForms>' to '<PropertyGroup>' at the start of the file.

This should result in Windows Forms controls, ColorDialogs and more using visual styles, making them look much more native and better following the user's system theme preferences: For more info from Microsoft on this fix, go here.

A WPF app that has opted in to GDI visual styles. Note the Windows Forms controls and MessageBox are using the standard Windows 11 style.
A WPF app that has opted in to GDI visual styles. Note the Windows Forms controls and MessageBox are using the standard Windows 11 style.

Tip: You may notice in the above screenshot that the WPF controls look like they would on Windows 10, even though it's running on Windows 11. See here for more information.

But what about the MessageBox?

If message boxes still don't use visual styles after enabling them, try using Microsoft.VisualBasic.Interaction.MsgBox instead (In case you were wondering, yes, despite having Visual Basic in its name, this function can be called from C#) - we found that using the System.Windows.MessageBox function would, for some reason, still not use visual styles even after they had been opted into, while the MsgBox function did. The MsgBox function is very similar to MessageBox.Show and so if you've used MessageBox.Show, MsgBox should be pretty easy to get the hang of. 
Note: If you're using C# and can't find this function, if you're using the .Net Framework, go to the solution explorer, right click References under your project, click Add Reference..., select Assemblies and then add Microsoft.VisualBasic. Unfortunately, this function doesn't seem to be available in .Net Core 3.0 or 3.1 but it is available in .Net 5 and above. If you know any other way to fix this, feel free to let us know in the comments! Using this function with visual styles enabled, should result in a properly styled message box:

A WPF app that has opted in to GDI visual styles and uses MsgBox to show a message box. Note the MessageBox is using the standard Windows 11 style.
A WPF app that has opted in to GDI visual styles and uses MsgBox to show a message box. Note the MessageBox is using the standard Windows 11 style.

Bonus tip: If a control looks a little strange with visual styles enable, check to see if it has a UseVisualStyleBackColor property and if it does, try setting that to true. If the control has a FlatStyle property, try setting that to System.

Also, if this guide helped you and you use an AdBlocker and you want to support us, consider disabling it for this site - if you do, it will be greatly appreciated!

Follow us to be notified when we release new guides:

This snippet is available in Codly. Click the appropriate link below to download the snippet. If you don't have Codly, it is available here in the Microsoft Store.

Comments

Popular posts from this blog

How to show placeholder text in a WPF TextBox in C# and VB

How to enable dark title bar in WPF and Windows Forms/WinForms apps in C# and VB

How to use modern icons in XAML in WPF on Windows 10 and 11

How to change the colour of a WPF or Windows Forms/WinForms title bar in Windows 11 in C# and VB

Microsoft WebView2: How to check if the WebView2 runtime is installed in C# and VB