如何使用 .NET MAUI 创建桌面条形码应用程序(扫描器/生成器)

This article was translated from English: Does it need improvement?
Translated
View the article in English

对于一个全面的软件解决方案而言,移动访问性并非唯一考量因素。 能够在 Windows 和 macOS 等桌面操作系统上进行原生部署的能力同样至关重要。 这种跨平台方法使企业能够充分利用工作站的强大功能来处理大量任务,例如资产跟踪和管理。

如果没有合适的桌面支持,工作流程就会中断,或者更糟糕的是,被迫在性能较低的设备上运行。 这在库存管理中尤为重要,因为办公室人员需要在不离开办公桌的情况下快速生成批量代码或验证扫描结果。

IronBarcode 提供实现这些功能所需的必要工具,确保您的 .NET MAUI 应用程序在任何计算机上都能可靠地运行。

在本文中,我们将解释如何集成 IronBarcode 来构建桌面条形码扫描器桌面条形码生成器

开始使用 IronBarcode



.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>
XML

桌面条码扫描器逻辑 CS

接下来,实现用户点击按钮时的逻辑。 在用户界面中,扫描按钮附加了一个OnScanButtonClicked事件处理程序。

PickPhotoAsync首先用于让用户选择要上传的条形码,然后使用OpenReadAsync访问文件流。 使用CopyToAsync立即将图像数据复制到MemoryStream中。 这样就可以同时使用数据在屏幕上显示图像,并让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;
            }
        }
    }
}
$vbLabelText   $csharpLabel

输出结果包含找到的条形码值

找到的条形码输出

如您所见,该应用程序显示了条形码结果和上传的条形码图像。

未找到条形码值

未找到条形码输出

如您所见,当用户上传的图片不包含条形码时,会显示一条红色消息,提示"未找到条形码"。

桌面条码生成器

下一部分将以相同的概念为基础,把 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 &amp; 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 &amp; 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

桌面条形码生成器逻辑 CS

接下来,实现按钮点击事件的逻辑。 UI 中的生成按钮附加了一个OnGenerateButtonClicked事件处理程序。

用户输入经过验证,以确保文本存在并且已选择类型,之后将选择映射到正确的BarcodeEncodingBarcodeWriter.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;
            }
        }
    }
}
$vbLabelText   $csharpLabel

输出生成的条形码

条形码生成成功

如您所见,该应用程序会显示生成的条形码并将其保存到用户的桌面。

输出失败

条形码故障生成

某些条形码类型对输入值有限制和格式要求。 当条形码生成失败时,应用程序会显示 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 可用于商业和个人项目,提供灵活的许可选项以满足不同的项目需求。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。

准备开始了吗?
Nuget 下载 2,035,202 | 版本: 2025.12 刚刚发布