在 Blazor 中,如何在动态模型中 @bind 然后触发 @onchange

mz1*_*378 5 c# blazor

模型:

public class FiltersModel
{      
    public CheckBoxListWithTitle Brand { get; set; }
}

public class CheckBoxListWithTitle
{        
    public List<FilterCheckBox> CheckBoxes { get; set; }
}

public class FilterCheckBox
{        
    public string Value { get; set; }
    public bool Checked { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

剃刀:

@foreach (var item in Model.Brand.CheckBoxes)
{
<label>
    @item.Value
    <input type="checkbox" @onchange="@FilterChangedBrand" />  
</label>
}
Run Code Online (Sandbox Code Playgroud)

@代码:

public FiltersModel Model { get; set; } // Initialized in OnParametersSet

private void FilterChangedBrand(UIChangeEventArgs e)
{
    string newCheckedBrand = e.Value.ToString();
    // Now How to Find and Set the relevant Model property to newCheckedBrand
    FiltersChanged?.Invoke(Model);
}
Run Code Online (Sandbox Code Playgroud)

如何在 FilterChangedBrand 方法中查找相关模型属性并将其设置为 newCheckedBrand。

或者在复选框标记中使用 @bind="@item.Checked" ,然后在其中一个复选框的选中状态发生更改时引发事件?

cod*_*ion 6

由于无法使用 @bind 和 @onchange,因此您必须纯粹在代码中进行更改。最简单的方法是使用 lambda 来捕获item

剃刀

@foreach (var item in Model.Brand.CheckBoxes)
{
    <label>
        @item.Value
        <input type="checkbox" @onchange="(e) => FilterChangedBrand(item, e)" />
    </label>
}
Run Code Online (Sandbox Code Playgroud)

@代码

public FiltersModel Model { get; set; } // Initialized in OnParametersSet

public event Action<FiltersModel> FiltersChanged;

private void FilterChangedBrand(FilterCheckBox item, ChangeEventArgs e)
{
    // here you do work of @bind
    item.Checked = !item.Checked;
    string newCheckedBrand = e.Value.ToString();
    // Now How to Find and Set the relevant Model property to newCheckedBrand
    FiltersChanged?.Invoke(Model);
}
Run Code Online (Sandbox Code Playgroud)

如果您想在 WPF 中重用 UI,另一种更复杂的方法可能会有所帮助,即将该事件级联放置在模型本身中。

public class CheckBoxListWithTitle
{
    private List<FilterCheckBox> items = new List<FilterCheckBox>();
    public IReadOnlyList<FilterCheckBox> CheckBoxes => items.AsReadOnly();

    public event EventHandler ModelChanged;

    public void Add(FilterCheckBox item)
    {
        item.CheckedChanged += this.Item_CheckedChanged;
        this.items.Add(item);
    }

    private void Item_CheckedChanged(object sender, EventArgs e)
    {
        ModelChanged.Invoke(this, EventArgs.Empty);
    }
}

public class FilterCheckBox
{
    public string Value { get; set; }
    public bool Checked { get; set; }

    public event EventHandler CheckedChanged;
}
Run Code Online (Sandbox Code Playgroud)

如您所见,CheckBoxListWithTitle它将处理所需事件的传播。在 Razor 中,您只订阅CheckBoxListWithTitle.ModelChanged