Drag / Drop (Blazor)

NuGet Package Details

Package Name
Llamachant.ExpressApp.DragDrop.Blazor

Overview

This module allows you to drag / drop files on list views for any business object that implements the IFileData, IFileAttachment, or ISupportDragDrop interface, or has the FileAttachment attribute.

🌟 Key Features

Installation

Step 1: Install the Module

Install-Package 'Llamachant.ExpressApp.DragDrop.Blazor'

Step 2: Register the Module

services.AddXaf(Configuration, builder => {
    builder.UseApplication<ExpressAppBlazorApplication>();
    builder.Modules.AddLlamachantFrameworkDragDropBlazorModule();
});

IMPORTANT

This module requires you to register the module using AddLlamachantFrameworkDragDropBlazorModule() in the application builder rather than adding it to the RequiredModuleTypes collection.

TIP

If you are using custom templates, set the options within the AddLlamachantFrameworkDragDropBlazorModule() call.

services.AddXaf(Configuration, builder => {
    builder.UseApplication<ExpressAppBlazorApplication>();
    builder.Modules.AddLlamachantFrameworkDragDropModuleBlazor(options => {
        options.UseDetailFormTemplate = false;
        options.UseNestedFrameTemplate = false;
    });
});

Drag / Drop Templates

When this module is added to your application, it automatically enables drag-and-drop file upload functionality on list views using two built-in templates. These templates are applied specifically for the following view contexts:

  • TemplateContext.NestedFrame
  • TemplateContext.View

In addition to supporting drag-and-drop, these templates also provide a clickable link that allows users to browse and select files from their computer or device, improving usability.

Filtering File Extensions and File Types

You can restrict which files users are allowed to upload by specifying file extensions or MIME types. Behind the scenes, this feature uses a DxFileInput component from DevExpress.

To control the accepted files:

  • Set DragDropAcceptedFileTypes to define allowed MIME types (e.g., image/png, application/pdf).
  • Set DragDropAllowedExtensions to define allowed file extensions (e.g., .jpg, .docx).

These values are automatically passed to the AcceptedFileTypes and AllowedFileExtensions properties of the DxFileInput control. Make sure to follow the DevExpress guidelines for formatting these values.

ISupportDragDrop

If your class does not implement IFileData, IFileAttachment, or use the [FileAttachment] attribute, you can still support drag-and-drop functionality by implementing the ISupportDragDrop interface.

namespace LlamachantFramework.DragDrop.Blazor.Interfaces;

public interface ISupportDragDrop
{
    void LoadFromStream(string filename, Stream stream);
}

When a file is dropped, an instance of your class is created and the LoadFromStream method is called. This gives you control over how the file content is handled.

Example: Parsing a Dropped Text File

In the following example, a text file is dropped onto the Contacts list view. The file contents are parsed to populate the Name, EmailAddress, and PhoneNumber properties of a new Contact object.

using LlamachantFramework.DragDrop.Blazor.Interfaces;

public class Contact(Session session) :
    BaseObject(session), ISupportDragDrop
{

private string _Name;
    public string Name
    {
        get { return _Name; }
        set { SetPropertyValue<string>(nameof(Name), ref _Name, value); }
    }

private string _PhoneNumber;
    public string PhoneNumber
    {
        get { return _PhoneNumber; }
        set { SetPropertyValue<string>(nameof(PhoneNumber), ref _PhoneNumber, value); }
    }

private string _EmailAddress;
    public string EmailAddress
    {
        get { return _EmailAddress; }
        set { SetPropertyValue<string>(nameof(EmailAddress), ref _EmailAddress, value); }
    }

private Client _Client;
    [Association]
    public Client Client
    {
        get { return _Client; }
        set { SetPropertyValue<Client>(nameof(Client), ref _Client, value); }
    }

public void LoadFromStream(string filename, Stream stream)
    {
        using StreamReader reader = new StreamReader(stream);
        string content = reader.ReadToEnd();

List<string> lines = content.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).ToList();

Name = lines.FirstOrDefault(x => x.StartsWith("name:", StringComparison.InvariantCultureIgnoreCase))?.Substring(5);
        EmailAddress = lines.FirstOrDefault(x => x.StartsWith("email:", StringComparison.InvariantCultureIgnoreCase))?.Substring(6);
        PhoneNumber = lines.FirstOrDefault(x => x.StartsWith("phone:", StringComparison.InvariantCultureIgnoreCase))?.Substring(6);
    }
}

Notes

  • Security: Always validate the file content to avoid malicious input. You may want to restrict parsing to expected formats only.
  • Error Handling: Consider wrapping file parsing in try-catch blocks to handle malformed data or unexpected errors gracefully.
  • Logging: Adding basic logging can help track dropped file activity and diagnose issues.