IWeakEventListener.cs (this is a System class missing from Silverlight, so I created it)

Yes

Utilities

ObservableHelper.cs

Yes

Utilities

PropertyChangedEventManager.cs (this is a System class missing from Silverlight, so I created it)

Yes

Utilities

PropertyObserver.cs

Yes

Utilities

BindingEvaluator.cs

Yes

Utilities

ObservableDictionary.cs

Yes

Utilities

TreeHelper.cs

Yes

Validation

RegexRule.cs

Yes

Validation

Rule.cs

Yes

Validation

SimpleRule.cs

Yes

ViewModels

EditableValidatingViewModelBase.cs

Yes

ViewModels

IViewStatusAwareInjectionAware.cs

Yes

ViewModels

ValidatingViewModelBase.cs

Yes

ViewModels

ViewMode.cs

Yes

ViewModels

ViewModelBase.cs

Yes

ViewModels

ViewModelBaseSLSpecific.cs

Yes

ViewModels

ViewModelBaseWPFSpecific.cs

Yes

Workspaces

ChildWindowResolver.cs

Yes

Workspaces

CinchBootStrapper.cs (Silverlight version)

Yes

Workspaces

CinchBootStrapper.cs (WPF version)

Yes

Workspaces

PopupNameToViewLookupKeyMetadataAttribute.cs

Yes

Workspaces

IWorkspaceAware.cs

Yes

Workspaces

MockView.cs

Yes

Workspaces

NavProps.cs

Yes

Workspaces

PopupResolver.cs

Yes

Workspaces

ViewnameToViewLookupKeyMetadataAttribute.cs

Yes

Workspaces

ViewResolver.cs

Yes

Workspaces

WorkspaceData.cs

Yes

Now that I have shown you what classes will work with WPF/Silverlight, let's get on with the rest of this article, shall we? But first, here are the links to the old Cinch V1 articles.

In case you missed Cinch V1, and have an interest in MVVM, I would strongly recommend that you read all the Cinch V1 articles first, as it will give you a much deeper understanding of the content that will be presented in these Cinch V2 articles.

Cinch V1 Article Links

Some of you may never have seen the old Cinch V1 articles, so I will also include a list of these here, as where the Cinch V2 still uses the same functionality as Cinch V1, I will be redirecting you to these articles.

OK so that is what the article roadmap looks like, so I guess it is now time to dive into the guts of this article, so lets go:

New Stuff for Cinch V2

Now we can get into the guts of this article which is really the new stuff that has been added to Cinch V2; some of it is a rewrite of Cinch V1 stuff that has been rewritten to current best practices, such as using Blend interactivity.

SimpleCommand

This is a rewrite of the SimpleCommand that was available in Cinch V1.

So what's changed? Well, quite a bit actually:

I have added two constructors to it to make it trivial to declare a new SimpleCommand.

I have added a Weak CommandCompleted event (this is incredibly useful, you will see more on this in a bit).

I have added two generic parameters to it, such that the ICommand.CanExecute parameter and the ICommand.Execute parameters can be declared as having different parameter types.

Step 3 : Add the Command Methods

Actions/Triggers

Now I am a massive fan of attached DPs, but I am also willing to roll over and play the game when something better comes along. And a while back, something better did come along by way of the Blend Interactity.dll, which contains base classes for Actions/Behaviours/Triggers, all of which have kind of come from what a lot of people were already doing with Attached DPs. Basically, the Blend Interactity.dll contains base classes that mimic what the WPF/Silverlight community were already doing with Attached DPs, just formalised into a pattern, that allows Blend users to simply drag on these classes to the design surface and change a few properties, and bingo...magic occurs.

Anyhow, all that said, I used to have a bunch of Attached DPs in Cinch V1, and by and large, these have just morphed their way into Blend Interactivity Actions/Behaviours/Triggers, but there are some new ones in here too.

You can access these new Cinch V2 Actions/Behaviours/Triggers using the standard Blend Assets tab:

SelectorDoubleClickCommandBehavior (WPF only, was also available in Cinch V1 as Attached DP)

This is also a pretty standard behaviour that can be used to fire a ViewModel Command whenever a Selector item is double clicked; although the WPF demo app does not have an example of this, this is how you would use it within XAML:

It can be seen that you can get all the relevant information, such as:

The Command parameter

The EventArgs

The sender (source of the event, ListView in this case)

Note: I am not an advocate of having UI type objects in my ViewModel, as it is harder to test, but some folk love it, so I do provide that within the args.EventArgs / args.Sender objects, but I have to say I have never had to do this sort of thing in any ViewModel code I have ever written. So use it at your peril, don't blame me when you can't test your ViewModel properly, I warned you.

TextBoxFocusBehavior (WPF only)

Cinch V2 also provides a way for ViewModels to set focus within a View. The basic idea is this:

The ViewModelBase class has a public method called RaiseFocusEvent(String focusProperty) which raises a ViewModelBase event called FocusRequested

Then there is a Blend Behaviour called TextBoxFocusBehavior, which listens for the ViewModelBase FocusRequested event

When the TextBoxFocusBehavior sees the ViewModelBase FocusRequested event fire, it sees if the Behaviour target FrameworkElements (TextBox) binding matches the requested property name, and if it does, focus is moved to the Behaviour target object (TextBox)

So what does the code look like? Well, starting with the ViewModelBase class, there is this code:

You can see that this Blend Behaviour supports DataWrappers too, you just need to specify if the TextBox you are applying this Behaviour to is bound to a DataWrapper. You may also notice that this class delegates some work to a base class, that is where the actual focus work takes place, so let's have a look at that too.

Triggers

CompletedAwareCommandTrigger

Most WPF/Silverlight users will be well used to the idea of calling Commands in ViewModels from their Views. But occasionally, what you need is the opposite, you need the ViewModel to tell the View to do something. In Cinch V2, I have provided for this mechanism, by providing a SimpleCommand that fires a CommandCompleted event when it has run its Execute delegate. This command can then be used as a Trigger to run some Blend Actions inside a View.

Cinch V2 goes a step further and provides a Blend Trigger that is expecting to be bound to a SimpleCommand that has a CommandCompleted event, and will run the Triggers Actions when the CommandCompleted event fires.

This example uses a standard Blend GoToStateAction but this could be any Action that you like that you want to trigger based on a SimpleCommand in the ViewModel Completing:

And this is what some ViewModel code might look like:

//public property for the View to bind topublic SimpleCommand<Object, Object> ShowActionsCommandReversed { get; privateset; }
// initialise the Command, do nothing with its Execute delegate// some reverse commands, that the VM fires,// and the View uses as CompletedAwareCommandTriggers//to carry out some actions. In this case GoToStateActions are used in the View
ShowActionsCommandReversed = new SimpleCommand<Object, Object>((input) => { });
//Fire the command from the ViewModel, so the Views//trigger can carry out any Actions associated //with this command completing
ShowActionsCommandReversed.Execute(null);

CompletedAwareGotoStateCommandTrigger

I don't know how many of you know this, but the standard VisualStateManager that can be used to programmatically go to a particular VisualState will only work when the VisualStateGroup that contains the VisualState you are trying to go to is contained directly under the root element in your VisualTree.

In fact, this is a fair assumption, as that is the way the standard Blend GoToStateAction is expecting to work; if you look at the VisulStateManager.GoToState, you will see it only accepts a control as shown below:

But sometimes you may require your VisualStateGroups to not be directly under the root node in your VisualTree (OK it is rare, but it does happen), and the FrameworkElement you might want them in may or may not be a control.

Now I don't think many people know this, but there is also a ExtendedVisualStateManager that can work with any FrameworkElement; as such, Cinch V2 provides a Blend trigger that can work with a Cinch SimpleCommand<T1,T2> CommandCompleted event to make use of the ExtendedVisualStateManager or the standard VisualStateManager

Note: I do not expect this to be used that much, but here is how one might use it anyway.

This is what the complete code for the CompletedAwareGotoStateCommandTrigger looks like:

It can be seen that you can tell it whether it is being used at root level within the VisualTree, in which case it will use a standard GoToStateAction, or else it will use the ExtendedVisualStateManager.

EventToCommandTrigger

As the name suggests, this Trigger provides an event to command functionality; that is, it will fire a ViewModel based Command when a certain event occurs. Now, some might argue that there is support for this already by simply using the standard Blend Actions/Triggers. Whilst that is partially true, the standard Blend ones lack the ability to disable the consuming FrameworkElement when the Command can not execute. This is something that Cinch V2 does offer over the standard Blend Actions/Trigger combination.

It can be seen that you can get all the relevant information, such as:

The Command parameter

The EventArgs

The sender (source of the event)

Note: I am not an advocate of having UI type objects in my ViewModel, as it is harder to test, but some folk love it, so I do provide that within the args.EventArgs / args.Sender objects, but I have to say I have never had to do this sort of thing in any ViewModel code I have ever written. So use it at your peril, don't blame me when you can't test your ViewModel properly, I warned you.

Actions

CommandDrivenGoToStateAction

This is a simple class that inherits from GoToStateAction and is expecting to be used in conjunction with a Cinch V2 CompletedAwareGoToStateCommandTrigger, which has a CommandCompleted event (which we talked about above), which you can use to supply a StateName with, using the CommandParameter in your ViewModel.

And you would have something like this in your ViewModel; obviously, you could also use the VisualStateManagerService as provided by Cinch V2, but as I mentioned, that only works if the VisualStateGroups are directly under the root node in the VisualTree, as the standard VisualStateManager is used.

Workspaces

This section discusses Workspace support in Cinch V1 (OK, there was no MeffedMVVM support in V1, I mean a V1'ish approach in V2 really) and Cinch V2 proper. The workspace techniques employed by a V1'ish offering and V2 proper offer quite different support for Workspaces and design time data, so please read carefully.

ViewModel First, Ala Cinch V1 stylee

Now in Cinch V1, there was some kind of attempt at workspaces using an ObservableCollection<ViewModelBase> and marrying that up with Views using some specific DataTemplates in a resource dictionary somewhere. You can read more about this approach using this Cinch V1 article link: CinchIII.aspx#CloseVM.

Using this approach, we are assuming a ViewModel first arrangement, and the problem with this approach is that you are not really lending the ViewModel the best support it could get in order for MeffedMVVM to supply design time data. Actually, there is a way, it's just not the preferred way in Cinch V2.

So let us just have a look at what sort of design time support Cinch V2/MeffedMVVM offers the DataTemplates workspace approach that a Cinch V1'ish type app uses.

ViewModel design

The ViewModel first and DataTemplates method is still supported by Cinch V2, and MeffedMVVM can still be used to supply design time data, though the way you have to create the ExportViewModelAttribute on the ViewModel would need to be told that the ViewModel is expecting to be set directly as the DataContext for a View (say via a DataTemplate), which would be the case in a ViewModel first approach using DataTemplates as done in a Cinch V1'ish style app.

You would set the ExportViewModelAttribute on the ViewModel as shown below, and also implement a special MeffedMVVM interface called IDesignTimeAware. So taking all that into account, we might have a ViewModel something like this:

Important: The [ExportViewModel("DummyViewModel", true)] line tells MeffedMVVM that this ViewModel is data aware, as it is used in some sort of DataTemplate approach.

Another thing to note is that the ViewModel implements a MeffedMVVM interface called IDesignTimeAware which allows MeffedMVVM to call the DesignTimeInitialization() method in order to supply design time data for this ViewModel. The only bad thing with this is that your ViewModel now contains code that is only used at design time. But a small price to pay, I think.

View design

The other piece of the puzzle is to use the standard MeffedMVVM Attached DP, as shown in this View, which allows MeffedMVVM to locate the ViewModel to supply design time data for:

ViewModel-View Matching

As I stated at the start of this section, Cinch V1 makes use of a ViewModel first paradigm, and as such, the View is created by using DataTemplates, where there is expected to be a ObservableCollection<ViewModelBase> somewhere, and some DataTemplates to match against the specific ViewModelBase instances. Something like this example that shows a View that has a ObservableCollection<ViewModelBase> bound to a TabControl:

But I also said this is not the proffered approach in Cinch V2, so let us have a look at what we might do in Cinch V2.

View First: A Better Approach (WPF Support Only, Sorry SL Users)

Within Cinch V2, what I wanted was a couple of things:

The ability to use full View first design time data support offered by MeffedMVVM

Allow some sort of contextual data to be passed to a view

So those are the requirements I set out with; sound simple, don't they? So how do they work? Well, the first one is dead simple, you have seen that before, and I talked about it in the first Cinch V2 article, read this link View-ViewModel Resolution for more details on that; that is standard Cinch V2/MeffedMVVM View-ViewModel resolution, so I will not go into that again.

The second point above is however totally new territory and something I do quite like actually.

So let's just go through a quick scenario:

"Suppose you have a TabControl that is showing a list of customers, and that list of customers is its own View (say CustomersListView/CustomerListViewModel), and when you click on one of the customers in the list, you wish to open a new View which shows the selected customer's details in a new View (say CustomerEditView / CustomerEditViewModel)."

That sounds easy enough, and you are probably thinking, oh, I could use a Mediator for that, but remember the Mediator is a broadcaster that broadcasts a message NotifyColleagues("New Customer Edit", SomeCustomer), so any subscriber of this message would have to work out whether they should add a new View for the CustomerEditView. It is not that easy, believe me.

So what I have come up with is a variation on what I offered in Cinch V1 using an ObservableCollection<T> and DataTemplates; it's just this time, I am using a View first approach to take full advantage of MeffedMVVM.

So how does it all work?

Well, in step by step instructions, it works like this:

The WPF ViewModelBase class holds a ObservableCollection<WorkspaceData>, where each WorkspaceData has a CloseWorkSpaceCommand to ensure that the workspace can be closed (say if it's in a TabControl).

Within the View that has the need to show the sub views, there is a single DataTemplate that matches against the type WorkspaceData.

Within the DataTemplate for the WorkspaceData, there is an Attached DP which uses the bound WorkspaceData to deduce what View should be loaded.

The Attached DP that now knows about the WorkspaceData can also obtain some additional contextual information from the bound WorkspaceData and passes this data to the View.

I have to say I think this approach now offers me the full support that I wanted; I can have View first, I have a way of adding Views to regions of another View using standard code all in my ViewModels. I can pass the newed up View some contextual data, and best of all, I get full design time data support for my ViewModels thanks to my Views being View first.

That is the brief, so what does the code look like? Well, let's start at the beginning.

WorkSpaces : The Actual WorkSpaceData Class

Probably the first thing to look at is the actual WorkspaceData code, which looks like this:

As you can see, this is a pretty simple class that has a few properties and also notifies (using the Mediator) any ViewModel that holds an instance of one of these classes to remove it when the CloseWorkSpaceCommand (maybe from a closeable TabItem) is executed.

WorkSpaces: ViewModelBase Class Support

And the Cinch WPF ViewModelBase class has a ObservableCollection<WorkspaceData> such that any ViewModel that inherits from a Cinch ViewModelBase class is capable of managing workspaces.

See how I am creating two workspaces there using the WorkspaceData, and you may also notice in the workspace 1 code above, I am even passing in some contextual data to it, which we will get to in a minute.

You can also see that there is an optional WorkspaceTabClosing that I can use to hook up, from where the ViewModel could possibly decide whether to really allow the WorkSpaceData to be closed (this could be some code, or asking the user, as I am in the example above).

So now we have some WorkspaceData items in the Views collection, what now? Well, we need to supply a single DataTemplate to match against the Type of WorkspaceData. This should only be done once per app, as the Template to use will always be the same (or it should be).

In this XAML, see how I am binding a TabControl (well, it's a special TabControl which I will also talk about in this article) to the Views collection, and I am providing a DataTemplate which uses an Attached DP called NavProps (more on this in just a second).

*** Very Important Notes ****

Sorry about the image, but it got your attention right!!!!!

Impotant Note 1

I would very, very strongly recommend that you use a DataTemplate like that shown above. In fact, you must provide a Border in your DataTemplate; otherwise the workspaces in Cinchwill not work. As the NavProps DP is expecting the parent to be a Border, you must supply a Border as the root container within the DataTemplate, so this is quite important.

Impotant Note 2

The other thing to note is that the workspaces are really only intended to be bound against a ItemsControl, and as such you must stick to using ItemsControl or any of its super types, such as TabControl/ListBox etc. Basically, with a ListBox, you should be able to craft anything, from a single item, to multiple items; remember, with a ListBox, you can swap out the ItemsPanelTemplate to use any of the standard layout containers such as Grid/Canvas etc., so I am confident you can do anything with ItemsControl or any of its super types. Failure to use a ItemsControl will result in non-working workspaces.

You must abide by these two notes....If you don't, this will result in non-working workspaces, so just follow these notes and you should be fine.

WorkSpaces: The NavProps Attached DP to Resolve the View

Recall from earlier, we briefly touched on an Attached DP called NavProps. Well, what does that do for us? A couple of things actually. There are actually two Attached DPs:

The ShouldHideHostWhenNoItems Attached DP: Can be used to hide the ItemsControl host when there are no more displayable items left.

The ViewCreator Attached DP: Is used to bind with a WorkspaceData object, and when it changes, it examines the bound WorkspaceData.ViewLookupKey and will create a new View based on that key.

ShouldHideHostWhenNoItems Attached DP

This is pretty simple really, it is basically just a boolean that can be set on your ItemsControl to have it hide itself when there are no more displayable items in it. This is probably most useful when you allow your users to close workspace items (such as closeable tabs).

ViewCreator Attached DP

This is the second Attached DP within the NavProps class. And as I say, this one is responsible for actually creating a new View based on some magical string that is set on the databound WorkspaceData.ViewLookupKey. This code looks like this:

Now you may notice that there is a class called ViewResolver (var theView = ViewResolver.CreateView(viewNavData.ViewLookupKey);), so how does this ViewResolver know what to do with a string, and how does it create a new Window from it? Well, simply put, the ViewResolver is just a Dictionary<string,type> where it uses Activator.CreateInstance to create a new instance of a type that matches a string lookup key (yes, the one from the bound WorkspaceData).

It then grabs the DataContext (MEF supplied) from the View, and stores it back in the WorkspaceData object, such that the code that created the WorkspaceData object will have a link to the newly created ViewModel.

It then casts the obtained View to IWorkSpaceAware and sets the dataAwareView.WorkSpaceContextualData property, passing in the contextual data as supplied by the WorkspaceData.

In the demo app, I use the WorkspaceData to pass a directory path to the ImageLoaderView using the IWorkSpaceAware interface that the View implements. What happens then is MeffedMVVM creates the ViewModel, and the WPF demo app's ViewModel just happens to use the IViewAwareStatus service, so we hook into the loaded event of that, and then do the following in the ViewModel.

And that is how we manage to get contextual data from the workspace into the View and also into the ViewModel via the View (using the IWorkspaceAware interface on the View).

But how does the ViewResolvers Dictionary<string,type> get populated in the first place? Well, in the Cinch V2 WPF demo app, this happens in the App.xaml.cs when you call the CinchBootstrapper to reflectively look through an IEnumerable<Assembly> to try and find any Views (UserControls) that are attributed up with the special Cinch ViewnameToViewLookupKeyMetadata.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Cinch;
using System.Diagnostics;
namespace CinchV2DemoWPF
{
[ViewnameToViewLookupKeyMetadata("ImageLoaderView", typeof(ImageLoaderView))]
publicpartialclass ImageLoaderView : UserControl, IWorkSpaceAware
{
}
}

And that is how the ViewResolvers Dictionary<string,type> is populated ready for the Attached DP to call upon it to create the View that matches the requested View type from the WorkspaceData that is being bound to in the DataTemplate.

WorkSpaces: Special Notes

Now all of this is grand, but unfortunately, WPF throws some weirdness in our path, in the form of the TabControl. Which is a bastard of a control. How many of you know that in WPF the TabControl's VisualTree only keeps the selected item in the VisualTree.

Does that sound bad to you? No, think again (though this is only a problem when using DataTemplates, direct TabItem / View combination is OK). So we have several Views which use MeffedMVVM to create a ViewModel within a TabControl. We then change tabs, and guess what? The View gets trashed, and when we go back to a previous TabItem, as we are using Vew first and MeffedMVVM, a new ViewModel is created for the View.

Now that is a bit messed up, don't you think? Well, I for one do.

Luckily, help is at hand. I have long known this, and have crafted a special TabControl for WPF that does not trash the VisualTree on selection changed, but rather keeps all items in memory and changes the Visibility of them.

This requires two things that you need to include in your own WPF projects:

Just for completeness, here is what I do in the WPF demo app to provide closeable TabItems, where the PART_CloseButtons is bound to the WorkspaceData that was used to create the DataTemplate being applied to the TabItem.

As I say, the workspace support in Cinch V2 is only available for WPF, and I will not be supplying it for Silverlight, for several reasons:

Silverlight's TabControl lacks some of the overrides and general internals that I need to make it work the same as in WPF.

In Silvelight, I think there is more of a tendency to use NavigationFrame etc., to provide navigation, which I think is a great idea. I think desktop apps should look and work like desktop apps, and web apps should look like web apps, which would imply (at least to me) that TabControl like functionality belongs only to the desktop ...but that is just my opinion. You know if you disagree, implement something similar to the WPF version and check out the WPF version's IViewAwareStatus service implementation, which is different from the Silverlight version. The WPF one uses WeakEvents/WeakReference all over the place.

Extra Threading Helpers

Cinch V1 already had a few Dispatcher related helpers, and Extension Methods. If you missed some of the utilities in Cinch V1, here is brief description of what they did:

BackgroundTaskManager: A small wrapper around a BackgroundWorker

DispatcherExtensions: Some nice Dispatcher extensions (WPF only)

DispatcherNotifiedObservableCollection<T>: ObservableCollection<T> which marshals to a UI thread

It is basically a UI synchronization context, similar to the one found in WinForms, but is tailored for use with WPF and Silverlight. It is strange that such an object does not already exist within the standard WPF/Silverlight base classes, ho hum.

There is an interface for this class, such that if you want to create a mock or test double, you can. Here is the interface:

PropertyChangedEventManager

This is only available for Silverlight.

As Silverlight does not have a PropertyChangedEventManager, I thought I would provide one to fill the gap (WPF has this class, of course). In fact, when I say I thought I would provide one, I really mean that I stole it from fellow WPF Disciple Pete O'Hanlon. So if you find that you need the PropertyChangedEventManager in Silverlight, never fear, it is here.

ArgumentValidator

Which is a simple class that provides many methods that can be used to validate arguments to methods.

BindingEvaluator (WPF Only)

This is only available for WPF.

I have found this class to be quite useful from time to time. Basically, it is a dead simple class that allows you to find the value of Binding; here is the full code listing:

See the recommended usage comments in the code chunk above to see how to use this class.

ObservableDictionary<TKey, TValue> (WPF Only)

This is only available for WPF.

I stole this directly from Dr. WPF, and it is a fantastically well written class that is basically a bindable ObservableDictionary, like it says on the tin.

TreeHelper (WPF Only)

This is only available for WPF.

When working with WPF, you will be working with the VisualTree, so it is useful to have some helper to aid in the drudgery. Fellow WPF Disciple Philip Sumi has a nice class called TreeHelper, which I have now included in Cinch V2, which offers various methods such as:

That's It ....For Now

Could I just ask if you have enjoyed this article, and feel it is going to help you out, could you please show your support by leaving a vote/comment?

As before, if you have any deep MEF related questions, you should direct those to Marlon Grech either by using his blog C# Disciples, or by using the MefedMVVM CodePlex site; any other Cinch V2 questions will be answered by the next Cinch V2 articles.

Comments and Discussions

I've started to try to use MVVM in an application and it is first now that I appreciate the work you have done. So a 5 from me.

I have a question regarding sharing properties between ViewModels and your Mediator class. If I get it correctly it only does one-way communication to a delegate. Is there any reason that you haven't set up the same Mediator to be able to set properties with similar key strings in the attribute?

I've started to try to use MVVM in an application and it is first now that I appreciate the work you have done. So a 5 from me.

Thanks

Kenneth Haugland wrote:

I have a question regarding sharing properties between ViewModels and your Mediator class. If I get it correctly it only does one-way communication to a delegate. Is there any reason that you haven't set up the same Mediator to be able to set properties with similar key strings in the attribute?

Hmmm. Sorry to bother you again, but I hit a bit of a problem that I really dont know how to tackle.

The Mediator is working fine for all objects that implement INotifyPropertyChanged, but I really wanted to include support for listening to ObservableCollections. So I did.

I hit a bit of a problem then; if I used the WeakReferance on the class itself to get the property that holds the ObservableCollection, I was not able to remove the handler. The Target of the WeakReferance was set to null, and so the property was not available. This would also lead to a memory leak, even if it is a WeakEventManager, or?

The strange thing, to me at least, was that I was able to remove the handler for the INotifyPropertyChanged without any problems:

I like the fact that Cinch has an ObservableDictionary class. I would like to add a handler to the CollectionChanged event, however I can't because it is marked protected. What is the reason behind this?

This is all running and the PropertyInfo in the first line is not null.
And at Debuggingtime, the "a" is recognized as a SimpleCommand<object, object>. But its content is null.
So, the last line is throwing a NullPointerException.

At this time it would be more elegant to run the method which my SimpleCommand has to call directly (i know), but I use this mechanism from Marlon Grech.

Hi,
Of course my vote of 5 - how you get the time to write 118 articles so far!

But in the text above you say you've never had to use EventArgs in your commands. I fully agree you don't want EventArgs in one's ViewModels but sometimes you need to handle Handled or get NewObject or OriginalObject from the EventArgs, especially when using 3rd Party controls. Which is my problem and why I'm searching articles. Surely you're not suggesting using the event in the code-behind and resending as a Command?

I do like Caliburn Micro's solution however, where I can add $eventArgs.Something as a parameter, and as many parameters as I like, so effectively I am avoiding references to the Control in my ViewModel.

I obviously do not see this as such a big deal as you do. If it really bothers you, just copy the source code into your own code add a new constructor, and then you are good to go. What I will do, is email myself to make that class partial so you could have added it without fuss

Sacha Barber

Microsoft Visual C# MVP 2008-2011

Codeproject MVP 2008-2011

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

Thats what I like to hear...To be honest that is one of the things that I am most happy with in CInch, the fact that its so extensible, and every part can be swapped/extended very easily especially now with Cinch on MefedMVVM

Sacha Barber

Microsoft Visual C# MVP 2008-2010

Codeproject MVP 2008-2010

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

I have just migrated a small application from CinchV1 to V2.
Most of the work caused the new MEFFed Workspaces: the instance of the ViewModel is not visible and the ctor has no own parameters.
Overall it is so still better, because the templating of the View is simplier.
Parmaters an be transfered via an special property of the WorkspaceAware-Interface.

No I have no idea what could be causing this weird behaviour. MefedMVVM code was broken, so you need to get latest Cinch/MefedMVVM dlls, from this weekend, downloaded latest Cinch code, I uploaded in Saturday. MefedMVVM was breaking design time code, Marlon made a mistake that he checked in by accident. All fixed now

Sacha Barber

Microsoft Visual C# MVP 2008-2010

Codeproject MVP 2008-2010

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

So, downloaded the newest MEFedMVVM and CinchV2, compiled (release) and copied the new dll-versions to my 'Distributions' directory.

After opening my app in VS2010, I just get the same behavior.

In your sample, you use your tabEx control, but I just put a simlle listbox on the form and bound it to an ordinary property returning an ObservableCollection(of String). Maybe there is some hidden issue?
I try to do the simplest scenario first, and use only standard stuff beside CinchV2.

as data support at design time is part of MEFedMVVM, I changed inheritance of my viewmodel class and didn't use the CinchV2 VieModelBase. I implemented the PropertyChanged notification the standard way using a string expression and still get the same behavior.

You started talking about a scenario where we have a list of customers and you want to see the details from one of those customers. This is exactly what I need to do, but I am struggling trying to work out the details. The discussion seems to switch to your sample program which does not demonstrate this behavior. Would it be possible for you to provide some simple pseudo code on what is necessary to replace on view with another, in this case the customer list view, with the customer details view.

REally depends on how you want to do it. Should it be list + details on same page. If so thats just a list of Customers with a CustomerView control (say) bound to List selected item.

If you want to view selected customer on a different page, you would need to listen to listbox selection or something maybe use ICollectionView, and send mediator message to ViewModel that has workspaces, and then use mediator message payload to create a new Workspace for the customer that was picked.

So it would be something like this

MainViewModel has ObservableCollection<workspacedata>, it adds a WorkspaceData item to initially show CustomersViewModel (see demo for working with WorkspaceData)

CustomersViewModel has list of Customers on it. Probably has ICollectionView to pick out selected one in ViewModel, when selection changes, it uses mediator to send a NewCustomerSelectedMessage with the Customer object selected as the message payload.

MainViewModel listens for NewCustomerSelectedMessage mediator message, grabs the Customer from it, creates a new WorkspaceData and passes it the NewCustomerSelectedMessage messages Customer (payload it was sent from CustomersViewModel) object as the DataValue.

The newly created WorkspaceData is added to the MainViewModel' ObservableCollection<workspacedata>

This should all work if you follow the View 1st/NavProps DP I show in the articles.

That is how I would do it.

Sacha Barber

Microsoft Visual C# MVP 2008-2010

Codeproject MVP 2008-2010

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue