This is a simple WPF tutorial that teaches the basics of building a WPF (.NET Core) application to customize, preview, generate QR Code barcode images on the WPF Windows Form.
After finish the tutorial, you can also further customize the C# to add more barcode options, such as generating styled QR Code with logo image inside.
1. Create a new WPF (.NET Core) app
Here we will quickly create a new ASP.NET Core web app using Visual Studio .NET
Start Visual Studio and select Create a new project
In the Create a new project dialog, select WPF Application, and select button Next.
In the Configure your new project dialog, enter BarcodeLib.Create.WPFCoreDemo for Project name. It is important to
name the proejct BarcodeLib.Create.WPFCoreDemo, including letter case, so the namespaces will match when you copy, paste the following
C# example source code.
Select button Create
In the Additional information diaplog, select .NET 6.0 or .NET 7.0 for the Framework dropdowns.
Select button Create.
Now we have created a new WPF application project successfully.
2. Install Barcode Generator library and Nuget package
Now we will add and install BarcodeLib C# barcode generator library (dll file) to the new WPF application project
and also add the a Nuget package named "System.Drawing.Common".
Add BarcodeLib C# Barcode Generator library
In the Solution Explorer window, right click Dependencies, select Add Project Reference...
Select button Browse... in the Reference Manager dialog.
Choose dll file BarcodeLib.Barcode.Common.dll from BarcodeLib downloaded package /Dll/net-standard/
Check BarcodeLib.Barcode.Common.dll is selected, and select button OK
Now we have added the barcodelib barcode generator library dll to the WPF project.
We will start to add a library "System.Drawing.Common" from Nuget
Install NuGet Package
Right click Dependencies, select Manage NuGet Packages...
Navigate to tab Browse in the NuGet Package Manager
Enter System.Drawing.Common to search NuGet package
Choose the first searched result System.Drawing.Common by Microsoft
Select button Install
Now we have added the C# barcode generator library dll file and nuget package to the WPF project successfully.
3. Apply function codes in the user interface in WPF Designer
Select and click MainWindow.xaml in the "Solution Explorer" to open the WPF Designer.
Add barcode setting option controls to customze the generated QR Code.
<GroupBoxHeader="QR Code Settings"Grid.Column="1"><Canvas><!-- Data to encode --><LabelContent="Data:"Canvas.Left="10"Canvas.Top="5"/><TextBoxName="tbData"Canvas.Left="110"Canvas.Top="10"Width="160"Height="90"TextWrapping="Wrap"/><!-- Barcode Width --><LabelContent="Barcode Width:"Canvas.Left="10"Canvas.Top="105"/><TextBoxName="tbBarcodeWidth"Canvas.Left="160"Canvas.Top="110"Width="60"/><LabelContent="inches"Canvas.Left="225"Canvas.Top="105"/><!-- Resolution --><LabelContent="Resolution:"Canvas.Left="10"Canvas.Top="135"/><TextBoxName="tbResolution"Canvas.Left="160"Canvas.Top="140"Width="60"/><LabelContent="dots per inch"Canvas.Left="225"Canvas.Top="135"/><!-- Fore Color --><LabelContent="Fore Color:"Canvas.Left="10"Canvas.Top="165"/><TextBoxName="tbForeColor"Canvas.Left="160"Canvas.Top="170"Width="60"/><RectangleName="rectForeColor"Canvas.Left="230"Canvas.Top="172"Width="15"Height="15"Stroke="Black"/><!-- Back Color --><LabelContent="Back Color:"Canvas.Left="10"Canvas.Top="195"/><TextBoxName="tbBackColor"Canvas.Left="160"Canvas.Top="200"Width="60"/><RectangleName="rectBackColor"Canvas.Left="230"Canvas.Top="202"Width="15"Height="15"Stroke="Black"/><!-- Preview --><ButtonName="btReview"Content="Review"Canvas.Left="60"Canvas.Bottom="20"Width="80"/><!-- Save --><ButtonName="btSave"Content="Save"Canvas.Left="180"Canvas.Bottom="20"Width="80"/></Canvas></GroupBox>
Now we can find the preview image control on the left and other barcode options controls on the right of the main window.
The xml code below is the complete code for MainWindow.xaml with controls events added.
Copy the following C# source code to set the barcode option controls default values.
<Windowx:Class="BarcodeLib.Create.WPFCoreDemo.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:BarcodeLib.Create.WPFCoreDemo"mc:Ignorable="d"Title="MainWindow"Height="450"Width="800"ResizeMode="NoResize"WindowStartupLocation="CenterScreen"><Grid><Grid.ColumnDefinitions><ColumnDefinitionWidth="480"/><ColumnDefinitionWidth="1*"/></Grid.ColumnDefinitions><GroupBoxHeader="Preview"Background="LightGray"></GroupBox><GroupBoxHeader="QR Code Settings"Grid.Column="1"></GroupBox><GroupBoxHeader="Preview"Background="LightGray"><BorderBorderThickness="2"BorderBrush="Blue"Width="404"Height="404"><ImageName="imgReview"Width="400"Height="400"/></Border></GroupBox><GroupBoxHeader="QR Code Settings"Grid.Column="1"><Canvas><!-- Data to encode --><LabelContent="Data:"Canvas.Left="10"Canvas.Top="5"/><TextBoxName="tbData"Canvas.Left="110"Canvas.Top="10"Width="160"Height="90"TextWrapping="Wrap"/><!-- Barcode Width --><LabelContent="Barcode Width:"Canvas.Left="10"Canvas.Top="105"/><TextBoxName="tbBarcodeWidth"Canvas.Left="150"Canvas.Top="110"Width="60"TextChanged="tbBarcodeWidth_TextChanged"PreviewTextInput="tbBarcodeWidth_PreviewTextInput"/><LabelContent="inches"Canvas.Left="215"Canvas.Top="105"/><!-- Resolution --><LabelContent="Resolution:"Canvas.Left="10"Canvas.Top="135"/><TextBoxName="tbResolution"Canvas.Left="150"Canvas.Top="140"Width="60"TextChanged="tbResolution_TextChanged"PreviewTextInput="tbResolution_PreviewTextInput"/><LabelContent="dots per inch"Canvas.Left="215"Canvas.Top="135"/><!-- Fore Color --><LabelContent="Fore Color:"Canvas.Left="10"Canvas.Top="165"/><TextBoxName="tbForeColor"Canvas.Left="150"Canvas.Top="170"Width="60"TextChanged="tbForeColor_TextChanged"PreviewTextInput="tbColor_PreviewTextInput"/><RectangleName="rectForeColor"Canvas.Left="220"Canvas.Top="172"Width="15"Height="15"Stroke="Black"/><!-- Back Color --><LabelContent="Back Color:"Canvas.Left="10"Canvas.Top="195"/><TextBoxName="tbBackColor"Canvas.Left="150"Canvas.Top="200"Width="60"TextChanged="tbBackColor_TextChanged"PreviewTextInput="tbColor_PreviewTextInput"/><RectangleName="rectBackColor"Canvas.Left="220"Canvas.Top="202"Width="15"Height="15"Stroke="Black"/><!-- Preview --><ButtonName="btReview"Content="Review"Canvas.Left="60"Canvas.Bottom="20"Width="80"Click="btReview_Click"/><!-- Save --><ButtonName="btSave"Content="Save"Canvas.Left="180"Canvas.Bottom="20"Width="80"Click="btSave_Click"/></Canvas></GroupBox></Grid></Window>
4. Add C# codes to controls event handler
Here is the complete C# code for MainWindow.xaml.cs with evets implemented.
usingBarcodeLib.Barcode;usingMicrosoft.Win32;usingSystem;usingSystem.Collections.Generic;usingSystem.Drawing;usingSystem.IO;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows;usingSystem.Windows.Controls;usingSystem.Windows.Data;usingSystem.Windows.Documents;usingSystem.Windows.Input;usingSystem.Windows.Media;usingSystem.Windows.Media.Imaging;usingSystem.Windows.Navigation;usingSystem.Windows.Shapes;namespaceBarcodeLib.Create.WPFCoreDemo{/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>publicpartialclassMainWindow:Window{publicconstintPreview_Width=400;publicMainWindow(){InitializeComponent();// Initial TextBoxthis.tbData.Text="QR Code";this.tbBarcodeWidth.Text="2";// 2 inchesthis.tbResolution.Text="300";// 300 dots per inchthis.tbForeColor.Text="000000";// Blackthis.tbBackColor.Text="FFFFFF";// White// Show preview barcode image.updatePreviewImage();}privatevoidtbBarcodeWidth_PreviewTextInput(objectsender,TextCompositionEventArgse){// Barcode Width must be a float valuee.Handled=!isValidChars(e.Text,"0123456789.");}privatevoidtbResolution_PreviewTextInput(objectsender,TextCompositionEventArgse){// Resolution must be an int valuee.Handled=!isValidChars(e.Text,"0123456789");}privatevoidtbColor_PreviewTextInput(objectsender,TextCompositionEventArgse){// Fore Color and Back Color must be a Hex char stringe.Handled=!isValidChars(e.Text,"0123456789ABCDEFabcdef");}privateboolisValidChars(Stringcontent,StringvalidCharSet){foreach(charcincontent){if(!validCharSet.Contains(c))returnfalse;}returntrue;}privatevoidtbBarcodeWidth_TextChanged(objectsender,TextChangedEventArgse){floatresult;boolisValid=float.TryParse(tbBarcodeWidth.Text,outresult);if(isValid)isValid=result>0;updateTextBoxBackground(this.tbBarcodeWidth,isValid);}privatevoidtbResolution_TextChanged(objectsender,TextChangedEventArgse){intresult;boolisValid=int.TryParse(tbBarcodeWidth.Text,outresult);if(isValid)isValid=result>0;updateTextBoxBackground(this.tbBarcodeWidth,isValid);}// Set background color of the TextBox to Red if the Text is invalid.privatevoidupdateTextBoxBackground(TextBoxtb,boolisValid){System.Windows.Media.Colornormal=System.Windows.Media.Color.FromRgb(255,255,255);System.Windows.Media.Colorerror=System.Windows.Media.Color.FromRgb(255,0,0);tb.Background=newSolidColorBrush(isValid?normal:error);}privatevoidtbForeColor_TextChanged(objectsender,TextChangedEventArgse){if(this.rectForeColor==null)return;try{System.Drawing.Colorcolor=parseColorString(this.tbForeColor.Text);// Not transparentif(color!=System.Drawing.Color.Transparent){System.Windows.Media.ColormColor=System.Windows.Media.Color.FromRgb(color.R,color.G,color.B);this.rectForeColor.Fill=newSystem.Windows.Media.SolidColorBrush(mColor);this.rectForeColor.Visibility=Visibility.Visible;}// Hidden Rectangle if set to transparent.elsethis.rectForeColor.Visibility=Visibility.Hidden;}catch(Exception){this.rectForeColor.Visibility=Visibility.Hidden;}intlen=this.tbForeColor.Text.Length;boolisValid=len==6;updateTextBoxBackground(this.tbForeColor,isValid);}privatevoidtbBackColor_TextChanged(objectsender,TextChangedEventArgse){if(this.rectBackColor==null)return;try{System.Drawing.Colorcolor=parseColorString(this.tbBackColor.Text);// Not transparentif(color!=System.Drawing.Color.Transparent){System.Windows.Media.ColormColor=System.Windows.Media.Color.FromRgb(color.R,color.G,color.B);this.rectBackColor.Fill=newSystem.Windows.Media.SolidColorBrush(mColor);this.rectBackColor.Visibility=Visibility.Visible;}// Hidden Rectangle if set to transparent.elsethis.rectBackColor.Visibility=Visibility.Hidden;}catch(Exception){this.rectBackColor.Visibility=Visibility.Hidden;}intlen=this.tbBackColor.Text.Length;boolisValid=len==0||len==6;updateTextBoxBackground(this.tbBackColor,isValid);}// Parse Color string to System.Drawing.ColorprivateSystem.Drawing.ColorparseColorString(Stringrrggbb){// Input must be a string with 6 hex chars.if(rrggbb==null||rrggbb.Length!=6)returnSystem.Drawing.Color.Transparent;try{intr=hexCharToInt(rrggbb[0])*16+hexCharToInt(rrggbb[1]);intg=hexCharToInt(rrggbb[2])*16+hexCharToInt(rrggbb[3]);intb=hexCharToInt(rrggbb[4])*16+hexCharToInt(rrggbb[5]);returnSystem.Drawing.Color.FromArgb(r,g,b);}catch(Exception){returnSystem.Drawing.Color.Transparent;}}// Convert Hex Char to integer.// Valid Input: '0' ~ '9', 'A' ~ 'F' or 'a' ~ 'f'.// Throw exception if input is invalid.privateinthexCharToInt(charc){if(c>='0'&&c<='9')return(int)c-(int)'0';if(c>='A'&&c<='F')return(int)c-(int)'A'+10;if(c>='a'&&c<='f')return(int)c-(int)'a'+10;thrownewException("Invalid Hex. Char");}privatevoidbtReview_Click(objectsender,RoutedEventArgse){updatePreviewImage();}privatevoidupdatePreviewImage(){try{QRCodeqrcode=generateBarcodeObject();Bitmapbitmap=qrcode.drawBarcode();// Resize barcode image to preview image.BitmappreviewImg=newBitmap(Preview_Width,Preview_Width);using(Graphicsg=Graphics.FromImage(previewImg)){g.DrawImage(bitmap,0,0,previewImg.Width,previewImg.Height);}// Update Image controlusing(MemoryStreamms=newMemoryStream()){previewImg.Save(ms,System.Drawing.Imaging.ImageFormat.Png);BitmapImagebi=newBitmapImage();bi.BeginInit();bi.StreamSource=ms;bi.CacheOption=BitmapCacheOption.OnLoad;bi.EndInit();this.imgReview.Width=Preview_Width;this.imgReview.Height=Preview_Width;this.imgReview.Source=bi;}}catch(Exceptionex){MessageBox.Show("Create preview image failed. "+ex.Message);}}privateQRCodegenerateBarcodeObject(){Stringdata=this.tbData.Text;floatimgWidthInInch;if(float.TryParse(this.tbBarcodeWidth.Text,outimgWidthInInch)==false)thrownewException("Invalid Barcode Width");intdpi;if(int.TryParse(this.tbResolution.Text,outdpi)==false)thrownewException("Invalid Resolution");if(this.tbForeColor.Text.Length!=6)thrownewException("Invalid Fore Color");if(this.tbBackColor.Text.Length!=6&&this.tbBackColor.Text.Length!=0)thrownewException("Invalid Back Color");System.Drawing.ColorforeColor=parseColorString(this.tbForeColor.Text);System.Drawing.ColorbackColor=parseColorString(this.tbBackColor.Text);QRCodebarcode=newQRCode();barcode.Encoding=QRCodeEncoding.Auto;barcode.Version=QRCodeVersion.V1;barcode.ECL=QRCodeErrorCorrectionLevel.L;// Use Auto Size modebarcode.ResizeImage=true;// Set padding area to transparentbarcode.ResizeImagePaddingTransparent=true;barcode.Data=data;barcode.UOM=UnitOfMeasure.INCH;barcode.Resolution=dpi;barcode.ImageWidth=imgWidthInInch;barcode.ImageHeight=imgWidthInInch;barcode.ModuleColor=foreColor;barcode.BackgroundColor=backColor;barcode.ImageFormat=System.Drawing.Imaging.ImageFormat.Png;returnbarcode;}privatevoidbtSave_Click(objectsender,RoutedEventArgse){SaveFileDialogsaveFileDialog=newSaveFileDialog();saveFileDialog.Filter="PNG Files (*.png)|*.png";saveFileDialog.DefaultExt=".png";if(saveFileDialog.ShowDialog()==true){StringoutputFilePath=saveFileDialog.FileName;try{QRCodeqrcode=generateBarcodeObject();qrcode.drawBarcode(outputFilePath);}catch(Exceptionex){MessageBox.Show("Save to file failed. "+ex.Message);}}}}}
5. Run the demo web app
Now you have finished all C# coding in the WPF project. Run the WPF app directly from Visual Studio .NET.
You can preview the customized QR Code and save the generated barcode image file.