Drop Zone

Drag and Drop.

Basic Usage

Drop Zone 1
Drag me!
Just Mud
Drop Zone 2
Or me!
<MudDropContainer T="DropItem" Items="_items" ItemsSelector="@((item,dropzone) => item.Identifier == dropzone)" ItemDropped="ItemUpdated" Class="d-flex flex-wrap flex-grow-1">
    <ChildContent>
        <MudDropZone T="DropItem" Identifier="Drop Zone 1" Class="rounded mud-background-gray pa-6 ma-8 flex-grow-1">
            <MudText Typo="Typo.h6" Class="mb-4">Drop Zone 1</MudText>
         </MudDropZone>
        <MudDropZone T="DropItem" Identifier="Drop Zone 2" Class="rounded mud-background-gray pa-6 ma-8 flex-grow-1">
            <MudText Typo="Typo.h6" Class="mb-4">Drop Zone 2</MudText>
        </MudDropZone>
    </ChildContent>
    <ItemRenderer>
        <MudPaper Elevation="25" Class="pa-4 my-4">@context.Name</MudPaper>
    </ItemRenderer>
</MudDropContainer>
@code {
    private void ItemUpdated(MudItemDropInfo<DropItem> dropItem)
    {
        dropItem.Item.Identifier = dropItem.DropzoneIdentifier;
    }
    
    private List<DropItem> _items = new()
    {
        new DropItem(){ Name = "Drag me!", Identifier = "Drop Zone 1" },
        new DropItem(){ Name = "Or me!", Identifier = "Drop Zone 2" },
        new DropItem(){ Name = "Just Mud", Identifier = "Drop Zone 1" },
    };
    
    public class DropItem
    {
        public string Name { get; init; }
        public string Identifier { get; set; }
    }
}
Nested Drop Zones

Drop Zone 1

Item 1

Item 2

Drop Zone 2

Item 3

<MudDropContainer T="DropZoneItem" Items="_items" ItemsSelector="@((item, dropzone) => item.Zone == dropzone)" ItemDropped="ItemUpdated" Class="4 flex-grow-1">
    <ChildContent>
        <MudDropContainer T="DropZone" Items="_zones" ItemsSelector="@((item, dropzone) => true)" Class="5">
            <ChildContent>
                <MudDropZone T="DropZone" AllowReorder Class="6 rounded mud-background-gray px-4 py-1 ma-4" />
             </ChildContent>
             <ItemRenderer>
                 <MudPaper Class="pa-4 my-4">
                     <MudText Typo="Typo.h6">@context.Name</MudText>
                     <MudDropZone T="DropZoneItem" Identifier="@context.Name" AllowReorder Class="rounded mud-background-gray px-4 py-1 ma-4" />
                 </MudPaper>
             </ItemRenderer>
         </MudDropContainer>
     </ChildContent>
     <ItemRenderer>
         <MudPaper Class="pa-4 my-4">
             <MudText>@context.Name</MudText>
         </MudPaper>
     </ItemRenderer>
 </MudDropContainer>
@code {

    private void ItemUpdated(MudItemDropInfo<DropZoneItem> dropItem) => dropItem.Item.Zone = dropItem.DropzoneIdentifier;

    private List<DropZone> _zones = new()
    {
        new() { Name = "Drop Zone 1" },
        new() { Name = "Drop Zone 2" }
    };

    private List<DropZoneItem> _items = new()
    {
        new() { Zone = "Drop Zone 1", Name = "Item 1" },
        new() { Zone = "Drop Zone 1", Name = "Item 2" },
        new() { Zone = "Drop Zone 2", Name = "Item 3" },
    };

    private class DropZone
    {
        public string Name { get; init; }
    }

    private class DropZoneItem
    {
        public string Zone { get; set; }
        public string Name { get; init; }
    }
}
Transfer items between Drop Zones

The MudDropContainer supports transferring dragged items between its drop zones. The MudDropContainer holds the collection of items used for dragging.

Drop Item Selector

Each MudDropZone has a unique settable Identifier that is used to determine what item should be placed in what dropzone. Provide the MudDropContainer with a selector function (Func<T, string, bool>) for the property ItemSelector to place the items correctly. This method can be overridden by each drop zone. The callback ItemDropped should be used to update the data item, when a drag operation has finished.

Drop Zone 1

Item 1

Item 2

Item 3

Drop Zone 2

Item 4

Item 5

Drop Zone 3
<MudDropContainer T="DropItem" Items="_items" ItemsSelector="@((item,dropzone) => item.Selector == dropzone)" ItemDropped="ItemUpdated" Class="d-flex flex-wrap flex-grow-1">
    <ChildContent>
        @for (int i = 1; i < 4; i++) 
         {
             var dropzone = i.ToString();
             <MudPaper Class="ma-4 flex-grow-1">
                <MudList T="string" Class="d-flex flex-column mud-height-full">
                     <MudListSubheader>Drop Zone @dropzone</MudListSubheader>
                     <MudDropZone T="DropItem" Identifier="@dropzone" Class="flex-grow-1" />
                 </MudList>
             </MudPaper>
         }
    </ChildContent>
    <ItemRenderer>
        <MudListItem T="string" Text="@context.Name" />
    </ItemRenderer>
</MudDropContainer>
@code {
    private void ItemUpdated(MudItemDropInfo<DropItem> dropItem)
    {
        dropItem.Item.Selector = dropItem.DropzoneIdentifier;
    }

    private List<DropItem> _items = new()
    {
        new DropItem(){ Name = "Item 1", Selector = "1" },
        new DropItem(){ Name = "Item 2", Selector = "1" },
        new DropItem(){ Name = "Item 3", Selector = "1" },
        new DropItem(){ Name = "Item 4", Selector = "2" },
        new DropItem(){ Name = "Item 5", Selector = "2" },
    };
    
    public class DropItem
    {
        public string Name { get; init; }
        public string Selector { get; set; }
    }
}
Reorder items

Items can be reordered inside each dropzone with the AllowReorder bool set to true on the dropzone.

Drop Zone 1

Item 1

Item 2

Item 3

Drop Zone 2

Item 4

Item 5

Drop Zone 3
<MudDropContainer T="DropItem" Items="_items" ItemsSelector="@((item,dropzone) => item.Selector == dropzone)" ItemDropped="ItemUpdated" Class="d-flex flex-wrap flex-grow-1">
    <ChildContent>
        @for (int i = 1; i < 4; i++) 
         {
             var dropzone = i.ToString();
             <MudPaper Class="ma-4 flex-grow-1">
                <MudList T="string" Class="d-flex flex-column mud-height-full">
                     <MudListSubheader>Drop Zone @dropzone</MudListSubheader>
                     <MudDropZone T="DropItem" Identifier="@dropzone" Class="flex-grow-1" AllowReorder="true" />
                 </MudList>
             </MudPaper>
         }
    </ChildContent>
    <ItemRenderer>
        <MudListItem T="string" Text="@context.Name" />
    </ItemRenderer>
</MudDropContainer>
@code {
    private void ItemUpdated(MudItemDropInfo<DropItem> dropItem)
    {
        dropItem.Item.Selector = dropItem.DropzoneIdentifier;
    }

    private List<DropItem> _items = new()
    {
        new DropItem(){ Name = "Item 1", Selector = "1" },
        new DropItem(){ Name = "Item 2", Selector = "1" },
        new DropItem(){ Name = "Item 3", Selector = "1" },
        new DropItem(){ Name = "Item 4", Selector = "2" },
        new DropItem(){ Name = "Item 5", Selector = "2" },
    };
    
    public class DropItem
    {
        public string Name { get; init; }
        public string Selector { get; set; }
    }
}
Save Reorder data

In this example we show one way to save the re-ordered data, click load and drag some items around then hit save and load again.

Drop Zone 1
Drop Zone 2
@using MudBlazor.Utilities

<div class="d-flex flex-column mud-width-full mud-height-full">
    <MudToolBar Class="gap-4">
        <MudButton OnClick="LoadServerData" Variant="Variant.Filled" Color="Color.Default">Load Data</MudButton>
        <MudButton OnClick="SaveData" Variant="Variant.Filled" Color="Color.Primary">Save Data</MudButton>
        <MudSpacer />
        <MudButton OnClick="Reset" Variant="Variant.Text" Color="Color.Error">Reset Example</MudButton>
    </MudToolBar>

    <MudDropContainer T="DropItem" Items="@_dropzoneItems" @ref="_container" ItemsSelector="@((item,dropzone) => item.Selector == dropzone)" ItemDropped="ItemUpdated" Class="d-flex flex-wrap flex-grow-1">
        <ChildContent>
            @for (int i = 1; i < 3; i++)
            {
                var dropzone = i.ToString();
                <MudPaper Class="ma-4 flex-grow-1">
                    <MudList T="string" Class="d-flex flex-column mud-height-full">
                        <MudListSubheader>Drop Zone @dropzone</MudListSubheader>
                        <MudDropZone T="DropItem" Identifier="@dropzone" Class="flex-grow-1" AllowReorder="true" />
                    </MudList>
                </MudPaper>
            }
        </ChildContent>
        <ItemRenderer>
            <MudListItem T="string" Text="@($"{context.Name} ({context.Order})")" />
        </ItemRenderer>
    </MudDropContainer>
</div>
@code {
    private MudDropContainer<DropItem> _container;

    private void ItemUpdated(MudItemDropInfo<DropItem> dropItem)
    {
        dropItem.Item.Selector = dropItem.DropzoneIdentifier;

        var indexOffset = dropItem.DropzoneIdentifier switch
        {
            "2"  => _dropzoneItems.Count(x => x.Selector == "1"),
            _ => 0
        };

        _dropzoneItems.UpdateOrder(dropItem, item => item.Order, indexOffset);
    }

    private List<DropItem> _dropzoneItems = new();

    private List<DropItem> _serverData = new()
        {
            new DropItem() { Order = 0, Name = "Item 1", Selector = "1" },
            new DropItem() { Order = 1, Name = "Item 2", Selector = "1" },
            new DropItem() { Order = 2, Name = "Item 3", Selector = "1" },
            new DropItem() { Order = 3, Name = "Item 4", Selector = "1" },
            new DropItem() { Order = 4, Name = "Item 5", Selector = "1" },
            new DropItem() { Order = 5, Name = "Item 6", Selector = "1" },
            new DropItem() { Order = 6, Name = "Item 7", Selector = "2" },
            new DropItem() { Order = 7, Name = "Item 8", Selector = "2" },
            new DropItem() { Order = 8, Name = "Item 9", Selector = "2" },
            new DropItem() { Order = 9, Name = "Item 10", Selector = "2" },
        };

    private void RefreshContainer()
    {
        //update the binding to the container
        StateHasChanged();

        //the container refreshes the internal state
        _container.Refresh();
    }

    private void LoadServerData()
    {
        _dropzoneItems = _serverData
            .OrderBy(x => x.Order)
            .Select(item => new DropItem
            {
                Order = item.Order,
                Name = item.Name,
                Selector = item.Selector
            })
            .ToList();
        RefreshContainer();
    }

    private void SaveData()
        => _serverData = _dropzoneItems
            .OrderBy(x => x.Order)
            .Select(item => new DropItem
            {
                Order = item.Order, Name = item.Name, Selector = item.Selector
            })
            .ToList();

    private void Reset()
    {
        _dropzoneItems = new();
        _serverData = new()
            {
                new DropItem() { Order = 0, Name = "Item 1", Selector = "1" },
                new DropItem() { Order = 1, Name = "Item 2", Selector = "1" },
                new DropItem() { Order = 2, Name = "Item 3", Selector = "1" },
                new DropItem() { Order = 3, Name = "Item 4", Selector = "1" },
                new DropItem() { Order = 4, Name = "Item 5", Selector = "1" },
                new DropItem() { Order = 5, Name = "Item 6", Selector = "1" },
                new DropItem() { Order = 6, Name = "Item 7", Selector = "2" },
                new DropItem() { Order = 7, Name = "Item 8", Selector = "2" },
                new DropItem() { Order = 8, Name = "Item 9", Selector = "2" },
                new DropItem() { Order = 9, Name = "Item 10", Selector = "2" }
            };

        RefreshContainer();
    }
    
    public class DropItem
    {
        public string Name { get; init; }
        public string Selector { get; set; }
        public int Order { get; set; }
    }
}
Only Zones

With the OnlyZone property set to true, the dropzone will only act as a dropable zone and not render any items.

Folders
Propaganda
Work
Files
Untitled document
GoonSwarmBestSwarm.png
co2traitors.txt
import.csv
planned_components_2022-2023.txt
<MudDropContainer T="DropItem" Items="_items" ItemsSelector="@((item,dropzone) => item.Identifier == dropzone)" ItemDropped="ItemUpdated" Class="d-flex flex-column flex-grow-1">
    <ChildContent>
        <MudListSubheader Class="mt-4 pb-2">Folders</MudListSubheader>
        <div class="d-flex gap-4 mx-4">
            <MudDropZone T="DropItem" OnlyZone="true" Identifier="Propaganda">
                <MudPaper Outlined="true" Class="d-flex align-center pa-3 gap-2">
                    <MudIcon Icon="@Icons.Custom.Uncategorized.Folder" Color="Color.Inherit" />Propaganda
                </MudPaper>
            </MudDropZone>
           <MudDropZone T="DropItem" OnlyZone="true" Identifier="Work">
                <MudPaper Outlined="true" Class="d-flex align-center pa-3 gap-2">
                    <MudIcon Icon="@Icons.Custom.Uncategorized.Folder" Color="Color.Inherit" />Work
                </MudPaper>
            </MudDropZone>
        </div>
        <MudListSubheader Class="mt-4 pb-2">Files</MudListSubheader>
        <MudDropZone T="DropItem" Identifier="Files" Class="d-flex flex-wrap flex-grow-1 pa-2 rounded" />
    </ChildContent>
    <ItemRenderer>
        <div Class="rounded mud-paper-outlined d-flex align-center pa-3 ma-2">
            <MudIcon Icon="@(context.Identifier == "Folders" ? Icons.Custom.Uncategorized.Folder : Icons.Custom.FileFormats.FileDocument)" Color="Color.Inherit" Class="mr-2"/>
            @context.Name
        </div>
    </ItemRenderer>
</MudDropContainer>
@code {
    private void ItemUpdated(MudItemDropInfo<DropItem> dropItem)
    {
        dropItem.Item.Identifier = dropItem.DropzoneIdentifier;
    }
    
    private List<DropItem> _items = new()
    {
        new DropItem(){ Name = "Untitled document", Identifier = "Files" },
        new DropItem(){ Name = "GoonSwarmBestSwarm.png", Identifier = "Files" },
        new DropItem(){ Name = "co2traitors.txt", Identifier = "Files" },
        new DropItem(){ Name = "import.csv", Identifier = "Files" },
        new DropItem(){ Name = "planned_components_2022-2023.txt", Identifier = "Files" },
    };
    
    public class DropItem
    {
        public string Name { get; init; }
        public string Identifier { get; set; }
    }
}
Drop Rules

If a draggable item can be dropped or not can be controlled with the CanDrop function, either globally in the MudDropContainer or per MudDropZone.

Compost Bin
Recycle Bin
Trash Bin
Apple Core
Banana Peel
Old Battery
Pizza Box
Moldy Bread
Paper Bag
Uranium-235
<MudDropContainer T="DropItem" Items="_items" ItemsSelector="@((item,dropzone) => item.Place == dropzone)" ItemDropped="ItemUpdated" Class="d-flex flex-column flex-grow-1">
    <ChildContent>
        <div class="d-flex flex-wrap justify-space-between">
            <MudDropZone T="DropItem" Identifier="Compost" CanDrop="@((item) => item.Type == ItemType.Compost)" Class="rounded-lg mud-alert-text-success pa-4 ma-4 flex-grow-1">
                <MudText Typo="Typo.button" Class="ma-2">Compost Bin</MudText>
            </MudDropZone>
            <MudDropZone T="DropItem" Identifier="Recycle" CanDrop="@((item) => item.Type == ItemType.Recycle)" Class="rounded-lg mud-alert-text-warning pa-4 ma-4 flex-grow-1">
                <MudText Typo="Typo.button" Class="ma-2">Recycle Bin</MudText>
            </MudDropZone>
            <MudDropZone T="DropItem" Identifier="Trash" CanDrop="@((item) => item.Type == ItemType.Trash)" Class="rounded-lg mud-alert-text-info pa-4 ma-4 flex-grow-1">
                <MudText Typo="Typo.button" Class="ma-2">Trash Bin</MudText>
            </MudDropZone>
        </div>
        <MudDropZone T="DropItem" Identifier="Street" CanDrop="@((item) => false)" Class="rounded-lg mud-alert-text-normal pa-4 mt-6 mx-4 flex-grow-1 d-flex flex-wrap"/>
    </ChildContent>
    <ItemRenderer>
        <MudPaper Elevation="25" Class="pa-4 ma-2">@context.Name</MudPaper>
    </ItemRenderer>
</MudDropContainer>
@code {
    private void ItemUpdated(MudItemDropInfo<DropItem> dropItem)
    {
        dropItem.Item.Place = dropItem.DropzoneIdentifier;
    }
    
    private List<DropItem> _items = new()
    {
        new DropItem(){ Name = "Apple Core", Type = ItemType.Compost, Place = "Street" },
        new DropItem(){ Name = "Banana Peel", Type = ItemType.Compost, Place = "Street" },
        new DropItem(){ Name = "Old Battery", Type = ItemType.Trash, Place = "Street" },
        new DropItem(){ Name = "Pizza Box", Type = ItemType.Recycle, Place = "Street" },
        new DropItem(){ Name = "Moldy Bread", Type = ItemType.Compost, Place = "Street" },
        new DropItem(){ Name = "Paper Bag", Type = ItemType.Recycle, Place = "Street" },
        new DropItem(){ Name = "Uranium-235", Type = ItemType.Trash, Place = "Street" },
    };
    
    public class DropItem
    {
        public string Name { get; set; }
        public ItemType Type { get; set; }
        public string Place { get; set; }
    }

    public enum ItemType
    {
        Compost,
        Recycle,
        Trash
    }
}
Drop Rule Styling

The cursor will change if a item can or cannot be dropped but it's also possible to effect the whole drop zone.
Add one of our or one of your own CSS class to CanDropClass and NoDropClass to change the styling of each behavior.

Fridge
Soup
Trash
<MudDropContainer T="DropItem" Items="_items" ApplyDropClassesOnDragStarted="_applyDropClassesOnDragStarted" ItemsSelector="@((item,dropzone) => item.Place == dropzone)" CanDropClass="mud-border-success" NoDropClass="mud-border-error" ItemDropped="ItemUpdated" Class="d-flex flex-column flex-grow-1">
    <ChildContent>
        <div class="d-flex flex-wrap justify-space-between">
            <MudDropZone T="DropItem" Identifier="Fridge" CanDrop="@((item) => false)" Class="rounded-lg border-2 border-solid mud-border-lines-default pa-6 ma-8">
                <MudText Typo="Typo.h6" Class="mb-4">Fridge</MudText>
            </MudDropZone>
            <MudDropZone T="DropItem" Identifier="Dinner" CanDrop="@((item) => item.IsPicked == false && item.IsRotten == false)" Class="rounded-lg border-2 border-solid mud-border-lines-default pa-6 ma-8 flex-grow-1">
                <MudText Typo="Typo.h6" Class="mb-4">Soup</MudText>
            </MudDropZone>
            <MudDropZone T="DropItem" Identifier="Trash" CanDrop="@((item) => item.IsPicked == false && item.IsRotten == true)" Class="rounded-lg border-2 border-dashed mud-border-lines-default pa-6 ma-8 flex-grow-1">
                <MudText Typo="Typo.h6" Class="mb-4">Trash</MudText>
            </MudDropZone>
        </div>
        <MudToolBar>
            <MudCheckBox @bind-Value="_applyDropClassesOnDragStarted" Label="Apply Drop Classes On Drag Started" />
            <MudSpacer/>
            <MudButton OnClick="Reset">Reset</MudButton>
        </MudToolBar>
    </ChildContent>
    <ItemRenderer>
        <MudPaper Height="54px" Width="54px" Class="pa-2" Elevation="0">
            <MudBadge Visible="@(context.IsRotten ? true : false)" Overlap="true" Icon="@Icons.Custom.Uncategorized.Bacteria" Color="Color.Dark">
                <MudIcon Icon="@context.Icon" Color="@context.Color" Size="Size.Large"/>
            </MudBadge>
        </MudPaper>
    </ItemRenderer>
</MudDropContainer>
@code {
    private bool _applyDropClassesOnDragStarted = false;

    private void Reset()
    {
        foreach (var item in _items)
        {
            item.Place = "Fridge";
            item.IsPicked = false;
        }
    }

    private void ItemUpdated(MudItemDropInfo<DropItem> dropItem)
    {
        dropItem.Item.IsPicked = true;
        dropItem.Item.Place = dropItem.DropzoneIdentifier;
    }

    private List<DropItem> _items = new()
        {
            new DropItem() { Icon = @Icons.Custom.Uncategorized.FoodApple, Color = Color.Error, IsRotten = false, Place = "Fridge" },
            new DropItem() { Icon = @Icons.Custom.Uncategorized.Baguette, Color = Color.Warning, IsRotten = false, Place = "Fridge" },
            new DropItem() { Icon = @Icons.Custom.Uncategorized.Sausage, Color = Color.Secondary, IsRotten = true, Place = "Fridge" },
            new DropItem() { Icon = @Icons.Custom.Uncategorized.WaterMelon, Color = Color.Success, IsRotten = false, Place = "Fridge" },
            new DropItem() { Icon = @Icons.Custom.Uncategorized.Fish, Color = Color.Info, IsRotten = true, Place = "Fridge" },
        };

    public class DropItem
    {
        public string Icon { get; init; }
        public Color Color { get; init; }
        public bool IsRotten { get; set; }
        public bool IsPicked { get; set; }
        public string Place { get; set; }
    }
}
Dragging Styles

Its possible to style the drop zone from which the dragged item starts from as well as the item itself with the DraggingClass parameter and the ItemDraggingClass property.

Folders
Wallpapers
Propaganda
Funny, Dank, Meme
Work
Photos
Files
Untitled spreadsheet
LoseLips.txt
Untitled document
GoonSwarmBestSwarm.png
co2traitors.txt
import.csv
MudBlazor Secrets
planned_components_2022-2023.txt
<MudDropContainer T="DropItem" Items="_items" ItemsSelector="@((item,dropzone) => item.Identifier == dropzone)" ItemDropped="ItemUpdated" Class="d-flex flex-column flex-grow-1">
    <ChildContent>
        <div class="d-flex flex-column flex-grow-1">
            <MudListSubheader Class="mt-4 pb-2">Folders</MudListSubheader>
            <MudDropZone T="DropItem" ItemDraggingClass="mud-info-text" Identifier="Folders" Class="d-flex flex-wrap flex-grow-1 pa-2 rounded" />
        </div>
        <div class="d-flex flex-column flex-grow-1">
            <MudListSubheader Class="mt-4 pb-2">Files</MudListSubheader>
            <MudDropZone T="DropItem" DraggingClass="mud-alert-text-normal" Identifier="Files" Class="d-flex flex-wrap flex-grow-1 pa-2 rounded" />
        </div>
        <div class="d-flex flex-column flex-grow-1">
            <MudListSubheader Class="mt-4 pb-2">MudBlazor Secrets</MudListSubheader>
            <MudDropZone T="DropItem" DraggingClass="mud-alert-text-error" ItemDraggingClass="mud-error-text" Identifier="MudBlazor" Class="d-flex flex-wrap flex-grow-1 pa-2 rounded" />
        </div>
    </ChildContent>
    <ItemRenderer>
        <div Class="rounded mud-paper-outlined d-flex align-center pa-3 ma-2">
            <MudIcon Icon="@(context.Identifier == "Folders" ? Icons.Custom.Uncategorized.Folder : Icons.Custom.FileFormats.FileDocument)" Color="Color.Inherit" Class="mr-2"/>
            @context.Name
        </div>
    </ItemRenderer>
</MudDropContainer>
@code {
    private void ItemUpdated(MudItemDropInfo<DropItem> dropItem)
    {
        dropItem.Item.Identifier = dropItem.DropzoneIdentifier;
    }
    
    private List<DropItem> _items = new()
    {
        new DropItem(){ Name = "Wallpapers", Identifier = "Folders" },
        new DropItem(){ Name = "Propaganda", Identifier = "Folders" },
        new DropItem(){ Name = "Funny, Dank, Meme", Identifier = "Folders" },
        new DropItem(){ Name = "Work", Identifier = "Folders" },
        new DropItem(){ Name = "Photos", Identifier = "Folders" },
        new DropItem(){ Name = "Untitled spreadsheet", Identifier = "Files" },
        new DropItem(){ Name = "LoseLips.txt", Identifier = "Files" },
        new DropItem(){ Name = "Untitled document", Identifier = "Files" },
        new DropItem(){ Name = "GoonSwarmBestSwarm.png", Identifier = "Files" },
        new DropItem(){ Name = "co2traitors.txt", Identifier = "Files" },
        new DropItem(){ Name = "import.csv", Identifier = "Files" },
        new DropItem(){ Name = "planned_components_2022-2023.txt", Identifier = "MudBlazor" },
    };
    
    public class DropItem
    {
        public string Name { get; init; }
        public string Identifier { get; set; }
    }
}
Override Values

Like the selector functions, the container also provides other values, like DraggingClass, that act as default values for all drop zones but can be overridden by the drop zone itself.

USS Enterprise
Grumman
Tomcat
McDonnell
Air Zone 1
Air Zone 2
Danger Zone
Frogfoot
Fulcrum
Fullback
<MudDropContainer T="DropItem" DraggingClass="mud-alert-text-warning" ItemDraggingClass="mud-alert-text-warning" Items="_items" ItemsSelector="@((item,dropzone) => item.Identifier == dropzone)" NoDropClass="mud-border-error" ItemDropped="ItemUpdated" Class="d-flex flex-wrap flex-grow-1">
    <ChildContent>
        <MudDropZone T="DropItem" Identifier="Enterprise" DraggingClass="mud-alert-text-info" ItemDraggingClass="mud-alert-text-info" Class="rounded-lg border-2 border-dashed mud-border-lines-default pa-6 ma-8" CanDrop="@((item) => item.Team == "BLUE")">
            <MudText Typo="Typo.h6" Class="mb-4">USS Enterprise</MudText>
         </MudDropZone>
        <MudDropZone T="DropItem" Identifier="Air Zone 1" Class="rounded-lg border-2 border-dashed mud-border-lines-default pa-6 ma-8 flex-grow-1">
            <MudText Typo="Typo.h6" Class="mb-4">Air Zone 1</MudText>
        </MudDropZone>
        <MudDropZone T="DropItem" Identifier="Air Zone 2" Class="rounded-lg border-2 border-dashed mud-border-lines-default pa-6 ma-8 flex-grow-1">
            <MudText Typo="Typo.h6" Class="mb-4">Air Zone 2</MudText>
        </MudDropZone>
        <MudDropZone T="DropItem" Identifier="Danger Zone" DraggingClass="mud-alert-text-error" ItemDraggingClass="mud-alert-text-error" CanDrop="@((item) => item.Team == "RED")" Class="rounded-lg border-2 border-dashed mud-border-lines-default pa-6 ma-8">
            <MudText Typo="Typo.h6" Class="mb-4">Danger Zone</MudText>
        </MudDropZone>
    </ChildContent>
    <ItemRenderer>
        <div class="mud-elevation-25 pa-4 my-4">@context.Name</div>
    </ItemRenderer>
</MudDropContainer>
@code {
    private void ItemUpdated(MudItemDropInfo<DropItem> dropItem)
    {
        dropItem.Item.Identifier = dropItem.DropzoneIdentifier;
    }
    
    private List<DropItem> _items = new()
    {
        new DropItem(){ Name = "Grumman", Team = "BLUE", Identifier = "Enterprise" },
        new DropItem(){ Name = "Tomcat", Team = "BLUE", Identifier = "Enterprise" },
        new DropItem(){ Name = "McDonnell", Team = "BLUE", Identifier = "Enterprise" },
        new DropItem(){ Name = "Frogfoot", Team = "RED", Identifier = "Danger Zone" },
        new DropItem(){ Name = "Fulcrum", Team = "RED", Identifier = "Danger Zone" },
        new DropItem(){ Name = "Fullback", Team = "RED", Identifier = "Danger Zone" },
    };
    
    public class DropItem
    {
        public string Name { get; init; }
        public string Team { get; init; }
        public string Identifier { get; set; }
    }
}
Disabled items

Drop items can be prevented from being dragged by using the ItemDisabled property.

Company Files

File1.txt

File3.txt

File4.txt

File6.txt

External USB

File2.txt

File5.txt

<MudDropContainer T="FileItem" ItemDisabled="@(item => item.IsLocked)" Items="_items"
                  ItemsSelector="@((item, dropzone) => item.TransferSlot == dropzone)" ItemDropped="ItemUpdated" Class="d-flex flex-wrap">
    <ChildContent>
        <MudPaper Class="ma-4" Height="400px" Width="300px">
            <MudList T="string" Class="mud-height-full">
                <MudDropZone T="FileItem" Identifier="Company" Class="mud-height-full">
                    <MudListSubheader>Company Files</MudListSubheader>
                </MudDropZone>
            </MudList>
        </MudPaper>
        <MudPaper Class="ma-4" Height="400px" Width="300px">
            <MudList T="string" Class="mud-height-full">
                <MudDropZone T="FileItem" Identifier="External" Class="mud-height-full">
                    <MudListSubheader>External USB</MudListSubheader>
                </MudDropZone>
            </MudList>
        </MudPaper>
    </ChildContent>
    <ItemRenderer>
        <MudListItem T="string" Disabled="@(context.IsLocked ? true : false)" Icon="@Icons.Custom.FileFormats.FileDocument">
            @context.Name
        </MudListItem>
    </ItemRenderer>
</MudDropContainer>
@code {

    private void ItemUpdated(MudItemDropInfo<FileItem> dropItem)
    {
        dropItem.Item.TransferSlot = dropItem.DropzoneIdentifier;
    }

    private List<FileItem> _items = new()
            {
            new FileItem() { Name = "File1.txt", IsLocked = false, TransferSlot = "Company" },
            new FileItem() { Name = "File2.txt", IsLocked = false, TransferSlot = "External" },
            new FileItem() { Name = "File3.txt", IsLocked = true, TransferSlot = "Company" },
            new FileItem() { Name = "File4.txt", IsLocked = true, TransferSlot = "Company" },
            new FileItem() { Name = "File5.txt", IsLocked = false, TransferSlot = "External" },
            new FileItem() { Name = "File6.txt", IsLocked = true, TransferSlot = "Company" },
        };

    public class FileItem
    {
        public string Name { get; init; }
        public bool IsLocked { get; set; }
        public string TransferSlot { get; set; }
    }
}
Miscellaneous

Kanban

Write unit test
Some docu stuff
Walking the dog
@using Microsoft.AspNetCore.Components
@using System.ComponentModel.DataAnnotations

<MudDropContainer T="KanbanTaskItem" @ref="_dropContainer" Items="@_tasks" ItemsSelector="@((item,column) => item.Status == column)" ItemDropped="TaskUpdated" Class="d-flex flex-row">
    <ChildContent>
        @foreach (var item in _sections)
        {
            <MudPaper Elevation="0" Width="224px" MinHeight="400px" Class="pa-4 ma-4 d-flex flex-column mud-background-gray rounded-lg">
                <MudToolBar Gutters="false">
                    <MudText Typo="Typo.subtitle1"><b>@item.Name</b></MudText>
                    <MudSpacer />
                    <MudMenu Icon="@Icons.Material.Rounded.MoreHoriz" AnchorOrigin="Origin.BottomRight" TransformOrigin="Origin.TopRight" ListClass="pa-2 d-flex flex-column" PopoverClass="mud-elevation-25">
                        <MudButton Size="Size.Small" Color="Color.Error" StartIcon="@Icons.Material.Outlined.Delete" OnClick="@( () => DeleteSection(item))">Delete Section</MudButton>
                        <MudButton Size="Size.Small" Color="Color.Default" StartIcon="@Icons.Material.Rounded.Edit">Rename Section</MudButton>
                    </MudMenu>
                </MudToolBar>
                <MudDropZone T="KanbanTaskItem" Identifier="@item.Name" Class="mud-height-full" />
                @if (item.NewTaskOpen)
                {
                    <MudPaper Elevation="25" Class="pa-2 rounded-lg">
                        <MudTextField @bind-Value="item.NewTaskName" Placeholder="New Task" Underline="false" Margin="Margin.Dense" Class="mx-2 mt-n2"></MudTextField>
                        <MudButton OnClick="@(() => AddTask(item))" Size="Size.Small" Color="Color.Primary" FullWidth="true">Add Task</MudButton>
                    </MudPaper>
                }
                else
                {
                    <MudButton OnClick="@(() => item.NewTaskOpen = !item.NewTaskOpen)" StartIcon="@Icons.Material.Filled.Add" FullWidth="true" Class="rounded-lg py-2">Add Task</MudButton>
                }
            </MudPaper>
        }
        <MudPaper Class="pa-4" Elevation="0" Width="224px">
            @if (_addSectionOpen)
            {
                <MudPaper Elevation="0" Width="224px" Class="pa-4 d-flex flex-column mud-background-gray rounded-lg">
                    <EditForm Model="@newSectionModel" OnValidSubmit="OnValidSectionSubmit">
                        <DataAnnotationsValidator />
                        <MudTextField @bind-Value="newSectionModel.Name" For="@(() => newSectionModel.Name)" Placeholder="New Section" Underline="false"></MudTextField>
                        <MudButton ButtonType="ButtonType.Submit" Size="Size.Small" Color="Color.Primary" FullWidth="true">Add Section</MudButton>
                    </EditForm>
                </MudPaper>
            }
            else
            {
                <MudButton OnClick="OpenAddNewSection" Variant="Variant.Outlined" StartIcon="@Icons.Material.Filled.Add" Color="Color.Primary" Class="rounded-lg py-2" FullWidth="true">Add Section</MudButton>
            }
        </MudPaper>
    </ChildContent>
    <ItemRenderer>
        <MudPaper Elevation="25" Class="pa-4 rounded-lg my-3">@context.Name</MudPaper>
    </ItemRenderer>
</MudDropContainer>
@code {
    private MudDropContainer<KanbanTaskItem> _dropContainer;

    private bool _addSectionOpen;
    /* handling board events */
    private void TaskUpdated(MudItemDropInfo<KanbanTaskItem> info)
    {
        info.Item.Status = info.DropzoneIdentifier;
    }

    /* Setup for board  */
    private List<KanBanSections> _sections = new()
        {
            new KanBanSections("To Do", false, String.Empty),
            new KanBanSections("In Process", false, String.Empty),
            new KanBanSections("Done", false, String.Empty),
        };

    public class KanBanSections
    {
        public string Name { get; init; }
        public bool NewTaskOpen { get; set; }
        public string NewTaskName { get; set; }

        public KanBanSections(string name, bool newTaskOpen, string newTaskName)
        {
            Name = name;
            NewTaskOpen = newTaskOpen;
            NewTaskName = newTaskName;
        }
    }
    public class KanbanTaskItem
    {
        public string Name { get; init; }
        public string Status { get; set; }

        public KanbanTaskItem(string name, string status)
        {
            Name = name;
            Status = status;
        }
    }

    private List<KanbanTaskItem> _tasks = new()
        {
            new KanbanTaskItem("Write unit test", "To Do"),
            new KanbanTaskItem("Some docu stuff", "To Do"),
            new KanbanTaskItem("Walking the dog", "To Do"),
        };

    KanBanNewForm newSectionModel = new KanBanNewForm();

    public class KanBanNewForm
    {
        [Required]
        [StringLength(10, ErrorMessage = "Name length can't be more than 10.")]
        public string Name { get; set; }
    }

    private void OnValidSectionSubmit(EditContext context)
    {
        _sections.Add(new KanBanSections(newSectionModel.Name, false, String.Empty));
        newSectionModel.Name = string.Empty;
        _addSectionOpen = false;
    }

    private void OpenAddNewSection()
    {
        _addSectionOpen = true;
    }

    private void AddTask(KanBanSections section)
    {
        _tasks.Add(new KanbanTaskItem(section.NewTaskName, section.Name));
        section.NewTaskName = string.Empty;
        section.NewTaskOpen = false;
        _dropContainer.Refresh();
    }

    private void DeleteSection(KanBanSections section)
    {
        if (_sections.Count == 1)
        {
            _tasks.Clear();
            _sections.Clear();
        }
        else
        {
            int newIndex = _sections.IndexOf(section) - 1;
            if (newIndex < 0)
            {
                newIndex = 0;
            }

            _sections.Remove(section);

            var tasks = _tasks.Where(x => x.Status == section.Name);
            foreach (var item in tasks)
            {
                item.Status = _sections[newIndex].Name;
            }
        }
    }
}
Mailbox

Demonstrates the usage of the OnlyZone property as well as multiple dropzones connected to the same Identifier.
Try drag items onto the list items, click on them to open the "mailbox".

MailBox

Inbox

Sent

Drafts

Categories

Social

Forums



Your exchange rate and Klarna benefits here


IKEA - Betalningsbekräftelse för din order


Leverans beställd till dig​


You’ve Got Sales! Cotton Bureau On Demand Report for Thursday, February 24, 2022


@using Microsoft.AspNetCore.Components

<MudDropContainer T="DropItem" Items="_items" ItemsSelector="@((item,dropzone) => item.Identifier == dropzone)" ItemDropped="ItemUpdated">
    <ChildContent>
        <MudPaper MinHeight="500px" Class="d-flex flex-1">
            <MudList T="string" Dense="true" @bind-SelectedValue="_selectedFolder">
                <MudListSubheader>MailBox</MudListSubheader>
                <MudDropZone T="DropItem" Identifier="Inbox" OnlyZone="true">
                    <MudListItem Text="Inbox" Value="@("Inbox")" Icon="@Icons.Material.Filled.Inbox"/>
                </MudDropZone>
                <MudDropZone T="DropItem" Identifier="Sent" OnlyZone="true">
                    <MudListItem Text="Sent" Value="@("Sent")" Icon="@Icons.Material.Filled.Send"/>
                </MudDropZone>
                <MudDropZone T="DropItem" Identifier="Drafts" OnlyZone="true">
                    <MudListItem Text="Drafts" Value="@("Drafts")" Icon="@Icons.Material.Filled.Drafts"/>
                </MudDropZone>
                <MudListItem Icon="@Icons.Material.Filled.Label" Text="Categories" Expanded="true">
                    <NestedList>
                        <MudDropZone T="DropItem" Identifier="Social" OnlyZone="true">
                            <MudListItem Dense="true" Text="Social" Value="@("Social")" Icon="@Icons.Material.Filled.Group" Class="pl-8"/>
                        </MudDropZone>
                        <MudDropZone T="DropItem" Identifier="Forums" OnlyZone="true">
                            <MudListItem Dense="true" Text="Forums" Value="@("Forums")" Icon="@Icons.Material.Filled.Forum" Class="pl-8"/>
                        </MudDropZone>
                    </NestedList>
                </MudListItem>
            </MudList>
            <MudDivider Vertical="true" FlexItem="true" />
            <MudList T="string" Dense="true" Class="d-flex flex-column flex-grow-1 py-0">
                <MudToolBar Gutters="false" Dense="true">
                    <MudCheckBox @bind-Value="ToolbarCheckBox"/>
                    <MudIconButton Icon="@Icons.Material.Filled.Refresh"/>
                    <MudIconButton Icon="@Icons.Material.Filled.MoreVert"/>
                    <MudSpacer/>
                    <MudIconButton Icon="@Icons.Material.Filled.ChevronLeft"/>
                    <MudIconButton Icon="@Icons.Material.Filled.ChevronRight"/>
                </MudToolBar>
                <MudDivider/>
                <MudDropZone T="DropItem" Identifier="@_selectedFolder.ToString()" Class="flex-grow-1"/>
            </MudList>
        </MudPaper>
    </ChildContent>
    <ItemRenderer>
        <MudListItem T="string" Text="@context.Name" />
        <MudDivider/>
    </ItemRenderer>
</MudDropContainer>
@code {
    public bool ToolbarCheckBox { get; set; } = false;
    string _selectedFolder = "Inbox";
    
    private void ItemUpdated(MudItemDropInfo<DropItem> dropItem)
    {
        dropItem.Item.Identifier = dropItem.DropzoneIdentifier;
    }
    
    private List<DropItem> _items = new()
    {
        new DropItem(){ Name = "Your exchange rate and Klarna benefits here", Identifier = "Inbox" },
        new DropItem(){ Name = "IKEA - Betalningsbekräftelse för din order", Identifier = "Inbox" },
        new DropItem(){ Name = "Leverans beställd till dig​", Identifier = "Inbox" },
        new DropItem(){ Name = "You’ve Got Sales! Cotton Bureau On Demand Report for Thursday, February 24, 2022", Identifier = "Inbox" },
        new DropItem(){ Name = "Answer: Offer to buy mudblazor", Identifier = "Drafts" },
        new DropItem(){ Name = "Inloggningsvarning för Facebook Messenger for Android", Identifier = "Social" },
        new DropItem(){ Name = "Nya privata meddelanden på SweClockers", Identifier = "Forums" },
    };
    
    public class DropItem
    {
        public string Name { get; init; }
        public string Identifier { get; set; }
    }
}
Chess Board

<MudDropContainer T="DropItem" Items="_items" CanDropClass="mud-border-info" NoDropClass="mud-border-error" CanDrop="@( (item,identifier ) => _items.Count(x => x.Identifier == identifier ) == 0)" ItemsSelector="@((item,dropzone) => item.Identifier == dropzone)" ItemDropped="ItemUpdated" Class="border-2 border-solid mud-border-lines-default">
    <ChildContent>
        @for(int r = 0; r < 8; r++)
        {
            var row = r.ToString();
            <div class="d-flex">
                @for (int c = 0; c < 8; c++)
                {
                    var col = c.ToString();
                    <MudDropZone T="DropItem" Identifier="@($"{row}{col}")" DraggingClass="mud-theme-success" Class="d-flex justify-center align-center border-2 border-solid docs-gray-bg mud-border-lines-default" Style="height:64px;width:64px;"/>
                }
            </div>
        }
    </ChildContent>
    <ItemRenderer>
        <div class="d-flex justify-center align-center flex-grow-1">
            <MudIcon Icon="@context.Icon" Color="@context.Color" Size="Size.Large" />
        </div>
    </ItemRenderer>
</MudDropContainer>
@code {
    private void ItemUpdated(MudItemDropInfo<DropItem> dropItem)
    {
        dropItem.Item.Identifier = dropItem.DropzoneIdentifier;
    }

    private List<DropItem> _items = new()
    {
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessRook, Color = Color.Primary, Identifier = "00" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessKnight, Color = Color.Primary, Identifier = "01" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessBishop, Color = Color.Primary, Identifier = "02" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessQueen, Color = Color.Primary, Identifier = "03" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessKing, Color = Color.Primary, Identifier = "04" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessBishop, Color = Color.Primary, Identifier = "05" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessKnight, Color = Color.Primary, Identifier = "06" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessRook, Color = Color.Primary, Identifier = "07" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Primary, Identifier = "10" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Primary, Identifier = "11" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Primary, Identifier = "12" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Primary, Identifier = "13" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Primary, Identifier = "14" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Primary, Identifier = "15" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Primary, Identifier = "16" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Primary, Identifier = "17" },
        
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Secondary, Identifier = "60" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Secondary, Identifier = "61" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Secondary, Identifier = "62" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Secondary, Identifier = "63" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Secondary, Identifier = "64" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Secondary, Identifier = "65" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Secondary, Identifier = "66" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessPawn, Color = Color.Secondary, Identifier = "67" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessRook, Color = Color.Secondary, Identifier = "70" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessKnight, Color = Color.Secondary, Identifier = "71" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessBishop, Color = Color.Secondary, Identifier = "72" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessQueen, Color = Color.Secondary, Identifier = "73" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessKing, Color = Color.Secondary, Identifier = "74" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessBishop, Color = Color.Secondary, Identifier = "75" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessKnight, Color = Color.Secondary, Identifier = "76" },
        new DropItem(){ Icon = @Icons.Custom.Uncategorized.ChessRook, Color = Color.Secondary, Identifier = "77" },
    };

    public class DropItem
    {
        public string Icon { get; init; }
        public Color Color { get; init; }
        public string Identifier { get; set; }
    }
}
An unhandled error has occurred. Reload 🗙