Blazor MudSelect @bind-SelectedValues 到字典

Blazor MudSelect @bind-SelectedValues to a dictionary

我需要将 @bind-SelectedValues 绑定到 ductionary 中的值。 但它给出了一个 CS1503 参数 2:无法从 'Microsoft.AspNetCore.Components.EventCallback<System.Collections.Generic.List>' 转换为 'Microsoft.AspNetCore.Components.EventCallback'

<MudTable Items="users.UserList" Loading="@_loading" LoadingProgressColor="Color.Info">
    <HeaderContent>
        <MudTh>User</MudTh>
        <MudTh>Applications</MudTh>
        <MudTh>Edit</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="User">@context.FullName</MudTd>
        <MudTd DataLabel="Application">
            <MudSelect Variant="Variant.Outlined" T="int" Label="Applications" MultiSelection="true" 
                @bind-Value="value" 
                @bind-SelectedValues="userAppsDict[context.Id]">
                @foreach(var item in apps.ApplicationList)
                {
                    <MudSelectItem T="int" Value="@item.Id">@item.Name</MudSelectItem>
                }
            </MudSelect>
        </MudTd>
        <MudTd>
            <MudButton Color="Color.Primary" Variant="Variant.Filled">Update</MudButton>
        </MudTd>
    </RowTemplate>
</MudTable>

@code{
    [Inject]
    private IApplicationService service{ get; set; }
    private int value { get; set; }
    private IEnumerable<int> options { get; set; } = new HashSet<int>();
    private bool _loading = false;
    private Dictionary<int, List<int>> userAppsDict { get; set; } = new Dictionary<int, List<int>>();

    UserHasApplicationsReadViewModel userApps = new UserHasApplicationsReadViewModel();
    UserReadViewModel users = new UserReadViewModel();
    ApplicationReadViewModel apps = new ApplicationReadViewModel();

    protected override async Task OnInitializedAsync()
    {
        _loading = true;
        userApps = await service.GetUserHasApplications();
        users = await service.GetUsers();
        apps = await service.GetApplicationsAsync();

        foreach(var user in users.UserList)
        {
            List<int> appIdList = new List<int>();
            var appsbyUid = await service.GetApplicationByUserId(user.Id);
            foreach (var item in appsbyUid.ApplicationList)
            {
                appIdList.Add(item.Id);
            }
            userAppsDict.Add(user.Id, appIdList);
        }
        Console.WriteLine(JsonSerializer.Serialize(userAppsDict));
        _loading = false;
    }
}

I need to bind @bind-SelectedValues to the values in a ductionary

需要是一个主观术语.. MB 想要将字符串的哈希集放入 SelectedValues 绑定中,所以阻力最小的路径是让它,然后 back-translate 那,也许是这样的:

@inject ISnackbar Snackbar

<MudTable Items="users" Loading="@_loading" LoadingProgressColor="Color.Info">
    <HeaderContent>
        <MudTh>User</MudTh>
        <MudTh>Applications</MudTh>
        <MudTh>Edit</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="User">@context.FullName</MudTd>
        <MudTd DataLabel="Application">
            <MudSelect Variant="Variant.Outlined" Label="Applications" MultiSelection="true" 
                @bind-SelectedValues="context.Apps">
                @foreach(var item in apps)
                {
                    <MudSelectItem Value="@item.Name">@item.Name</MudSelectItem>
                }
            </MudSelect>
        </MudTd>
        <MudTd>
            <MudButton Color="Color.Primary" Variant="Variant.Filled"  OnClick="@(() => UpdateUser(context))">Update</MudButton>
        </MudTd>
    </RowTemplate>
</MudTable>


@code{
    private bool _loading = false;

    List<User> users = new List<User>();
    List<App> apps = new List<App>();

    protected override async Task OnInitializedAsync()
    {
        _loading = true;
        apps = new List<App>{ 
            new(){
                Id = 1,
                Name = "FirstApp"
            },
            new(){
                Id = 2,
                Name = "SecondApp"
            }
        };
        users = new List<User>{
            new User{ 
                Id = 1,
                FullName = "Firstappuser",
                Apps = new HashSet<string>{ apps.First().Name }
            },
            new User{ 
                Id = 2,
                FullName = "Secondappuser",
                Apps = new HashSet<string>{ apps.Last().Name }
            },
            
        };
        _loading = false;
    }

    class User{
      public int Id {get;set;}
      public string FullName {get;set;}
      public IEnumerable<string> Apps {get;set;}
    }
    class App{
      public int Id {get;set;}
      public string Name {get;set;}
    }

    void UpdateUser(User u){
      var newApps = u.Apps.Select(a => apps.First(app => app.Name == a)).ToArray();
      Snackbar.Add("Updating user " + u.FullName + " to have apps " + string.Join(",", newApps.Select(app => app.Id.ToString())));
    }
}

我不得不发明 类 来涵盖用例,但它也强调了你 不必 必须使用 类 你作为模型给出;随意做任何必要的事情来简单地建模。这里每个用户都有一个 IEnumerable<string> 来跟踪用户拥有的应用程序,而不是 Dictionary<userid, List<app ids>> 所以 1:M User:App 关联是 在每个用户内部 .. 单击更新按钮时,用户被传递给处理程序,并且有一个过程将应用程序名称反转回应用程序(newApps 行,然后我将他们的 ID 字符串连接到小吃栏中以证明这一点能够将应用程序名称反转为应用程序,并改为获取 ID

https://try.mudblazor.com/snippet/cEQGkmwGgvbuyXTd