【问题标题】:In Blazor, How to @bind and then fire @onchange in a dynamic model在 Blazor 中,如何在动态模型中 @bind 然后触发 @onchange
【发布时间】:2020-02-15 12:53:55
【问题描述】:

型号:

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 方法中查找相关的 Model 属性并将其设置为 newCheckedBrand。

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

【问题讨论】:

    标签: c# blazor


    【解决方案1】:

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

    剃须刀

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

    @代码

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

    另一种更复杂的方法,如果您想通过 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;
    }
    

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

    【讨论】:

      【解决方案2】:

      另一种选择是在绑定对象中使用 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)" />
      

      【讨论】:

        猜你喜欢
        • 2020-01-27
        • 1970-01-01
        • 2020-05-16
        • 2021-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-11
        相关资源
        最近更新 更多