0

I'm writing a WPF application using MVVM. I'm trying to understand how to use correctly this pattern for what concern validation. For example, my application will manage data about articles. When a user will insert a new row, a first-step validation will mark controls needed, such as article code, quantity, description, vat...

But there is a second step validation executed by the model: for example I should check that code article will be available from vendors. I need to call one (or more) webservice and this operation can be done only by the model. Well, when I get an incorrect result (ie, article not available) I need to return it to the viewmodel and to the view. I'd like not to show only a message, in this case I'd like to adorn code article textbox... or I'd like at least to set focus on textbox!

But... how can I do without "break" mvvm pattern? The model can return the string result, but model don't know anything about viewmodel and viewmodel don't know anything avout view... so... when I get the result from the webservice, I can return string result, I could show a messagebox with string result, but how can I refer to the code article textbox in the view in order to set focus or adorn textbox with a redline?

Obviously, this is only an example, the question is if is possibile to create a "link" (through binding?) between data passed to vm-m and controls in the ui...

davides77
  • 19
  • 5
  • 1
    It's VM job to communicate between view and model. In your case VM can have an event, rised when everything is done (`INotifyPropertyChanged` is good enough). View subscribe to it and perform additional steps (setting focus on certain control if certain property changed). – Sinatr Mar 25 '21 at 08:04
  • Good suggestion... but... how can I do? The user has to fill several fields. Once all values are inserted, the user click on cmdUpdate (binded to UpdateCommand). How can I inform View (adorning xaml and set focus on control) about errors? – davides77 Mar 26 '21 at 08:39

1 Answers1

0

Unfortunately, you did not show any code, so I don't know whether you can apply this to your solution. But here is one approach how you could solve it. Let's assume the user has to input an article id:

<Label Content="Article ID"/>
<TextBox Text="{Binding ArticleID}"/>
<Label Content="{Binding ArticleIdVerification}" Foreground="{Binding ArticleIdForeground}"/>

Your view model could look like this (I neglect that you have to implement INotifyPropertyChanged for brevity):

// Viewmodel
public int ArticleID { get; set; }

public string ArticleIdVerification { get; set; }

public SolidColorBrush ArticleIdForeground { get; set; }

I imagine the user presses a button like "Verify". Then the view model calls a method in your model that verifies the complete input. This model method could look like this. It returns an object containing all information about whether the input was ok:

// Model
public async Task<VerificationResult> Verify(string articleId)
{
    var result = new VerificationResult();
    if(await ArticleIsAvailable(articleId)
    {
       result.ArticleAvailable = true;
    }

    // also verify other stuff, and add this to your result DTO
    return result;
}

Now after your view model called this method, it has to set all the properties:

// Viewmodel
private async void Verify() // this method is called by your ICommand implementation when the button is clicked
{
    var result = await model.Verify(ArticleID);
    if(result.ArticleAvailable)
    {
       ArticleIdVerification  = "OK";
       ArticleIdForeground = Brushes.Green;
    }
    else
    {
       ArticleIdVerification  = "Article not available";
       ArticleIdForeground = Brushes.Red;
    }
}

If you also want to focus the text box with wrong input, you can check this question: MVVM Focus To Textbox

SomeBody
  • 7,515
  • 2
  • 17
  • 33