title: Using Input radio inside Blazor and allowing nullable Enum
body: <p>I work on a Blazor WebAssembly project and I need to display input radio buttons based on Enum.</p>
  
  <p><a href="https://i.stack.imgur.com/9JqA8.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/9JqA8.png" alt="enter image description here"></a></p>
  
  <p>Below is my 'InputRadio.razor'</p>
  
  <pre><code>    @using System.Globalization
      @typeparam TValue
      @inherits InputBase&lt;TValue&gt;
  
      &lt;input @attributes="AdditionalAttributes" type="radio" value="@SelectedValue" checked="@(SelectedValue.Equals(Value))" @onchange="OnChange" /&gt;
  
      @code {
          [Parameter]
          public TValue SelectedValue { get; set; }
          [Parameter]
          public EventCallback&lt;ChangeEventArgs&gt; SelectedValueChanged { get; set; }
  
          private void OnChange(ChangeEventArgs args)
          {
              if (args.Value is "on") {            // &lt;------- only way to test if value is null. Why "on" ??? 
                  CurrentValueAsString = null;
              } else {
                  CurrentValueAsString = args.Value.ToString();
              }
              SelectedValueChanged.InvokeAsync(args);
          }
  
          protected override bool TryParseValueFromString(string value, out TValue result, out string errorMessage)
          {
              var success = BindConverter.TryConvertTo&lt;TValue&gt;(value, CultureInfo.CurrentCulture, out var parsedValue);
              if (success)
              {
                  result = parsedValue;
                  errorMessage = null;
  
                  return true;
              }
              else
              {
                  result = default;
                  errorMessage = $"{FieldIdentifier.FieldName} field isn't valid.";
  
                  return false;
              }
          }
      }
  </code></pre>
  
  <p>Below is my 'Test.razor'</p>
  
  <pre><code>&lt;EditForm Model="CurrentFilterModel"&gt;
  &lt;InputRadio name="difficulty" SelectedValue="null"                        SelectedValueChanged="FilterCourses" @bind-Value="@CurrentFilterModel.DifficultyFilter" /&gt; All
  &lt;InputRadio name="difficulty" SelectedValue="EnumDifficulty.Beginner"     SelectedValueChanged="FilterCourses" @bind-Value="@CurrentFilterModel.DifficultyFilter" /&gt; Beginner
  &lt;InputRadio name="difficulty" SelectedValue="EnumDifficulty.Intermediate" SelectedValueChanged="FilterCourses" @bind-Value="@CurrentFilterModel.DifficultyFilter" /&gt; Intermediate
  &lt;InputRadio name="difficulty" SelectedValue="EnumDifficulty.Advanced"     SelectedValueChanged="FilterCourses" @bind-Value="@CurrentFilterModel.DifficultyFilter" /&gt; Advanced
  &lt;/EditForm&gt;
  </code></pre>
  
  <p>Below the 'Test.cs'</p>
  
  <pre><code>public enum EnumDifficulty
  {
      Beginner,
      Intermediate,
      Advanced
  }
  
  public FilterModel CurrentFilterModel = new FilterModel();
  
  public class FilterModel
  {
     public EnumDifficulty? DifficultyFilter { get; set; }
     ...
  }
  </code></pre>
  
  <p>As you can see, the <code>DifficultyFilter</code> filter used is nullable. When null I know this filter is not set.</p>
  
  <p>This implementation works. Each time a radio button is selected the <code>onchange</code> event is triggered. I had hard time handling the <code>null</code> value. After searching and trying things, I discovered that the test <code>if (args.Value is "on") ...</code> allowed me to manage <code>null</code> values. But why <strong>"on"</strong> ? I have no clue. Please take a look at my code above.</p>
  
  <p>Some of you may suggest me to adjust my <code>Enum</code> like that:</p>
  
  <pre><code>public enum EnumDifficulty
  {
      Any,     // &lt;--- added 
      Beginner,
      Intermediate,
      Advanced
  }
  </code></pre>
  
  <p>But I don't want that because this Enum is also used on my Entity Framework model and this is not a valid choice.</p>
  
  <p>** UPDATE **</p>
  
  <p>Below is the full code for TryParseValueFromString</p>
  
  <pre><code>protected override bool TryParseValueFromString(string value, out TValue result, out string errorMessage)
  {
      if (typeof(TValue) == typeof(string))
      {
          result = (TValue)(object)value;
          errorMessage = null;
          return true;
      }
      else if (typeof(TValue).IsNullableEnum()) // (typeof(TValue).IsEnum) 
      {
          var success = BindConverter.TryConvertTo&lt;TValue&gt;(value, CultureInfo.CurrentCulture, out var parsedValue);
          if (success)
          {
              result = parsedValue;
              errorMessage = null;
              return true;
          }
          else
          {
              result = default;
              errorMessage = $"The {FieldIdentifier.FieldName} field is not valid.";
              return false;
          }
      }
      if (typeof(TValue) == typeof(int))
      {
          if (int.TryParse(value, out var resultInt))
          {
              result = (TValue)(object)resultInt;
              errorMessage = null;
              return true;
          }
          else
          {
              result = default;
              errorMessage = "The chosen value is not a valid number.";
              return false;
          }
      }
  
      throw new InvalidOperationException($"{GetType()} does not support the type '{typeof(TValue)}'.");
  }
  
  public static class CustomStaticFunctions
  {
      public static bool IsNullableEnum(this Type t)
      {
          Type u = Nullable.GetUnderlyingType(t);
          return (u != null) &amp;&amp; u.IsEnum;
      }
  }
  </code></pre>