The FileManager TreeView does not expand automatically in some scenarios, which can cause the TreeView and ListView UI to be inconsistent:
Here is a test page and steps to reproduce.
<p>/folder-16/folder-17</p>
<TelerikTextBox @bind-Value="@DirectoryPath" Width="max-content" OnChange="@(() => FileManagerRef!.Rebind())" />
<TelerikFileManager @ref="@FileManagerRef"
Data="@FileManagerData"
@bind-Path="@DirectoryPath"
View="@FileManagerViewType.ListView"
EnableLoaderContainer="false"
OnDownload="@OnDownloadHandler"
NameField="@(nameof(FlatFileEntry.Name))"
SizeField="@(nameof(FlatFileEntry.Size))"
PathField="@(nameof(FlatFileEntry.Path))"
ExtensionField="@(nameof(FlatFileEntry.Extension))"
IsDirectoryField="@(nameof(FlatFileEntry.IsDirectory))"
HasDirectoriesField="@(nameof(FlatFileEntry.HasDirectories))"
IdField="@(nameof(FlatFileEntry.Id))"
ParentIdField="@(nameof(FlatFileEntry.ParentId))"
DateCreatedField="@(nameof(FlatFileEntry.DateCreated))"
DateCreatedUtcField="@(nameof(FlatFileEntry.DateCreatedUtc))"
DateModifiedField="@(nameof(FlatFileEntry.DateModified))"
DateModifiedUtcField="@(nameof(FlatFileEntry.DateModifiedUtc))"
Class="my-filemanager">
</TelerikFileManager>
@code {
private TelerikFileManager<FlatFileEntry>? FileManagerRef { get; set; }
private List<FlatFileEntry>? FileManagerData { get; set; }
public string? DirectoryPath { get; set; } = string.Empty;
private readonly string RootPath = string.Empty;
public async Task<bool> OnDownloadHandler(FileManagerDownloadEventArgs args)
{
await Task.Delay(1);
return true;
}
private int FolderLevelCount { get; set; } = 5;
private int FilesInFolderCount { get; set; } = 5;
private int FoldersInFolderCount { get; set; } = 2;
private int FolderNameCounter { get; set; }
private readonly List<string> FileExtensions = new() {
".txt", ".pdf", ".docx", ".xlsx", ".png", ".jpg", ".gif", ".zip", ".css", ".html", ".mp3", ".mpg"
};
protected override async Task OnInitializedAsync()
{
await Task.CompletedTask;
DirectoryPath = RootPath;
FileManagerData = LoadFlatDataAsync();
await base.OnInitializedAsync();
}
private List<FlatFileEntry> LoadFlatDataAsync()
{
List<FlatFileEntry> data = new List<FlatFileEntry>();
string rootDataPath = string.IsNullOrEmpty(RootPath) ? "/" : RootPath;
PopulateChildren(data, null, rootDataPath, 1);
return data;
}
private void PopulateChildren(List<FlatFileEntry> data, string? parentId, string parentPath, int level)
{
var rnd = Random.Shared;
for (int i = 1; i <= FilesInFolderCount; i++)
{
string itemId = Guid.NewGuid().ToString();
string itemExtension = FileExtensions[rnd.Next(0, FileExtensions.Count)];
string itemName = $"{itemExtension.Substring(1)}-file-{(FolderNameCounter != default ? string.Concat(FolderNameCounter, "-") : string.Empty)}{i}";
string itemPath = Path.Combine(parentPath, string.Concat(itemName, itemExtension));
data.Add(new FlatFileEntry()
{
Id = itemId,
ParentId = parentId,
Name = itemName,
IsDirectory = false,
HasDirectories = false,
DateCreated = DateTime.Now,
DateCreatedUtc = DateTime.Now.ToUniversalTime(),
DateModified = DateTime.Now,
DateModifiedUtc = DateTime.Now.ToUniversalTime(),
Path = itemPath,
Extension = itemExtension,
Size = rnd.Next(1_000, 3_000_000)
});
}
if (level < FolderLevelCount)
{
for (int i = 1; i <= FoldersInFolderCount; i++)
{
var itemId = Guid.NewGuid().ToString();
var itemName = $"folder-{++FolderNameCounter}";
var itemPath = Path.Combine(parentPath, itemName);
data.Add(new FlatFileEntry()
{
Id = itemId,
ParentId = parentId,
Name = itemName,
IsDirectory = true,
HasDirectories = level < FolderLevelCount - 1,
DateCreated = DateTime.Now,
DateCreatedUtc = DateTime.Now.ToUniversalTime(),
DateModified = DateTime.Now,
DateModifiedUtc = DateTime.Now.ToUniversalTime(),
Path = itemPath,
Size = rnd.Next(100_000, 10_000_000)
});
PopulateChildren(data, itemId, itemPath, level + 1);
}
}
}
public class FlatFileEntry : FileEntry
{
public string Id { get; set; } = Guid.NewGuid().ToString();
public string ParentId { get; set; }
}
public class FileEntry
{
public string Name { get; set; }
public long Size { get; set; }
public string Path { get; set; }
public string Extension { get; set; }
public bool IsDirectory { get; set; }
public bool HasDirectories { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateCreatedUtc { get; set; }
public DateTime DateModified { get; set; }
public DateTime DateModifiedUtc { get; set; }
}
}
Would like to be able to change / recall State of expanded / collapsed items in FileManager, similar to how we can with the Grid component using Groups.
We would also like the ability to set the Splitter collapsed on initial load to hide the tree.
On refreshing data from the database, the entire File Manager reverts to all items collapsed, which will be annoying for end users.
State management could also deal with the default view (Details vs Icons) as requested elsewhere for this component.
The ability to choose which options to appear in the ContextMenu.
=====
TELERIK EDIT: In the meantime, here is how to hide context menu items with CSS:
/* Hide the Rename item in the FileManager context menu */
.k-context-menu:has(.k-svg-i-download) .k-menu-item:nth-of-type(1) {
display: none;
}
/* Hide the Delete item in the FileManager context menu */
.k-context-menu:has(.k-svg-i-download) .k-menu-item:nth-of-type(3) {
display: none;
}Here is a complete example: https://blazorrepl.telerik.com/cpPkuBEq408A36p010
I want to use the built-in FileManagerToolBarSortTool but I want to remove the "Date Modified" option from the "Sort BY" menu.
===
ADMIN EDIT
===
For the time being, a possible option is to create a custom tool for sorting. You can use the SplitButton component to simulate the built-in UI. Upon selecting option from the dropdown, you may sort your data collection based on the selected custom sort option. Call the Rebind method to refresh the data after updating it.
Greetings.
I was using the FileManager recently and wanted to make sure the user could only select a single file. I was expecting a parameter to configure that but I didn't find any. I was able to bypass the issue by acting on the value reported by the component but I found it a bit inconvenient.
I think it might be interesting if we could:
What do you think?
Currently, only the "Download" option has an icon and this is not consistent:
The need to right-click a file to be able to download it is a bit less intuitive.
I would like to be able to download a file by double-clicking it, or, more generic, to be able to add a double click handler so I can decide what to do with it.
For true load on demand, the OnRead event should be triggered for: