0

I am moving my traditional WPF code-behind app to a MVVM pattern.

I have moved all the button handlers into the ModelView so far.

Now is the turn of some of the logic which performs the functions. Alot of logic has been placed in separate classes as they involve no UI interaction, but the main part of the logic involves running some tasks, and then updating the UI during those stages, including a progress bar fed from background worker updates.

I looked into putting this logic in the Model, but it seems difficult to Update the UI (View) from the model, so was going to place in to the ViewModel.

Is this a bad idea? If so, why?

If this logic should really be placed in the Model, how should I update the UI - these are some of the existing functions in that logic:

//if task is run update UI:
txtCurrentStatus.Text = "Preparing job...";
progressBar.IsIndeterminate = true;
progressBar.Value = 0;
txtPercentage.Text = "0%";

//When progress updates from reading a log, update progress bar
txtPercentage.Text = (percentOutput) + "%";
progressBar.Value = Convert.ToDouble(percentOutput);
Dan Sewell
  • 1,278
  • 4
  • 18
  • 45
  • possible duplicate of http://stackoverflow.com/questions/3520359/how-to-implement-a-progress-bar-using-the-mvvm-pattern – failedprogramming Jan 22 '15 at 22:48
  • Not sure that really answers my questions, its not just about progress bar's. – Dan Sewell Jan 22 '15 at 22:50
  • 1
    The link shows an example of how to use a background worker in a ViewModel to update a progress bar and also shows an example of how the view would be updated using bindings. If you are asking whether it is ok to put logic into a Model, you will get different opinions. Personally I like to keep my Models as simple POCOs. – failedprogramming Jan 22 '15 at 22:57
  • Thanks for your comments. So in your opinion, your program logic goes in ViewModel, and the Model is just the data/get/setters? – Dan Sewell Jan 22 '15 at 23:00
  • For a really simple one-off program, i might do it that way. But usually i have my business logic in service classes and these are fed to the viewmodel using DI. – failedprogramming Jan 22 '15 at 23:02
  • @failedprogramming For what its worth, I usually consider those service classes part of the "Model" layer. Obviously others will disagree :) – BradleyDotNET Jan 22 '15 at 23:17

1 Answers1

1

I would design it like so:

  1. Create a LogReader class. This is effectively part of the Model
  2. Have that class raise an UpdateProgress event
  3. The ViewModel owns a LogReader and listens to that event
  4. In the event callback, it sets a CurrentProgress property on the ViewModel
  5. The View's progress bar has Value="{Binding CurrentProgress}"

Now you have nice seperation of concerns on the LogReader, the view data is in the View Model and the binding is updating the View!

You could certainly keep all the "reading" logic in the view model, but it probably doesn't belong there.

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
  • Hi Bradley, thanks for your answer. I am not quite a C# expert, so struggle on some of these concepts you talk about. Could you expand a bit more what numbers 3, and 4 mean? – Dan Sewell Jan 22 '15 at 22:53
  • @DanSewell I'd be happy to, but could you be a bit more specific on what is confusing about those items? – BradleyDotNET Jan 22 '15 at 23:18
  • So, 3. 'ViewModel owns a logReader'? What do you mean by 'owns'? 4. What do you mean by the event Callback. I would appreciated some pointers, so I can investigate these. – Dan Sewell Jan 23 '15 at 09:09
  • @DanSewell I mean "It owns an instance of ", which basically means it has a variable of that type (non-null of course). For (4), I mean you would write something like `myLogReader.UpdateProgress += HandleProgressUpdate` where `HandleProgressUpdate` would update the `CurrentProgress` property. Does that make sense? – BradleyDotNET Jan 23 '15 at 15:38