MVVM Part 6: InteractingViewModel / IUserInteracter

How can ViewModels become nearly independant from their concrete view but still keep the control over it?
IUserInteracter can be an answer.

Note: This posting is part of a series. See MVVM-Library for other parts and download.

As the last part of this series is more than one month ago, I really have to publish this now :-) So please excuse some undocumented parts, unfinished classes and not working code in the MVVM-Library. I will correct it later.

Where did we breake off?

In the last part we were able to abstract the user interface using the IUserInterface interface. At the end, we could use this IUserInterface to show IShowables. However, we do not have any Showables yet – so we can not really use our IUserInterface.

What this part is about

Now we want to connect the IUserInterface and our ViewModels.

Let’s start!

IUserInteracter

The IUserInteracter is the “core” of interaction between ViewModels and Views: It is strongly connected with a View (means “a Showable”) which is not directly accessible, however, as you will see. Its implementation is fully based on the IUserInterface interface introduces in the last part. So it is independent from any concrete technology.

Look at this class diagram showing its members:

Class diagram of IUserInteracter and UserInteracter

Close

This method does exactly what it is called: It closes the associated Showable.

Show(Modal)

Show and ShowModal show a new Showable with the Showable represented by the UserInteracter as its parent.

Closing

This event is fired when someone (including the user) tries to close the Showable represented by the UserInteracter. Subscribers of it may cancel the closing process.

Closed

You may be able to guess when this event is fired ;-) : It’s fired after the Showable represented by the UserInteracter has been closed.

How does this help us?

Well – we now have one more layer of abstraction; let’s call it the “UserInteractor-Layer”.

What makes it different from the IUserInterface?

An IUserInterface represents the whole UserInterface with all its windows etc. Or in order to express it better: It makes it accessible.

The UserInteracter – in contrast – makes one View accessible. And that’s the common practice we find: A ViewModel is represented by one View.

So the next logical step is to give the UserInteracter to a ViewModel.

InteractingViewModel

And we are lucky: InteractingViewModel is just what we have been looking for :-)

The following diagram shows both InteractingViewModel and UiPartViewModel. By now, UiPartViewModel is not fully implemented – I will come back to it in a further post again.

Class diagram of UiPartViewModel and InteractingViewModel

The only thing IInteractingViewModel introduces: The property Interacter of type IUserInteracter.

UiPartViewModel brings in more comfort by providing the Close-command and OnClosing / OnClosed.

After very long time of thinking, I came to the result that it is the best that InteractingViewModels get their IUserInteracter as a constructor parameter.

ViewModelShowable

In order to show our InteractingViewModels we still need a subclass of Showable: ViewModelShowable.

Its constructor accepts a Func creating an InteractingViewModel with a provided IUserInteracter.

ViewModelPresenter

You may remember that our UserInterface relies on so-called IShowablePresenters. Therefore, we have a ViewModelPresenter showing ViewModelShowables. As a Window is able to close itself (this is not very ViewModel friendly), we have to do a little workaround so only ViewModels are able to close windows. You will easily find it in the code of ViewModelPresenter.

Code

This may be the most important part for you: How does the code look like now, using InteractingViewModel.

In my opinion it all looks really clean and elegant.

Showing a ViewModel

This is all you have to write:

this.Interacter.Show(new ViewModelShowable(interacter => new FooViewModel(interacter)));

Closing a ViewModel

Again: Very simple

this.Interacter.Close()

Deny closing a ViewModel

Just override OnClosing:

protected override void OnClosing(CancelEventArgs e)
{
    e.Cancel = true;
}

Sample project

ScreenshotOf course, we also have got a little sample project.

Do not wonder about the sense of this sample project – there is absolutely none behind it. Its only purpose its illustrating how flexible you are using my MVVM-Library. Just play around and see how parents can not be closed when children deny it and how easy showing new ViewModels is.

As always, it can be downloaded from the MVVM-Library. You will find it as UserInteractionSample.

A little workaround

One problem is still left: If you block closing a ViewModel, you have to call CommandManager.InvalidateRequerySuggested when the condition changes that controlls this blocking. Sounds a little bit confusing but the sample project shows what I want to say. I am still looking for a better way here – if you have one, please let me know.

Conclusion / Outlook

Our ViewModels are on the best way to get rid of any UI-specific code. We fully abstracted the process of showing and closing ViewModels in Windows.

In the next part, we will look at the view creation. It is used by components of this part but we did not really introduce it yet. In addition, our Windows will get icons and titles.

The part after the next will come back to threading again – we have still have a bad dependency to the Dispatcher class. In addition, we will see ways of threadsafe multithreading.

About these ads

4 Responses to “MVVM Part 6: InteractingViewModel / IUserInteracter”

  1. DotNetShoutout Says:

    Model-View-ViewModel (MVVM) – Part 6: InteractingViewModel…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

  2. Frederic Ouellet Says:

    Really nice set of posts.
    They answer to some tough i recently had.
    Can’t wait for the last parts.

  3. tobi Says:

    I have a question:

    class Model { IList Items; }
    class ViewModel { ObservableCollection Items; }

    whenever my business logic changes the Model.Items collection i want the ui to update of course. How can i do that without manually doing that every time my logic changes the Model.Items collection?

  4. winsharp93 Says:

    >> whenever my business logic changes the Model.Items collection i want the ui to update of course.
    Well – there is no really good way. You could either let the commands (which are the reason for changes in the model as they call methods) update the collection. Another possibility would be change notifications the model raises.

    In most cases, however, there is no need for such tricks as only the ViewModel changes the Model. Therefore, it should not change by iteself.


Comments are closed.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: