Skip to main content
All docs
V24.2

DxTreeList.AllowedDropTarget Property

Specifies allowed drag-and-drop targets.

Namespace: DevExpress.Blazor

Assembly: DevExpress.Blazor.v24.2.dll

NuGet Package: DevExpress.Blazor

Declaration

[DefaultValue(TreeListAllowedDropTarget.Internal)]
[Parameter]
public TreeListAllowedDropTarget AllowedDropTarget { get; set; }

Property Value

Type Default Description
TreeListAllowedDropTarget Internal

An enumeration value.

Available values:

Name Description
None

Users cannot reorder rows or drop them onto this TreeList from another component.

Internal

Users can reorder rows within this TreeList.

External

Users can drop rows onto other components.

All

Users can reorder rows within this TreeList and drop them onto other components.

Remarks

Activate the AllowDragRows option to render drag handles for data rows. The AllowedDropTarget property specifies whether these handles allow users to reorder rows or move them to other components. In all modes, except for None, the TreeList component allows users to change its hierarchy. Handle the target component’s ItemsDropped event to update the data source.

In the following example, the Grid allows users to drag rows to external targets. The TreeList accepts rows from the Grid and allows row reordering:

Drag And Drop Between Components

Run Demo: Drag and Drop Rows - Between Components

<DxTreeList @ref="PlannedTasksTreeList"
            Data="PlannedTasks"
            KeyFieldName="Id"
            ParentKeyFieldName="ParentId"
            AllowDragRows="true"
            AllowedDropTarget="TreeListAllowedDropTarget.All"
            ItemsDropped="TreeList_ItemsDropped">
    <Columns>
        <DxTreeListDataColumn FieldName="Name" Caption="Task" />
        <DxTreeListDataColumn FieldName="Priority" Width="100px" CaptionAlignment="TreeListTextAlignment.Center" TextAlignment="TreeListTextAlignment.Center">
            <CellDisplayTemplate>
                @GetEmployeeTaskPriorityIconHtml((EmployeeTask)context.DataItem)
            </CellDisplayTemplate>
        </DxTreeListDataColumn>
    </Columns>
    <DragHintTextTemplate>
        @if(context.DataItems[0] != null) {
            var employeeTask = (EmployeeTask)context.DataItems[0];
            <span class="dxbl-text">@(employeeTask.Name)</span>
            <span class="dxbl-text">@GetEmployeeTaskPriorityIconHtml(employeeTask)</span>
        }
    </DragHintTextTemplate>
</DxTreeList>

<DxGrid Data="PendingTasks"
        TextWrapEnabled="false"
        AllowDragRows="true"
        AllowedDropTarget="GridAllowedDropTarget.External"
        ItemsDropped="Grid_ItemsDropped">
    <Columns>
        <DxGridDataColumn FieldName="Name" Caption="Task" />
        <DxGridDataColumn FieldName="Priority" Width="100px" CaptionAlignment="GridTextAlignment.Center" TextAlignment="GridTextAlignment.Center">
            <CellDisplayTemplate>
                @GetEmployeeTaskPriorityIconHtml((EmployeeTask)context.DataItem)
            </CellDisplayTemplate>
        </DxGridDataColumn>
    </Columns>
    <DragHintTextTemplate>
        @if(context.DataItems.Count == 1) {
            var employeeTask = (EmployeeTask)context.DataItems[0];
            <span class="dxbl-text">@(employeeTask.Name)</span>
            <span class="dxbl-text">@GetEmployeeTaskPriorityIconHtml(employeeTask)</span>
        }
        else {
            <span class="dxbl-text">@(context.DataItems.Count) tasks</span>
        }
    </DragHintTextTemplate>
</DxGrid>

@code {
    ITreeList PlannedTasksTreeList { get; set; }

    ObservableCollection<EmployeeTask> PlannedTasks { get; set; }
    ObservableCollection<EmployeeTask> PendingTasks { get; set; }

    protected override async Task OnInitializedAsync() {
        var employeeTasks = EmployeeTaskDataProvider.GenerateData();
        PlannedTasks = new ObservableCollection<EmployeeTask>(employeeTasks.Where(t => t.Priority <= 0));
        PendingTasks = new ObservableCollection<EmployeeTask>(employeeTasks.Where(t => t.Priority > 0));
    }

    void TreeList_ItemsDropped(TreeListItemsDroppedEventArgs evt) {
        var sourceTasks = GetTaskCollection(evt.SourceComponent);
        RemoveDroppedItems(sourceTasks, evt.DroppedItems);

        var targetTask = (EmployeeTask)evt.TargetItem;
        var index = targetTask != null
            ? PlannedTasks.IndexOf(targetTask) + (evt.DropPosition == TreeListItemDropPosition.After ? 1 : 0)
            : PlannedTasks.Count;

        var droppedTasks = evt.DroppedItems.OfType<EmployeeTask>();
        foreach(var droppedTask in droppedTasks) {
            droppedTask.ParentId = evt.DropPosition == TreeListItemDropPosition.Inside
                ? targetTask.Id
                : targetTask.ParentId;
        }

        InsertDroppedItems(PlannedTasks, evt.DroppedItems, index);
    }

    void Grid_ItemsDropped(GridItemsDroppedEventArgs evt) {
        var sourceTasks = GetTaskCollection(evt.SourceComponent);
        RemoveDroppedItems(sourceTasks, evt.DroppedItems);

        var targetTask = (EmployeeTask)evt.TargetItem;
        var index = targetTask != null
            ? PendingTasks.IndexOf(targetTask) + (evt.DropPosition == GridItemDropPosition.After ? 1 : 0)
            : PendingTasks.Count;

        InsertDroppedItems(PendingTasks, evt.DroppedItems, index);
    }

    void RemoveDroppedItems(IList<EmployeeTask> employeeTasks, IEnumerable<object> droppedItems) {
        foreach(var item in droppedItems)
            employeeTasks.Remove((EmployeeTask)item);
    }

    void InsertDroppedItems(IList<EmployeeTask> employeeTasks, IEnumerable<object> droppedItems, int index) {
        foreach(var item in droppedItems.Reverse())
            employeeTasks.Insert(index, (EmployeeTask)item);
    }

    ObservableCollection<EmployeeTask> GetTaskCollection(object grid) {
        return grid == PlannedTasksTreeList ? PlannedTasks : PendingTasks;
    }

    MarkupString GetEmployeeTaskPriorityIconHtml(EmployeeTask employeeTask) {
        var displayText = TreeListRenderHelper.EmployeeTaskPriorityToString(employeeTask);
        var badgeClass = employeeTask.Priority switch {
            -1 => "bg-success",
            0 => "bg-info",
            1 => "bg-warning",
            _ => throw new ArgumentException()
        };

        string html = string.Format("<span class='badge {0} py-1 px-2' title='{1} priority'>{1}</span>", badgeClass, displayText);
        return new MarkupString(html);
    }
}

Implements

See Also