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

时间:2019-10-18 13:54:27

标签: 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; }
}

剃刀:

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

@代码:

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);
}

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

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

2 个答案:

答案 0 :(得分:1)

另一种选择是在绑定对象中使用INotifyPropertyChanged接口。

public class RowToApprove : INotifyPropertyChanged
{
    private bool _approved;
  
    public string AddressLine { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
  
    public bool Approved
    {
        get => _approved;
        set
        {
            if (value == _approved) return;
            _approved = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

,然后在您的页面中,注册到ItemOnPropertyChanged事件。

  item.PropertyChanged += ItemOnPropertyChanged;

在那做你的工作

private void ItemOnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    //Do something
}

您的商品可能如下所示:

<input type="checkbox" @bind-value="@(context.Approved)" />

答案 1 :(得分:0)

由于没有办法使用@bind和@onchange,因此您只能在代码中进行更改。最简单的方法是使用lambda捕获item

剃刀

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

@code

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);
}

另一种更复杂的方式,如果您想将UI与WPF一起使用,则可能会有所帮助,例如将事件级联放置在模型本身中。

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;
}
如您所见,

CheckBoxListWithTitle将处理必需事件的传播。在Razor中,您仅订阅CheckBoxListWithTitle.ModelChanged