Cómo crear una aplicación de código de barras de escritorio (escáner/generador) con .NET MAUI

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

Para una solución de software integral, no se trata sólo de accesibilidad móvil. La capacidad de implementar de forma nativa en sistemas operativos de escritorio, como Windows y macOS, es igualmente fundamental. Este enfoque multiplataforma permite a las empresas aprovechar todo el poder de las estaciones de trabajo para tareas de gran volumen, como el seguimiento y la administración de activos.

Sin un soporte de escritorio adecuado, los flujos de trabajo se interrumpen o, peor aún, se fuerzan a utilizar dispositivos menos capaces. Esto es particularmente importante en la gestión de inventario, donde el personal de oficina necesita generar lotes de códigos o verificar escaneos rápidamente sin abandonar sus escritorios.

IronBarcode proporciona las herramientas necesarias para implementar estas características, garantizando que su aplicación .NET MAUI funcione de manera confiable en cualquier computadora.

En este artículo, explicaremos cómo integrar IronBarcode para crear un escáner de código de barras de escritorio y un generador de código de barras de escritorio .

Comience a usar IronBarcode



Aplicación de escritorio .NET MAUI

Integrar IronBarcode en una aplicación .NET MAUI es sencillo, ya que la biblioteca funciona de forma nativa con la plataforma de escritorio desde el primer momento. En este ejemplo, crearemos un escáner de código de barras y un generador de código de barras utilizando IronBarcode por separado.

Comencemos primero con el escáner de código de barras.

Interfaz de escáner de código de barras XAML

Para la interfaz .NET MAUI, se implementa una interfaz simple que permite a los usuarios cargar imágenes de códigos de barras a través de un botón de envío. El archivo MainPage.xaml dentro del proyecto debe reemplazarse con el contenido que se muestra a continuación.

<?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

Lógica CS de escáner de código de barras de escritorio

A continuación, se implementa la lógica para cuando el usuario hace clic en el botón. Un controlador de evento OnScanButtonClicked está adjunto al botón de escaneo en la interfaz de usuario.

PickPhotoAsync se utiliza primero para permitir a los usuarios elegir el código de barras que desea cargar, seguido de OpenReadAsync para acceder al flujo de archivos. Los datos de la imagen se copian inmediatamente en un MemoryStream usando CopyToAsync . Esto permite que los datos se utilicen simultáneamente para mostrar la imagen en pantalla y para que el método Read escanee el código de barras.

Finalmente, el valor del código de barras se muestra en la interfaz de usuario si se detecta un código de barras válido o se muestra un mensaje rojo que indica que no se encontró ningún código de barras en la imagen.

Por favor nota Reemplace la clave de licencia con la suya antes de probar la aplicación.

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

Salida con valor de código de barras encontrado

Salida de códigos de barras encontrados

Como puede ver, la aplicación muestra el resultado del código de barras y la imagen del código de barras cargada.

Salida sin valor de código de barras encontrado

No se encontraron códigos de barras en la salida

Como puede ver, cuando un usuario carga una imagen que no contiene un código de barras, se muestra un mensaje rojo que dice "No se encontraron códigos de barras".

Generador de códigos de barras de escritorio

La siguiente parte se basa en el mismo concepto al integrar IronBarcode en MAUI para crear un generador de códigos de barras.

Interfaz del generador de códigos de barras XAML

Para la interfaz del generador, se implementa un formulario simple que permite el ingreso de texto y la selección del tipo de código de barras a través de un menú desplegable. Se incluye un botón para activar el proceso de generación y guardado, junto con una vista de imagen para mostrar el resultado. El archivo MainPage.xaml debe reemplazarse con el contenido que se muestra a continuación.

Consulte aquí para obtener la lista completa de códigos de barras 1D y aquí para obtener la lista de códigos de barras 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

Generador de códigos de barras de escritorio Logic CS

A continuación, se implementa la lógica para el evento de clic del botón. Un controlador de evento OnGenerateButtonClicked está adjunto al botón de generación en la interfaz de usuario.

La entrada del usuario se valida para garantizar que el texto esté presente y se seleccione un tipo, después de lo cual la selección se asigna al BarcodeEncoding correcto. BarcodeWriter.CreateBarcode se utiliza para generar la imagen, redimensionarla y convertirla a datos binarios JPEG. Luego, la imagen se muestra en la pantalla mediante un MemoryStream .

Finalmente, el archivo de código de barras generado se guarda directamente en el escritorio del usuario mediante File.WriteAllBytes , y la etiqueta de estado se actualiza para confirmar la ubicación de guardado.

Por favor nota Reemplace la clave de licencia con la suya antes de probar la aplicación.

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

Salida con código de barras generado

Generar código de barras con éxito

Como puede ver, la aplicación muestra el código de barras generado y lo guarda en el escritorio del usuario.

Fallo de salida

Error en la generación de código de barras

Ciertos tipos de códigos de barras tienen restricciones y requisitos de formato para el valor de entrada. Cuando no se puede generar el código de barras, la aplicación muestra la excepción IronBarcode, como se muestra arriba. Consulte los respectivos formatos detallados 1D y 2D para cada tipo de código de barras.

Para probar los ejemplos anteriores ( Escáner de código de barras de escritorio y Generador de código de barras de escritorio ), descargue este proyecto de muestra.

Preguntas Frecuentes

¿Qué es .NET MAUI?

.NET MAUI es un framework multiplataforma para crear aplicaciones nativas móviles y de escritorio con C# y XAML. Permite a los desarrolladores crear aplicaciones para Android, iOS, macOS y Windows utilizando una única base de código.

¿Cómo se puede utilizar IronBarcode en una aplicación .NET MAUI?

IronBarcode se puede integrar en una aplicación .NET MAUI para habilitar la generación y el escaneo de códigos de barras. Ofrece una forma sencilla de crear y leer códigos de barras en múltiples plataformas de escritorio.

¿Qué tipos de códigos de barras puede generar IronBarcode?

IronBarcode admite la generación de una amplia variedad de formatos de códigos de barras, incluidos códigos QR, Código 128, Código 39, UPC, EAN y muchos más, lo que lo hace versátil para cualquier necesidad de aplicación de escritorio.

¿Es posible escanear códigos de barras utilizando una aplicación de escritorio creada con IronBarcode?

Sí, IronBarcode se puede utilizar para escanear códigos de barras en aplicaciones de escritorio, lo que permite a los usuarios decodificar la información del código de barras de manera rápida y eficiente a través de la interfaz de la aplicación.

¿Cuáles son las ventajas de utilizar IronBarcode para aplicaciones de código de barras?

IronBarcode ofrece alta precisión, velocidad y facilidad de uso. Se integra perfectamente con .NET MAUI, lo que proporciona compatibilidad completa para la generación y el escaneo de códigos de barras en aplicaciones de escritorio.

¿Puede IronBarcode manejar grandes volúmenes de datos de códigos de barras?

Sí, IronBarcode está diseñado para procesar de manera eficiente grandes volúmenes de datos de códigos de barras, lo que lo hace adecuado para aplicaciones que requieren el manejo de extensas tareas de códigos de barras.

¿Necesito una biblioteca separada para la generación y el escaneo de códigos de barras?

No, IronBarcode proporciona funcionalidades de generación y escaneo de códigos de barras dentro de una única biblioteca, lo que simplifica el proceso de desarrollo para aplicaciones de escritorio.

¿Cuáles son los requisitos del sistema para utilizar IronBarcode con .NET MAUI?

IronBarcode requiere un entorno .NET compatible con .NET MAUI. Es compatible con Windows, macOS y otras plataformas donde se pueden ejecutar aplicaciones .NET MAUI.

¿Cómo garantiza IronBarcode la precisión del código de barras?

IronBarcode utiliza algoritmos avanzados para garantizar una alta precisión tanto en la generación como en el escaneo de códigos de barras, reduciendo la probabilidad de errores en la codificación o decodificación de datos de códigos de barras.

¿Se puede utilizar IronBarcode tanto para proyectos comerciales como personales?

Sí, IronBarcode se puede utilizar tanto para proyectos comerciales como personales y ofrece opciones de licencia flexibles para adaptarse a diferentes requisitos del proyecto.

Curtis Chau
Escritor Técnico

Curtis Chau tiene una licenciatura en Ciencias de la Computación (Carleton University) y se especializa en el desarrollo front-end con experiencia en Node.js, TypeScript, JavaScript y React. Apasionado por crear interfaces de usuario intuitivas y estéticamente agradables, disfruta trabajando con frameworks modernos y creando manuales bien ...

Leer más
¿Listo para empezar?
Nuget Descargas 2,035,202 | Versión: 2025.12 recién lanzado