0
votes

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...

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
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

1 Answers

0
votes

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