Home > Mobile >  Button validation using Textbox with radiobutton WPF c#
Button validation using Textbox with radiobutton WPF c#

Time:11-27

I need to activate a button when a textbox has a specific type/format of text input (FilterString) based on which radiobutton is selected without breaking mvvm pattern.

Basically in the CanExecute method of the RelayCommand instance of the button do something like

public bool CanDoStuff(object param)
        {
            if (rb_1.IsChecked == true) {
                if (string.IsNullOrEmpty(FilterString)) {
                    return false;
                } else
                    return true;
            }
            
            else if (rb_2.IsChecked == true) {
                DateTime searchDate;
                if (DateTime.TryParseExact(FilterString, "dd-MM-yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out searchDate)) {
                    return true;
                } else
                    return false;
            }
            
            else if (rb_3.IsChecked == true) {
                Decimal k;
                if (Decimal.TryParse(FilterString, out k)) {
                    return true;
                } else
                    return false;
            }
            else
                return true;
        }

But I can't access radiobuttons like above in a proper mvvm setup. Is there a different approach for this like using IDataErrorInfo or something and how do I do that?

CodePudding user response:

It's recommended to not interpret button states directly. Rather abstract them to a meaningful state value in context of their purpose.

  1. You can always bind each RadioButton to a dedicated property.
  2. You can use a IValueConverter to convert the button's state to a meaningful value e.g. an enum.
  3. You can, of course, use an ICommand to send the state as a meaningful value e.g. an enum.
  4. Attach a Click event handler

Solution 3) is good because it eliminates the more complex Binding definitions introduced e.g. by 2) which is uses a IValueConverter. It makes the code more readable.
Because grouped RadioButton are mutual exclusive, you basically need to create a ICommand for each RadioButton group.
You can find a common reusable ICommand implementation, the RelayComand, here: Microsoft Docs: Relaying Command Logic.

For example, if you want to use an array of RadioButton to allow the user to pick a currency, you could first implement an enum to create constants that represent a currency. Then use a enum value for each RadioButton and send it using the ButtonBase.CommandParameter property:

Currency.cs

public enum Currency
{
  Default = 0,
  Euro,
  BritishPound,
  JapaneseYen,
  UsDollar
}

MainViewModel.cs

class MainViewModel : INotifyPropertyChagned
{
  public Currency SelectedCurrency { get; private set; }

  // E.g., binding source for a TextBox
  // TODO::Raise INotifyPropertyChanged.PropertyChanged event
  public string Value { get; set; }

  public ICommand SelectCurrencyCommand { get; private set; }
  public ICommand SaveCommand { get; private set; }

  public MainViewModel()
  {
    this.SelectCurrencyCommand = new RelayCommand(ExecuteSelectCurrencyCommand, commandParameter => true);
    this.SaveCommand = new RelayCommand(ExecuteSaveCommand, CanExecuteSaveCommand);
  }

  private void ExecuteSelectCurrencyCommand(object commandParameter)
  {
    this.SelectedCurrency = (Currency)commandParameter;
  }
  
  // Your CanExecute handler, that depends on the state of the radio buttons.
  private bool CanExecuteSaveCommand(object commandParameter)
  {
    decimal decimalValue;
    switch (this.SelectedCurrency)
    {
      case Currency.Euro:
          return Decimal.TryParse(this.Value, out decimalValue);
      case Currency.BritishPound:
          return Decimal.TryParse(this.Value, out decimalValue);
      case Currency.JapaneseYen:
          break;
      case Currency.UsDollar:
          break;
      case Currency.Default:
          break;
      default:
        return false;
    }
  }
}

MainWindow.xaml

<Window>
  <Window.DataContext>
    <MainViewModel />
  </Window.DataContext>

  <StackPanel>
    <RadioButton Command="{Binding SelectCurrencyCommand}"
                 CommandParameter="{x:Static Currency.Euro}" />
    <RadioButton Command="{Binding SelectCurrencyCommand}"
                 CommandParameter="{x:Static Currency.BritishPound}" />
    <RadioButton Command="{Binding SelectCurrencyCommand}"
                 CommandParameter="{x:Static Currency.JapaneseYen}" />

    <TextBox Text="{Binding Value}" />
    <Button Content="Save"
            Command="{Binding SaveCommand}" />
  </StackPanel>
</Window>
  • Related