Complex TextBox Input Validation WPF MVVM

StashyCode 61 Reputation points
2021-11-23T15:40:56.017+00:00

I have a ListBox in my main window and a button for adding a property to my ListBox:

<ListBox
    //other stuff
    ItemsSource="{Binding ViewModels, UpdateSourceTrigger=PropertyChanged}"
    SelectedItem="{Binding SelectedThing, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />

<Button Click="OnAddClick" Content="Add"/>

MainWindow.xaml.cs:

private void OnAddClick(object sender, EventArgs e)
{
      var addDialogBox = new AddView(((MainViewModel)DataContext).AddViewModel);
      addDialogBox.ShowDialog();
}

The button opens a new window for the adding of the element. This view has a TextBox for entering one of the properties: a string, composed of integers, separated by a comma - for example 1-5, 15, 20 => this will be deserialized into a List<int> in the MainViewModel. The integers are not supposed to exceed a value in the MainViewModel - MaxPossibleValue.

I need to create a validation in the newly opened window, making sure that correct input has been entered.

AddWindow.xaml:

<DockPanel LastChildFill="True">
        <StackPanel
            Height="40"
            HorizontalAlignment="Right"
            DockPanel.Dock="Bottom"
            Orientation="Horizontal">
            <Button
                Command="{Binding SaveCommand}"
                Content="Submit"
                IsDefault="True" />
        </StackPanel>
            <TextBox
                Name="PropertyTextBox"
                Text="{Binding SomeProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DockPanel>

AddWindow.xaml.cs:

public AddWindow()
{
     InitializeComponent();
}

public AddWindow(AddViewModel context) : this()
{
     DataContext = context;
     context.Save += Save;
}

private void Save(object sender, EventArgs e)
{
     Close();
}

AddViewModel.cs:

public string SomeProperty { get; set; }

public event EventHandler Save;

public RelayCommand<object> SaveCommand { get; set; }

public AddViewModel()
{
      SaveCommand = new RelayCommand<object>(x => Save(this, new EventArgs()));
}

MainViewModel.cs:

public MainViewModel(AddViewModel addViewModel)
{
      AddViewModel = addViewModel ?? throw new ArgumentNullException(nameof(addViewModel));
      AddViewModel.Save += ViewModelOnAddSave;
}

private void ViewModelOnAddSave(object sender, EventArgs eventArgs)
{
       //this will throw an exception and break if the input is not correct
       var groupFromSomeProperty = AddViewModel.SomeProperty.Split(new string[] { ", " }, StringSplitOptions.None)
                                .Select(i => i.Split('-').Select(s => int.Parse(s)).ToArray())
                                .SelectMany(i => i.Length == 1 ? i : Enumerable.Range(i[0], i[1] - i[0] + 1)).ToList();

       ViewModels.Add(new SomeNotImportantType
       {
             ListOfIntegers = groupFromSomeProperty 
       });
}

AddViewModel is injected into MainViewModel using dependency injection and the adding to the ListBox's ItemsSource is performed there.

I want to validate it after clicking on Submit button, but the Window should remain open until a successful action has been made (the user corrects himself or the user closes the entire window on his own).

How can I achieve that?

Developer technologies Windows Presentation Foundation
Developer technologies XAML
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.