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.
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.
Install-Package 'Llamachant.ExpressApp.DragDrop.Blazor'
services.AddXaf(Configuration, builder => {
builder.UseApplication<ExpressAppBlazorApplication>();
builder.Modules.AddLlamachantFrameworkDragDropBlazorModule();
});
This module requires you to register the module using AddLlamachantFrameworkDragDropBlazorModule() in the application builder rather than adding it to the RequiredModuleTypes collection
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;
});
});
Install-Package 'Llamachant.ExpressApp.DragDrop.Blazor'
services.AddXaf(Configuration, builder => {
builder.UseApplication<ExpressAppBlazorApplication>();
builder.Modules.AddLlamachantFrameworkDragDropBlazorModule();
});
This module requires you to register the module using AddLlamachantFrameworkDragDropBlazorModule() in the application builder rather than adding it to the RequiredModuleTypes collection
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;
});
});
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.NestedFrameTemplateContext.ViewIn 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.
If you're using custom templates and want to integrate this drag-and-drop upload feature, refer to the Custom Templates section below for instructions.
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.NestedFrameTemplateContext.ViewIn 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.
If you're using custom templates and want to integrate this drag-and-drop upload feature, refer to the Custom Templates section below for instructions.
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:
DragDropAcceptedFileTypes to define allowed MIME types (e.g., image/png, application/pdf).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.
| Application | Llamachant Framework | Example Values |
|---|---|---|
| DragDropAcceptedFileTypes | image/*;application/pdf | |
| DragDropAllowedExtensions | .jpg;.png;.pdf |
See more information on available MIME 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:
DragDropAcceptedFileTypes to define allowed MIME types (e.g., image/png, application/pdf).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.
| Application | Llamachant Framework | Example Values |
|---|---|---|
| DragDropAcceptedFileTypes | image/*;application/pdf | |
| DragDropAllowedExtensions | .jpg;.png;.pdf |
See more information on available MIME types
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.
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);
}
}
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.
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);
}
}
If you're using your own custom Blazor XAF templates and want to support drag-and-drop functionality, implement the IDragDropTemplate interface:
namespace LlamachantFramework.DragDrop.Blazor.Interfaces;
public interface IDragDropTemplate
{
DragDropViewComponentModel ComponentModel { get; }
}
Your template class should initialize a DragDropViewComponentModel and expose it through the ComponentModel property. Here's an example for a custom nested frame template:
using LlamachantFramework.DragDrop.Blazor.Interfaces;
public class MyCustomNestedFrameTemplate : NestedFrameTemplate, IDragDropTemplate
{
public MyCustomNestedFrameTemplate()
{
ComponentModel = new DragDropViewComponentModel(this);
}
protected override RenderFragment CreateComponent() =>
DragDropNestedFrameTemplateComponent.Create(this);
public DragDropViewComponentModel ComponentModel { get; }
}
Within your custom component's markup, include the <LCTDragDropTarget> component and pass the ComponentModel from your frame template:
@using DevExpress.ExpressApp.Blazor
@using DevExpress.ExpressApp.Blazor.Templates
@using LlamachantFramework.DragDrop.Blazor.Components
@inherits FrameTemplateComponentBase<MyCustomNestedFrameTemplate>
<div class="nested-frame" data-frame-name="@FrameTemplate.View?.Caption">
<div class="nested-toolbar">
@FrameTemplate.Toolbar.GetComponentContent()
</div>
<div class="nested-content">
@* Drag-and-Drop Target *@
<LCTDragDropTarget ComponentModel="@FrameTemplate.ComponentModel" />
<ViewSiteComponent ViewHolder="@FrameTemplate" />
</div>
</div>
@code {
public static RenderFragment Create(MyCustomNestedFrameTemplate nestedFrameTemplate) =>
@<DragDropNestedFrameTemplateComponent FrameTemplate="@nestedFrameTemplate" />;
}
If you want to specify a custom element as the drag-and-drop target, use the DropZoneElementID parameter:
<LCTDragDropTarget
ComponentModel="@FrameTemplate.ComponentModel"
DropZoneElementID="your-custom-dropzone-id" />
This allows you to route drag-and-drop interactions to a specific element rather than the default target.
If you're using your own custom Blazor XAF templates and want to support drag-and-drop functionality, implement the IDragDropTemplate interface:
namespace LlamachantFramework.DragDrop.Blazor.Interfaces;
public interface IDragDropTemplate
{
DragDropViewComponentModel ComponentModel { get; }
}
Your template class should initialize a DragDropViewComponentModel and expose it through the ComponentModel property. Here's an example for a custom nested frame template:
using LlamachantFramework.DragDrop.Blazor.Interfaces;
public class MyCustomNestedFrameTemplate : NestedFrameTemplate, IDragDropTemplate
{
public MyCustomNestedFrameTemplate()
{
ComponentModel = new DragDropViewComponentModel(this);
}
protected override RenderFragment CreateComponent() =>
DragDropNestedFrameTemplateComponent.Create(this);
public DragDropViewComponentModel ComponentModel { get; }
}
Within your custom component's markup, include the <LCTDragDropTarget> component and pass the ComponentModel from your frame template:
@using DevExpress.ExpressApp.Blazor
@using DevExpress.ExpressApp.Blazor.Templates
@using LlamachantFramework.DragDrop.Blazor.Components
@inherits FrameTemplateComponentBase<MyCustomNestedFrameTemplate>
<div class="nested-frame" data-frame-name="@FrameTemplate.View?.Caption">
<div class="nested-toolbar">
@FrameTemplate.Toolbar.GetComponentContent()
</div>
<div class="nested-content">
@* Drag-and-Drop Target *@
<LCTDragDropTarget ComponentModel="@FrameTemplate.ComponentModel" />
<ViewSiteComponent ViewHolder="@FrameTemplate" />
</div>
</div>
@code {
public static RenderFragment Create(MyCustomNestedFrameTemplate nestedFrameTemplate) =>
@<DragDropNestedFrameTemplateComponent FrameTemplate="@nestedFrameTemplate" />;
}
If you want to specify a custom element as the drag-and-drop target, use the DropZoneElementID parameter:
<LCTDragDropTarget
ComponentModel="@FrameTemplate.ComponentModel"
DropZoneElementID="your-custom-dropzone-id" />
This allows you to route drag-and-drop interactions to a specific element rather than the default target.