Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I avoid command clutter in the ViewModel?

I am building an application that uses quite a few commands, and they are cluttering up my viewmodel. MVVM is new to me, so sorry if this question is a bit stupid. Is there a way to reduce the clutter? For example here you can see the a part of the clutter..

    private void InitializeCommands()
    {
        LogoutCommand = new RelayCommand(Logout);
        OpenCommand = new RelayCommand(SetImage);
        SaveCommand = new RelayCommand(SaveImage, SaveImageCanExecute);
        UploadToFlickrCommand = new RelayCommand(UploadToFlickr);
        CropCommand = new RelayCommand(SetCropMouseEvents);
        RemoveRedEyeCommand = new RelayCommand(SetRemoveRedEyeMouseEvents);
        TextInputCropCommand = new RelayCommand(CropFromText);
        ReloadImageCommand = new RelayCommand(ReloadImage);
        FlipYCommand = new RelayCommand(FlipY);
        Rotate90RCommand = new RelayCommand(Rotate90R);
        FlipXCommand = new RelayCommand(FlipX);
        ToGrayscaleCommand = new RelayCommand(ToGrayscale);
        ToSepiaCommand = new RelayCommand(ToSepia);
        WindowClosingCommand = new RelayCommand(WindowClosing);
        EffectsViewCommand = new RelayCommand(() => CurrentToolView = new EffectsView());
        AddTextCommand = new RelayCommand(() => CurrentToolView = new AddTextView());
        ResizeCommand = new RelayCommand(() => CurrentToolView = new ResizeView());
        CropViewCommand = new RelayCommand(() => CurrentToolView = new CropView());
        RedEyeCommand = new RelayCommand(() => CurrentToolView = new RedEyeView());
        RotateViewCommand = new RelayCommand(() => CurrentToolView = new RotateView());
        ExitCommand = new RelayCommand(() => Application.Current.Shutdown());
        FullscreenCommand = new RelayCommand(() =>
                                                 {
                                                     var fs = new FullscreenView
                                                                  {FullscreenImage = CurrentImage.LoadedImage};
                                                     fs.Show();
                                                 });
        HandleDropCommand = new RelayCommand<DragEventArgs>(e => OnFileDrop(this, e));
        Messenger.Default.Register<User>(this, "UserLogin", SetUser);
        Messenger.Default.Register<FlickrAccount>(this, "AddedAccount", AddAccount);
        Messenger.Default.Register<string>(this, "INeedAUser", SendUser);
        Messenger.Default.Register<string>(this, "INeedAImage", SendImage);
    }
like image 972
Iris Classon Avatar asked Dec 18 '11 15:12

Iris Classon


2 Answers

So you have commands for:

  1. File operations (Open, Save, Upload to Flicker)

  2. Window operations (Full screen, Close)

  3. Editing (Rotating, Resizing, Colour, etc)

Consider grouping (composing) related commands together in a custom class called for example FileCommands. Create a multi-level hierarchy if applicable. If you have a hierarchical menu in your view, You'll likely want similar Command Hierarchy.

Then, create one Controller per command group (for example FileController) and in the controller create method that will register the commands from the FileCommands group with the associated service.

See http://waf.codeplex.com/ sample applications (for example BookController.cs) for some ideas on how to actually implement Controller/ViewModel mapping. Note however that it's not exact same scenario (no breaking of Commands into groups).

like image 115
surfen Avatar answered Nov 07 '22 20:11

surfen


Use Caliburn Micro. For a button named name="Logout" the only thing needed in the ViewModel is a public method named Logout.

And without convetion bindings:

<Button Content="Remove"
        cal:Message.Attach="[Event Click] = [Action Remove($dataContext)]" />

Then on the ViewModel add a method named Remove and in that sample the DataContext is passed to the method.

like image 37
Derek Beattie Avatar answered Nov 07 '22 20:11

Derek Beattie