如何使用 .NET MAUI 创建桌面条形码应用程序(扫描器/生成器)
对于一个全面的软件解决方案而言,移动访问性并非唯一考量因素。 能够在 Windows 和 macOS 等桌面操作系统上进行原生部署的能力同样至关重要。 这种跨平台方法使企业能够充分利用工作站的强大功能来处理大量任务,例如资产跟踪和管理。
如果没有合适的桌面支持,工作流程就会中断,或者更糟糕的是,被迫在性能较低的设备上运行。 这在库存管理中尤为重要,因为办公室人员需要在不离开办公桌的情况下快速生成批量代码或验证扫描结果。
IronBarcode 提供实现这些功能所需的必要工具,确保您的 .NET MAUI 应用程序在任何计算机上都能可靠地运行。
在本文中,我们将解释如何集成 IronBarcode 来构建桌面条形码扫描器和桌面条形码生成器。
如何使用 .NET MAUI 在 C# 中创建桌面条形码应用程序
- 下载 IronBarcode C# 库,以便与 .NET MAUI(桌面平台框架)集成。
- 使用`Read`功能读取用户上传的条形码。
- 在 .NET MAUI 用户界面中显示条形码值
- 使用`CreateBarcode`生成带有字符串值的条形码
- 在 .NET MAUI 用户界面中显示生成的条形码并将其保存为图像
.NET MAUI 桌面应用程序
将 IronBarcode 集成到 .NET MAUI 应用程序中非常简单,因为该库开箱即用,可与桌面平台原生兼容。 在这个例子中,我们将分别使用 IronBarcode 创建条形码扫描器和条形码生成器。
我们先从条形码扫描器开始。
条形码扫描器接口 XAML
对于 .NET MAUI 接口,实现了一个简单的接口,允许用户通过提交按钮上传条形码图像。 项目内的 MainPage.xaml 文件应替换为以下内容。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1.MainPage"
BackgroundColor="{DynamicResource PageBackgroundColor}">
<ScrollView>
<VerticalStackLayout Spacing="25" Padding="30" VerticalOptions="Center">
<Label Text="Desktop Barcode Scanner"
FontSize="32"
HorizontalOptions="Center" />
<Image x:Name="ScannerImage"
HeightRequest="300"
WidthRequest="400"
BackgroundColor="#F0F0F0"
Aspect="AspectFit"
HorizontalOptions="Center" />
<Button Text="Select Image to Scan"
Clicked="OnScanButtonClicked"
HorizontalOptions="Center"
WidthRequest="200"/>
<Label x:Name="ResultLabel"
Text="Result will appear here..."
FontSize="20"
HorizontalOptions="Center"
HorizontalTextAlignment="Center" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1.MainPage"
BackgroundColor="{DynamicResource PageBackgroundColor}">
<ScrollView>
<VerticalStackLayout Spacing="25" Padding="30" VerticalOptions="Center">
<Label Text="Desktop Barcode Scanner"
FontSize="32"
HorizontalOptions="Center" />
<Image x:Name="ScannerImage"
HeightRequest="300"
WidthRequest="400"
BackgroundColor="#F0F0F0"
Aspect="AspectFit"
HorizontalOptions="Center" />
<Button Text="Select Image to Scan"
Clicked="OnScanButtonClicked"
HorizontalOptions="Center"
WidthRequest="200"/>
<Label x:Name="ResultLabel"
Text="Result will appear here..."
FontSize="20"
HorizontalOptions="Center"
HorizontalTextAlignment="Center" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>
桌面条码扫描器逻辑 CS
接下来,实现用户点击按钮时的逻辑。 UI 中的扫描按钮附加了一个 OnScanButtonClicked 事件处理程序。
首先使用 PickPhotoAsync 让用户选择要上传的条形码,然后使用 OpenReadAsync 访问文件流。 图像数据立即被复制到 MemoryStream 中,使用 CopyToAsync。 这样就可以同时使用数据在屏幕上显示图像,并让 Read 方法扫描条形码。
最后,如果检测到有效的条形码,则会在用户界面中显示条形码值;如果未在图像中找到条形码,则会显示一条红色消息。
using IronBarCode;
namespace MauiApp1
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
// Your license key is set here
IronBarCode.License.LicenseKey = "YOUR_KEY"
}
private async void OnScanButtonClicked(object sender, EventArgs e)
{
try
{
var fileResult = await MediaPicker.Default.PickPhotoAsync();
if (fileResult != null)
{
// 1. Copy the file content into a byte array or MemoryStream immediately
// This ensures we have the data in memory before the file closes
byte[] imageBytes;
using (var stream = await fileResult.OpenReadAsync())
using (var memoryStream = new MemoryStream())
{
await stream.CopyToAsync(memoryStream);
imageBytes = memoryStream.ToArray();
}
// 2. Set the Image Source for the UI
// We give the UI a FRESH stream from the bytes we just saved
ScannerImage.Source = ImageSource.FromStream(() => new MemoryStream(imageBytes));
// 3. Process the Barcode
// We give IronBarcode its OWN fresh stream from the same bytes
using (var processingStream = new MemoryStream(imageBytes))
{
// 4. Read the barcode with Read
var results = BarcodeReader.Read(processingStream);
// 5. Display barcode results
if (results != null && results.Count > 0)
{
// Successfully found barcode value
ResultLabel.Text = $"Success: {results[0].Value}";
ResultLabel.TextColor = Colors.Green;
}
else
{
// Image uploaded has no barcode or barcode value is not found
ResultLabel.Text = "No barcode detected.";
ResultLabel.TextColor = Colors.Red;
}
}
}
}
catch (Exception ex)
{
// Display any exception thrown in runtime
ResultLabel.Text = $"Error: {ex.Message}";
ResultLabel.TextColor = Colors.Red;
}
}
}
}
using IronBarCode;
namespace MauiApp1
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
// Your license key is set here
IronBarCode.License.LicenseKey = "YOUR_KEY"
}
private async void OnScanButtonClicked(object sender, EventArgs e)
{
try
{
var fileResult = await MediaPicker.Default.PickPhotoAsync();
if (fileResult != null)
{
// 1. Copy the file content into a byte array or MemoryStream immediately
// This ensures we have the data in memory before the file closes
byte[] imageBytes;
using (var stream = await fileResult.OpenReadAsync())
using (var memoryStream = new MemoryStream())
{
await stream.CopyToAsync(memoryStream);
imageBytes = memoryStream.ToArray();
}
// 2. Set the Image Source for the UI
// We give the UI a FRESH stream from the bytes we just saved
ScannerImage.Source = ImageSource.FromStream(() => new MemoryStream(imageBytes));
// 3. Process the Barcode
// We give IronBarcode its OWN fresh stream from the same bytes
using (var processingStream = new MemoryStream(imageBytes))
{
// 4. Read the barcode with Read
var results = BarcodeReader.Read(processingStream);
// 5. Display barcode results
if (results != null && results.Count > 0)
{
// Successfully found barcode value
ResultLabel.Text = $"Success: {results[0].Value}";
ResultLabel.TextColor = Colors.Green;
}
else
{
// Image uploaded has no barcode or barcode value is not found
ResultLabel.Text = "No barcode detected.";
ResultLabel.TextColor = Colors.Red;
}
}
}
}
catch (Exception ex)
{
// Display any exception thrown in runtime
ResultLabel.Text = $"Error: {ex.Message}";
ResultLabel.TextColor = Colors.Red;
}
}
}
}
Imports IronBarCode
Namespace MauiApp1
Partial Public Class MainPage
Inherits ContentPage
Public Sub New()
InitializeComponent()
' Your license key is set here
IronBarCode.License.LicenseKey = "YOUR_KEY"
End Sub
Private Async Sub OnScanButtonClicked(ByVal sender As Object, ByVal e As EventArgs)
Try
Dim fileResult = Await MediaPicker.Default.PickPhotoAsync()
If fileResult IsNot Nothing Then
' 1. Copy the file content into a byte array or MemoryStream immediately
' This ensures we have the data in memory before the file closes
Dim imageBytes As Byte()
Using stream = Await fileResult.OpenReadAsync(), memoryStream = New MemoryStream()
Await stream.CopyToAsync(memoryStream)
imageBytes = memoryStream.ToArray()
End Using
' 2. Set the Image Source for the UI
' We give the UI a FRESH stream from the bytes we just saved
ScannerImage.Source = ImageSource.FromStream(Function() New MemoryStream(imageBytes))
' 3. Process the Barcode
' We give IronBarcode its OWN fresh stream from the same bytes
Using processingStream = New MemoryStream(imageBytes)
' 4. Read the barcode with Read
Dim results = BarcodeReader.Read(processingStream)
' 5. Display barcode results
If results IsNot Nothing AndAlso results.Count > 0 Then
' Successfully found barcode value
ResultLabel.Text = $"Success: {results(0).Value}"
ResultLabel.TextColor = Colors.Green
Else
' Image uploaded has no barcode or barcode value is not found
ResultLabel.Text = "No barcode detected."
ResultLabel.TextColor = Colors.Red
End If
End Using
End If
Catch ex As Exception
' Display any exception thrown in runtime
ResultLabel.Text = $"Error: {ex.Message}"
ResultLabel.TextColor = Colors.Red
End Try
End Sub
End Class
End Namespace
输出结果包含找到的条形码值
如您所见,该应用程序显示了条形码结果和上传的条形码图像。
未找到条形码值
如您所见,当用户上传不包含条形码的图片时,会显示一条红色消息,提示"未找到条形码"。
桌面条码生成器
下一部分将以相同的概念为基础,把 IronBarcode 集成到 MAUI 中,创建一个条形码生成器。
条形码生成器接口 XAML
对于生成器的界面,实现了一个简单的表单,允许通过下拉菜单输入文本和选择条形码类型。 包含一个按钮,用于触发生成和保存过程,以及一个图像视图,用于显示结果。 请将 MainPage.xaml 文件替换为以下内容。
请点击此处查看完整的 1D 条形码列表,点击此处查看完整的 2D 条形码列表。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1.MainPage"
BackgroundColor="{DynamicResource PageBackgroundColor}">
<ScrollView>
<VerticalStackLayout Spacing="20" Padding="30" VerticalOptions="Center">
<Label Text="Barcode Generator"
FontSize="32"
HorizontalOptions="Center" />
<Entry x:Name="BarcodeEntry"
Placeholder="Enter value (e.g. 12345 or https://ironsoftware.com)"
WidthRequest="300" />
<Picker x:Name="BarcodeTypePicker"
Title="Select Barcode Type"
WidthRequest="300">
<Picker.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>QRCode</x:String>
<x:String>Code128</x:String>
<x:String>EAN13</x:String>
<x:String>Code39</x:String>
<x:String>PDF417</x:String>
</x:Array>
</Picker.ItemsSource>
</Picker>
<Button Text="Generate & Save"
Clicked="OnGenerateButtonClicked"
HorizontalOptions="Center"
WidthRequest="200" />
<Image x:Name="GeneratedImage"
HeightRequest="200"
WidthRequest="300"
BackgroundColor="#F0F0F0"
Aspect="AspectFit" />
<Label x:Name="StatusLabel"
FontSize="16"
HorizontalOptions="Center"
HorizontalTextAlignment="Center" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1.MainPage"
BackgroundColor="{DynamicResource PageBackgroundColor}">
<ScrollView>
<VerticalStackLayout Spacing="20" Padding="30" VerticalOptions="Center">
<Label Text="Barcode Generator"
FontSize="32"
HorizontalOptions="Center" />
<Entry x:Name="BarcodeEntry"
Placeholder="Enter value (e.g. 12345 or https://ironsoftware.com)"
WidthRequest="300" />
<Picker x:Name="BarcodeTypePicker"
Title="Select Barcode Type"
WidthRequest="300">
<Picker.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>QRCode</x:String>
<x:String>Code128</x:String>
<x:String>EAN13</x:String>
<x:String>Code39</x:String>
<x:String>PDF417</x:String>
</x:Array>
</Picker.ItemsSource>
</Picker>
<Button Text="Generate & Save"
Clicked="OnGenerateButtonClicked"
HorizontalOptions="Center"
WidthRequest="200" />
<Image x:Name="GeneratedImage"
HeightRequest="200"
WidthRequest="300"
BackgroundColor="#F0F0F0"
Aspect="AspectFit" />
<Label x:Name="StatusLabel"
FontSize="16"
HorizontalOptions="Center"
HorizontalTextAlignment="Center" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>
桌面条形码生成器逻辑 CS
接下来,实现按钮点击事件的逻辑。 在用户界面中,"生成"按钮已附加一个 OnGenerateButtonClicked 事件处理程序。
用户输入经过验证,以确保文本存在并且已选择类型,之后将选择映射到正确的 BarcodeEncoding。 BarcodeWriter.CreateBarcode 用于生成图像、调整图像大小并将其转换为 JPEG 二进制数据。 然后使用 MemoryStream 在屏幕上显示图像。
最后,生成的条形码文件使用 File.WriteAllBytes 直接保存到用户的桌面,并且状态标签更新以确认保存位置。
using IronBarCode;
using System.IO; // Required for saving files
namespace MauiApp1
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
IronBarCode.License.LicenseKey = "YOUR-KEY";
// Set default selection
BarcodeTypePicker.SelectedIndex = 0;
}
private void OnGenerateButtonClicked(object sender, EventArgs e)
{
try
{
// 1. Get and Validate Input
string text = BarcodeEntry.Text;
if (string.IsNullOrWhiteSpace(text))
{
StatusLabel.Text = "Error: Please enter text.";
StatusLabel.TextColor = Colors.Red;
return;
}
if (BarcodeTypePicker.SelectedIndex == -1)
{
StatusLabel.Text = "Error: Please select a type.";
StatusLabel.TextColor = Colors.Red;
return;
}
// 2. Determine Encoding Type
string selectedType = BarcodeTypePicker.SelectedItem.ToString();
BarcodeEncoding encoding = BarcodeEncoding.QRCode;
switch (selectedType)
{
case "QRCode": encoding = BarcodeEncoding.QRCode; break;
case "Code128": encoding = BarcodeEncoding.Code128; break;
case "EAN13": encoding = BarcodeEncoding.EAN13; break;
case "Code39": encoding = BarcodeEncoding.Code39; break;
case "PDF417": encoding = BarcodeEncoding.PDF417; break;
}
// 3. Generate Barcode
var barcode = BarcodeWriter.CreateBarcode(text, encoding);
barcode.ResizeTo(400, 200); // Optional resizing
// 4. Convert to Bytes (JPEG)
var bytes = barcode.ToJpegBinaryData();
// 5. Update UI
GeneratedImage.Source = ImageSource.FromStream(() => new MemoryStream(bytes));
// 6. Save to Desktop automatically
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string fileName = $"barcode_{DateTime.Now:yyyyMMdd_HHmmss}.jpg";
string fullPath = Path.Combine(desktopPath, fileName);
File.WriteAllBytes(fullPath, bytes);
// 7. Show Success Message
StatusLabel.Text = $"Saved to Desktop:\n{fileName}";
StatusLabel.TextColor = Colors.Green;
}
catch (Exception ex)
{
StatusLabel.Text = $"Error: {ex.Message}";
StatusLabel.TextColor = Colors.Red;
}
}
}
}
using IronBarCode;
using System.IO; // Required for saving files
namespace MauiApp1
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
IronBarCode.License.LicenseKey = "YOUR-KEY";
// Set default selection
BarcodeTypePicker.SelectedIndex = 0;
}
private void OnGenerateButtonClicked(object sender, EventArgs e)
{
try
{
// 1. Get and Validate Input
string text = BarcodeEntry.Text;
if (string.IsNullOrWhiteSpace(text))
{
StatusLabel.Text = "Error: Please enter text.";
StatusLabel.TextColor = Colors.Red;
return;
}
if (BarcodeTypePicker.SelectedIndex == -1)
{
StatusLabel.Text = "Error: Please select a type.";
StatusLabel.TextColor = Colors.Red;
return;
}
// 2. Determine Encoding Type
string selectedType = BarcodeTypePicker.SelectedItem.ToString();
BarcodeEncoding encoding = BarcodeEncoding.QRCode;
switch (selectedType)
{
case "QRCode": encoding = BarcodeEncoding.QRCode; break;
case "Code128": encoding = BarcodeEncoding.Code128; break;
case "EAN13": encoding = BarcodeEncoding.EAN13; break;
case "Code39": encoding = BarcodeEncoding.Code39; break;
case "PDF417": encoding = BarcodeEncoding.PDF417; break;
}
// 3. Generate Barcode
var barcode = BarcodeWriter.CreateBarcode(text, encoding);
barcode.ResizeTo(400, 200); // Optional resizing
// 4. Convert to Bytes (JPEG)
var bytes = barcode.ToJpegBinaryData();
// 5. Update UI
GeneratedImage.Source = ImageSource.FromStream(() => new MemoryStream(bytes));
// 6. Save to Desktop automatically
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string fileName = $"barcode_{DateTime.Now:yyyyMMdd_HHmmss}.jpg";
string fullPath = Path.Combine(desktopPath, fileName);
File.WriteAllBytes(fullPath, bytes);
// 7. Show Success Message
StatusLabel.Text = $"Saved to Desktop:\n{fileName}";
StatusLabel.TextColor = Colors.Green;
}
catch (Exception ex)
{
StatusLabel.Text = $"Error: {ex.Message}";
StatusLabel.TextColor = Colors.Red;
}
}
}
}
Imports IronBarCode
Imports System.IO ' Required for saving files
Namespace MauiApp1
Public Partial Class MainPage
Inherits ContentPage
Public Sub New()
InitializeComponent()
IronBarCode.License.LicenseKey = "YOUR-KEY"
' Set default selection
BarcodeTypePicker.SelectedIndex = 0
End Sub
Private Sub OnGenerateButtonClicked(sender As Object, e As EventArgs)
Try
' 1. Get and Validate Input
Dim text As String = BarcodeEntry.Text
If String.IsNullOrWhiteSpace(text) Then
StatusLabel.Text = "Error: Please enter text."
StatusLabel.TextColor = Colors.Red
Return
End If
If BarcodeTypePicker.SelectedIndex = -1 Then
StatusLabel.Text = "Error: Please select a type."
StatusLabel.TextColor = Colors.Red
Return
End If
' 2. Determine Encoding Type
Dim selectedType As String = BarcodeTypePicker.SelectedItem.ToString()
Dim encoding As BarcodeEncoding = BarcodeEncoding.QRCode
Select Case selectedType
Case "QRCode"
encoding = BarcodeEncoding.QRCode
Case "Code128"
encoding = BarcodeEncoding.Code128
Case "EAN13"
encoding = BarcodeEncoding.EAN13
Case "Code39"
encoding = BarcodeEncoding.Code39
Case "PDF417"
encoding = BarcodeEncoding.PDF417
End Select
' 3. Generate Barcode
Dim barcode = BarcodeWriter.CreateBarcode(text, encoding)
barcode.ResizeTo(400, 200) ' Optional resizing
' 4. Convert to Bytes (JPEG)
Dim bytes = barcode.ToJpegBinaryData()
' 5. Update UI
GeneratedImage.Source = ImageSource.FromStream(Function() New MemoryStream(bytes))
' 6. Save to Desktop automatically
Dim desktopPath As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Dim fileName As String = $"barcode_{DateTime.Now:yyyyMMdd_HHmmss}.jpg"
Dim fullPath As String = Path.Combine(desktopPath, fileName)
File.WriteAllBytes(fullPath, bytes)
' 7. Show Success Message
StatusLabel.Text = $"Saved to Desktop:{Environment.NewLine}{fileName}"
StatusLabel.TextColor = Colors.Green
Catch ex As Exception
StatusLabel.Text = $"Error: {ex.Message}"
StatusLabel.TextColor = Colors.Red
End Try
End Sub
End Class
End Namespace
输出生成的条形码
如您所见,该应用程序会显示生成的条形码并将其保存到用户的桌面。
输出失败
某些条形码类型对输入值有限制和格式要求。 当条形码生成失败时,应用程序会显示 IronBarcode 异常,如上所示。 请参考相应的详细一维和二维条码格式说明,了解每种条码类型的格式要求。
要测试上述示例(桌面条形码扫描器和桌面条形码生成器),请下载此示例项目。
常见问题解答
什么是 .NET MAUI?
.NET MAUI 是一个跨平台框架,用于使用 C# 和 XAML 创建本地移动和桌面应用程序。它允许开发人员使用单一代码库为 Android、iOS、macOS 和 Windows 构建应用程序。
如何在 .NET MAUI 应用程序中使用 IronBarcode?
IronBarcode 可集成到 .NET MAUI 应用程序中,实现条码生成和扫描功能。它提供了一种在多个桌面平台上创建和读取条形码的直接方法。
IronBarcode 可以生成哪些类型的条形码?
IronBarcode 支持生成多种条形码格式,包括 QR 码、Code 128、Code 39、UPC、EAN 等,因此可满足任何桌面应用程序的多功能需求。
是否可以使用 IronBarcode 构建的桌面应用程序扫描条形码?
是的,IronBarcode 可用于扫描桌面应用程序中的条形码,使用户能够通过应用程序的界面快速有效地解码条形码信息。
在条码应用中使用 IronBarcode 有哪些优势?
IronBarcode 具有精度高、速度快、使用方便等特点。它与 .NET MAUI 无缝集成,为桌面应用程序中的条形码生成和扫描提供全面支持。
IronBarcode 可以处理大量条码数据吗?
是的,IronBarcode 旨在高效处理大量条码数据,因此适合需要处理大量条码任务的应用程序。
我需要一个单独的库来进行条形码扫描和生成吗?
不,IronBarcode 在一个库中同时提供条码扫描和生成功能,简化了桌面应用程序的开发过程。
IronBarcode 与 .NET MAUI 的系统要求是什么?
IronBarcode 需要与 .NET MAUI 兼容的 .NET 环境。它支持 Windows、macOS 和其他可运行 .NET MAUI 应用程序的平台。
IronBarcode 如何确保条码的准确性?
IronBarcode 采用先进的算法,确保条码生成和扫描的高精度,降低条码数据编码或解码出错的可能性。
IronBarcode 可以用于商业和个人项目吗?
是的,IronBarcode 可用于商业和个人项目,提供灵活的许可选项,以适应不同的项目要求。

