MVVM: providing a service to work with a specific part of the user interface?

let's say that in my application there is a user interface for presenting a (geographical) map. It is integrated into the application as UserControlit has its own presentation model behind it.

Now suppose that I want to provide other parts of my application with a common service interface for performing common tasks on the map (zooming, panning, etc.) and not worry about the specifics of the user interface. I could give a direct link to the viewmodel, but I'm sure I will violate the principle of separation of problems, not to mention that this will be less verifiable.

So there are a few questions:

  • Does it make sense and is it good practice to implement such services (which act as an intermediate connection with the user interface) in the first place?
  • Since the service runs directly on the map display model, should it be the view model itself that implements the service interface?
  • Is it appropriate for the service interface to provide events (for example, in addition to providing a way to change the map scale, specify an event that also changed the map scale)? Or is it preferable to use some kind of broadcasting mechanism (aggregator) to push such notifications out of service?

Thanks in advance for your help.

+5
source share
4 answers

, ( - , , , ), , , . (MVVM Light Messenger, Prism Caliburn.Micro EventAggregator.) ( ), . invoke (, ) , . . . , ( - ).

. . , , , , , . . (.? , .)

. , .

+1

Messenger MVVM Light. . SO:

fooobar.com/questions/121123/...

+3

EventAggregator - , . , MVVm viewmodel . .

http://msdn.microsoft.com/en-us/magazine/dd943055.aspx#id0420209

. .

+2

, Command, ? , , :

, : , .., , , - . , , , , .

- CompositeCommands ( Prism Application Guidance) . , ( , ).

public class MapNavigationCommands{
  public static CompositeCommand startPanning = new CompositeCommand();
  public static CompositeCommand startZooming = new CompositeCommand();
  public static CompositeCommand setViewbox = new CompositeCommand();
}

, , DI, ( DI , ).

public class ModeControls : UserControl{
  ...
  public void PanButtonSelected(object sender, RoutedEventArgs e){
    MapNavigationCommands.StartPanning.Execute(this); //It doesn't really care who sent it, it just good event practice to specify the event/command source.
  }
}

, XAML:

...
  <Button Command={x:Static yourXmlns:MapNavigationCommands.StartPanning}>Start</Button>
...

:

public class PannableMapViewModel{
  public PannableMapViewModel(){
    MapNavigationCommands.StartPanning.RegisterCommand(new DelegateCommand<object>(StartPanning));
    MapNavigationCommands.SetViewbox.RegisterCommand(new DelegateCommand<Rectangle>(SetViewBox));

  }
  private void StartPanning(object sender){
    this.SetMode(Mode.Pan); //Or as appropriate to your application.  The View is bound to this mode state
  }
  private void SetViewbox(Rectangle newView){
    //Apply appropriate transforms.  The View is bound to your transform state.
  }
}

, , ViewModel, .

+1

All Articles