未将更改的值发送到Blazor组件';父母

未将更改的值发送到Blazor组件';父母,blazor,Blazor,注意为了更清楚地说明我在做什么,我添加了一个。这显示了FormRowText组件和formrowdropdowneum组件的使用,前者工作正常,后者不工作。如果有人能够下载这个项目,看看我做错了什么,那就太好了 我正在尝试编写一系列可重用的Blazor组件,用于布局表单控件。这些方法中的大多数都有效(例如用于),但有一种给我带来了问题。其思想是将enum的类型作为参数传递,组件将基于enum值创建 我制作了一个通用组件,如下所示(.razor first) 这将正确显示,并根据型号的频率设置相应

注意为了更清楚地说明我在做什么,我添加了一个。这显示了
FormRowText
组件和
formrowdropdowneum
组件的使用,前者工作正常,后者不工作。如果有人能够下载这个项目,看看我做错了什么,那就太好了

我正在尝试编写一系列可重用的Blazor组件,用于布局表单控件。这些方法中的大多数都有效(例如用于
),但有一种给我带来了问题。其思想是将
enum
的类型作为参数传递,组件将基于
enum
值创建

我制作了一个通用组件,如下所示(.razor first)

这将正确显示
,并根据型号的
频率设置相应的

中更改选择时,将调用
OnChanged
方法,并将正确的值用作事件回调的参数。但是,保存此组件的Blazor页面(即上面显示的带有
标记的页面)从未看到新值,并且那里的模型也没有更新。我在模型的setter上设置了一个断点,但它从未被击中

正如我所说,我为其他输入类型提供了类似的组件,它们工作得很好,所以我不确定我在这里做错了什么

有人能帮忙吗?谢谢

更新在enet回复之后,我尝试在代码中添加一个私有变量,并在输入值更改时修改它

    private int _value;
    protected override void OnParametersSet() =>
      _value = Value;

    private async Task OnChanged(ChangeEventArgs cea) {
      int val = (int)Enum.Parse(typeof(T), cea.Value?.ToString() ?? "0");
      _value = val;
      await ValueChanged.InvokeAsync(val);
    }
我将Razor标记更改为使用
\u value
而不是
value
,如下所示

if ((int)Enum.Parse(typeof(T), v.ToString()) == _value) {
然而,这样做的结果是,当我更改下拉列表中的选择时,它立即恢复为以前的值,并且父页面从未看到新值。

如下所示

FormRowDropdownEnum.razor

@typeparam TEnum

<div class="form-group row">
  <label for="@PropertyName" class="col-lg-2 col-form-label">@(Caption ?? PropertyName)</label>
  <div class="col-lg-10 input-group">
    <div class="input-group-prepend">
      <span class="input-group-text">
        <i class="far fa-@Icon"></i>
      </span>
    </div>
    <select class="form-control" name="@PropertyName" id="@PropertyName" @bind="Value">
        @foreach (var enumValue in EnumValues)
        {
            @ChildContent(enumValue)
        }
    </select>
  </div>
</div>
...
      <FormRowDropdownEnum PropertyName="@nameof(Customer.Frequency)" @bind-Value="_customer.Frequency" Icon="wave-sine" Context="freq">
          <option value="@freq">@freq</option>
      </FormRowDropdownEnum>
...
@code {

  readonly Customer _customer = new Customer {
    Name = "Jim",
    Email = "jim@spriggs.org",
    Frequency = Frequency.Monthly
  };

  private string _msg = "";

  private void OnSubmit() =>
    _msg = $"Customer name: {_customer.Name}, email: {_customer.Email}, frequency: {_customer.Frequency}";

}
Index.razor

@typeparam TEnum

<div class="form-group row">
  <label for="@PropertyName" class="col-lg-2 col-form-label">@(Caption ?? PropertyName)</label>
  <div class="col-lg-10 input-group">
    <div class="input-group-prepend">
      <span class="input-group-text">
        <i class="far fa-@Icon"></i>
      </span>
    </div>
    <select class="form-control" name="@PropertyName" id="@PropertyName" @bind="Value">
        @foreach (var enumValue in EnumValues)
        {
            @ChildContent(enumValue)
        }
    </select>
  </div>
</div>
...
      <FormRowDropdownEnum PropertyName="@nameof(Customer.Frequency)" @bind-Value="_customer.Frequency" Icon="wave-sine" Context="freq">
          <option value="@freq">@freq</option>
      </FormRowDropdownEnum>
...
@code {

  readonly Customer _customer = new Customer {
    Name = "Jim",
    Email = "jim@spriggs.org",
    Frequency = Frequency.Monthly
  };

  private string _msg = "";

  private void OnSubmit() =>
    _msg = $"Customer name: {_customer.Name}, email: {_customer.Email}, frequency: {_customer.Frequency}";

}
。。。
@频率
...
@代码{
只读客户_客户=新客户{
Name=“吉姆”,
电子邮件=”jim@spriggs.org",
频率=频率。每月
};
私有字符串_msg=“”;
私有void OnSubmit()=>
_msg=$“客户名称:{{u Customer.name},电子邮件:{{u Customer.email},频率:{u Customer.frequency}”;
}

谢谢你的回复,但我无法让它工作。我收到一个编译器错误“组件'InputEnum'的子上下文元素'ChildContent'使用了与包含组件'EditForm'的子内容元素'ChildContent'相同的参数名('context')。请指定参数名,如:'以解决歧义'”。对不起,如果我是哑巴,但我对Blazor还是相当陌生的,不知道这意味着什么。另外,我对你的用法感到困惑。如果你看看我最初的问题,你会看到我对其他组件的使用方式。我希望这个能用同样的方式工作。再次感谢您在其他上下文中使用它,您需要命名其中一个。感谢更新的项目。我明白了,但我不懂你的代码。在Index.razor中的何处告诉组件枚举类型?在我的代码中,我有
T
参数,但您已经删除了它。此外,您的代码将枚举值作为字符串返回,例如
OneOff
,而我的代码将其作为
int
返回。
int
更易于使用,因为您可以轻松地将其强制转换为枚举,并且数据库将该值存储为
int
。如果父页面获取字符串,则必须将其转换为枚举值。这有什么办法吗?再次感谢。#@avrohmyisroel其他属性允许属性飞溅。。。使您的组件更加灵活。
public partial class FormRowDropdownEnum<TEnum>
{
    private TEnum _value;
    [Parameter] public string PropertyName { get; set; }
    [Parameter] public string Caption { get; set; }
    [Parameter] public string Icon { get; set; }
    [Parameter]
    public TEnum Value
    {
        get => _value;
        set
        {
            if (_value.Equals(value)) return;
            _value = value;
            if (ValueChanged.HasDelegate)
            {
                ValueChanged.InvokeAsync(Value);
            }
        }
    }
    [Parameter(CaptureUnmatchedValues = true)]
    public Dictionary<string, object> AdditionalAttributes { get; set; }
    [Parameter] public RenderFragment<TEnum> ChildContent { get; set; }
    [Parameter] public EventCallback<TEnum> ValueChanged { get; set; }
    IEnumerable<TEnum> EnumValues => Enum.GetValues(typeof(TEnum)).Cast<TEnum>();
    protected override void OnInitialized()
    {
        if (Value is not Enum) throw new ArgumentException("Value must be of type Enum");
    }
}

...
      <FormRowDropdownEnum PropertyName="@nameof(Customer.Frequency)" @bind-Value="_customer.Frequency" Icon="wave-sine" Context="freq">
          <option value="@freq">@freq</option>
      </FormRowDropdownEnum>
...
@code {

  readonly Customer _customer = new Customer {
    Name = "Jim",
    Email = "jim@spriggs.org",
    Frequency = Frequency.Monthly
  };

  private string _msg = "";

  private void OnSubmit() =>
    _msg = $"Customer name: {_customer.Name}, email: {_customer.Email}, frequency: {_customer.Frequency}";

}