bool IAddChildViewModel.CanAddChildren(IReadOnlyCollection <object> children, AddChildModifiers modifiers, out string message) { if (children.Any(x => (x is IIsEditableViewModel) && !((IIsEditableViewModel)x).IsEditable)) { message = "Some source items are read-only"; return(false); } if (!Package.IsEditable) { message = "Read-only package"; return(false); } message = $"Add to {Path}"; foreach (var child in children) { var mountPoint = child as MountPointViewModel; var directory = child as DirectoryViewModel; var asset = child as AssetViewModel; if (mountPoint != null) { message = DragDropBehavior.InvalidDropAreaMessage; return(false); } if (directory != null) { if (directory == this) { message = "Can't drop a folder on itself or its children"; return(false); } if (directory.Root.GetType() != Root.GetType()) { message = "Incompatible folder"; return(false); } if (directory.Root is ProjectViewModel && Root != directory.Root) { message = "Can't move source files between projects"; return(false); } if (SubDirectories.Any(x => x.Name == directory.Name)) { message = $"Directory {((this is DirectoryViewModel) ? Path : Name)} already contains a subfolder named {directory.Name}"; return(false); } if (children.OfType <DirectoryViewModel>().Any(x => x != child && string.Compare(x.Name, directory.Name, StringComparison.OrdinalIgnoreCase) == 0)) { message = "Can't move directories with duplicate names"; return(false); } var currentParent = Parent; while (currentParent != null) { if (currentParent == directory) { message = "Can't drop a directory on itself or its children"; return(false); } currentParent = currentParent.Parent; } } else if (asset != null) { if (asset.IsLocked) { message = $"Asset {asset.Url} can't be moved"; return(false); } if (Assets.Any(x => string.Compare(x.Name, asset.Name, StringComparison.OrdinalIgnoreCase) == 0)) { message = $"{(!string.IsNullOrEmpty(Path) ? $"Directory {Path}" : "This directory")} already contains an asset named {asset.Name}"; return(false); } if (children.OfType <AssetViewModel>().Any(x => x != child && string.Compare(x.Name, asset.Name, StringComparison.OrdinalIgnoreCase) == 0)) { message = "Can't move assets with duplicate names"; return(false); } if (asset.Directory.Root.GetType() != Root.GetType()) { message = "Incompatible folder"; return(false); } if (asset.Directory.Root is ProjectViewModel && Root != asset.Directory.Root) { message = "Can't move source files between projects"; return(false); } } else { message = "Only folders can be dropped"; return(false); } } return(true); }