public async Task NotifyStateChanged(ListUpdateEventArgs e = null) { var overrideDebug = false; if (DnDState.ShowDebugInfo || overrideDebug) { Console.WriteLine("Notifying state has changed"); } if (DnDState.BaseContainer != null) { DnDState.BaseContainer.StateHasChanged(); if (DnDState.BaseContainer.OnStatusUpdated.HasDelegate && e != null) { await DnDState.BaseContainer.OnStatusUpdated.InvokeAsync(e); } } else { StateHasChanged(); if (OnStatusUpdated.HasDelegate && e != null) { await OnStatusUpdated.InvokeAsync(e); } } }
protected async Task HandleMove(DragEventArgs e, int index, bool isDropOnExisting = false, bool dropIntoFirst = false) { var overrideDebug = false; if (DnDState.ShowDebugInfo || overrideDebug) { Console.WriteLine($"Handling Move (Drop)"); } DnDState.ShowDropAtEnd = false; if (DnDState.BaseContainer is null) { Console.Error.WriteLine("Could not retrieve the Base Container information."); return; } index = Math.Max(0, Math.Min(index, List.Count())); var pl = DnDState.Payload; if (string.IsNullOrWhiteSpace(pl.Address)) { // Drop not allowed when there is no payload (the address is empty) Console.Error.WriteLine("Could not retrieve the payload information."); return; } else if (Address.StartsWith(pl.Address) && pl.IsContainer) { // when the payload is a DnDContainer and it is being dropped as a descendant of itself Console.WriteLine("A container cannot be dropped as a child of itself."); return; } if (pl.FromContainer is null || pl.FromIndex < 0) { Console.Error.WriteLine("No item to drop"); return; } if (pl.FromIndex >= pl.FromContainer.List.Count()) { Console.Error.WriteLine("Index of the item being dragged was out of range"); return; } var itemToMove = pl.FromContainer.List[pl.FromIndex]; // If dropping on empty, index out of range possibly var myItemAtIndex = List.Count() > 0 && index < List.Count() ? List[index] : default(TListItem); var childProp = string.IsNullOrWhiteSpace(DnDState.ChildrenPropertyName) ? null : myItemAtIndex?.GetType().GetProperty(DnDState.ChildrenPropertyName); if (pl.FromContainer == this && pl.FromIndex == index) { if (DnDState.ShowDebugInfo || overrideDebug) { Console.WriteLine("The item was dropped onto itself."); } return; } if (DnDState.ShowDebugInfo || overrideDebug) { Console.WriteLine($"itemToMove's address: {pl.Address}"); Console.WriteLine($"itemToMove's container's address: {pl.FromContainer.Address}"); Console.WriteLine($"myItemAtIndex's address: {Address}.{index}"); Console.WriteLine($"this's address: {Address}"); } bool makeNewGroup = // The parameter to allow grouping when dropping on existing items is set to True AND AllowDropToGroup && // The picked up item is being dropped on an existing item AND isDropOnExisting && ( // The item being dropped is a container and the item at the drop target index is not an ancestor of the item being dropped OR (pl.IsContainer && !pl.FromContainer.Address.StartsWith($"{Address}.{index}")) || // The item being dropped is not a container and the item at the drop target index is not a container either (!pl.IsContainer && childProp is null) ); var updateEventArgs = new ListUpdateEventArgs(); // TODO: Fill in the appropriate fields for the updateEventArgs if (makeNewGroup) { if (DnDState.ShowDebugInfo || overrideDebug) { Console.WriteLine($"Making a new group"); } // TODO: Add an argument to determine if this is a drop before/after var newGroup = Activator.CreateInstance <TGroup>(); var children = new List <TListItem>(); children.Add(dropIntoFirst ? itemToMove : myItemAtIndex); children.Add(dropIntoFirst ? myItemAtIndex : itemToMove); childProp = typeof(TGroup).GetProperty(DnDState.ChildrenPropertyName); childProp.SetValue(newGroup, children); List.RemoveAt(index); List.Insert(index, (TListItem)(object)newGroup); } else { List.Insert(index, itemToMove); } var removeIndex = pl.FromContainer == this && !makeNewGroup ? pl.FromIndex + (pl.FromIndex > index && !makeNewGroup ? 1 : 0) : pl.FromIndex; pl.FromContainer.List.RemoveAt(removeIndex); if (DnDState.ShowDebugInfo || overrideDebug) { Console.WriteLine("Removing drop css styles"); } DnDState.DropCssStylesDict.Clear(); DnDState.ShowGroupWithDict.Clear(); // ================> Test for ungroup <================ var containerToCheck = pl.FromContainer; // Test the fromContainer to see if there is <= 1 element and is not the DnDState.BaseContainer and has a Parent container if (containerToCheck.List.Count() <= 1 && containerToCheck != DnDState.BaseContainer && containerToCheck.Parent != null) { if (DnDState.ShowDebugInfo || overrideDebug) { Console.WriteLine($"There {(containerToCheck.List.Count() == 0 ? "are 0 items" : "is 1 item")} in the container, so it should be ungrouped."); } // Determine the index within the parent container's list using the provided container's Address if (!int.TryParse(containerToCheck.Address.Split('.').Last(), out int indexInParentContainer)) { Console.Error.WriteLine("Could not determine the container's index in the parent container."); } else { var parent = containerToCheck.Parent; // Add 1 to the index if the item being moved is being dropped into its previous parent's parent at an index before or equal to its previous parent's index if (this == containerToCheck.Parent && index <= indexInParentContainer) { indexInParentContainer += 1; } CheckForUngroup(containerToCheck, indexInParentContainer); } } await SetPayload(null, -1); await DnDState.BaseContainer.OnStatusUpdated.InvokeAsync(updateEventArgs); if (DnDState.ShowDebugInfo || overrideDebug) { Console.WriteLine($"Drop method complete"); } }