I'm trying to data bind some user-selected files in the Blazor InputFile
component, specifically the AssociatedFiles
property of each ToDoItem
. This is not working because the AssociatedFiles
is always null
.
This is my razor component:
@page "/todo"
@using BlazorPlayground.Data
<h3>Todo List</h3>
Total items: @todos.Count()
<br />
Done: @todos.Count(x => x.IsDone) out of @todos.Count()
<br />
Not Done: @todos.Count(x => !x.IsDone) out of @todos.Count()
<br />
<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone" />
<input @bind="todo.Title" />
<input type="datetime-local" @bind="todo.DateAdded" />
<InputFile OnChange="@OnFileSelected" @bind-value="todo.AssociatedFiles" multiple />
</li>
}
</ul>
<input placeholder="Write something to do..." @bind="newTodo" />
<button @onclick="AddTodo">Add Todo Item</button>
@code {
private IList<TodoItem> todos = new List<TodoItem>();
private string newTodo;
private void AddTodo()
{
if (!String.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem(newTodo));
newTodo = "";
}
}
private void OnFileSelected(InputFileChangeEventArgs e)
{
}
}
This is my ToDoItem
class:
namespace BlazorPlayground.Data
{
public class TodoItem
{
public string Title { get; set; }
public bool IsDone { get; set; }
public DateTime DateAdded { get; set; }
public IReadOnlyList<IBrowserFile> AssociatedFiles {get; set;}
public TodoItem(string title)
{
this.Title = title;
this.IsDone = false;
this.DateAdded = DateTime.Now;
}
}
}
By the way, you may have noticed that this is an extension of the Blazor todo list app tutorial .
Never done that before, but I guess this should work...
<InputFile OnChange="@((InputFileChangeEventArgs args) => OnFileSelected(args, todo))" multiple />
Get the selected files, and add them to the AssociatedFiles
field of the current TodoItem
object
private void OnFileSelected (InputFileChangeEventArgs e, TodoItem todo)
{
var selectedFiles = e.GetMultipleFiles();
todo.AssociatedFiles = selectedFiles;
this.StateHasChanged();
}
I'm quite new to web development and I didn't know that you could pass anonymous functions to the OnChange attribute there.
It's a lambda expression...
I thought you were supposed to enter the name of a method there.
The InputFile component exposes an EventCallback property like this:
[Parameter] public EventCallback OnChange { get; set; }
Usually you assign the name of your event handler to the property attribute like the following:
<InputFile OnChange="OnInputFileChange" multiple />
And use it like this:
private void OnInputFileChange (InputFileChangeEventArgs e)
{
selectedFiles = e.GetMultipleFiles();
message = $"{selectedFiles.Count} file(s) selected";
this.StateHasChanged();
}
You may use a lambda expression as the value of the OnChange attribute, as done below... but in that case it's your responsibility to pass the InputFileChangeEventArgs
argument to your event handler ( OnInputFileChange
)
<InputFile OnChange="@((InputFileChangeEventArgs args) =>
OnInputFileChange(args))" multiple />
This of course is over skill and really superfluous. But if you want to pass a second parameter to your event handler, as in the case of your question, this approach is the correct one.
I think your problem is related with foreach. Cuz when you use foreach it added additional prefix, that can be problem why your model can't binded
So I recommend your replace foreach on for and checkout again
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.