Implementing Closable Views

Topics: Prism v2 - Silverlight 3
Oct 17, 2009 at 12:36 AM

Hey guys - I am relatively new to Prism, Silverlight and MVVM.  I would like to describe the approach I have taken to implementing closable views, and get feedback on if I am going down the right path or not.

I have a ViewModel base class that has a DelegateCommand named CloseCommand.  It also has 3 virtual methods - CanCloseView, OnViewClosing, OnViewClosed.  Currently CloseCommand is bound to a Button in the HeaderTemplate of a TabItem.

Whenever I create a View, I do the following: 

IRegion mainRegion = _regionManager.Regions["MainRegion"];
string viewName = "OrderListView";

OrderListView view = _container.Resolve<OrderListView>();
OrderListViewModel = _container.Resolve<OrderListViewModel>();

view.DataContext = viewModel;

mainRegion.Add(view, viewName);

viewModel.CloseCommand = new DelegateCommand<object>(
   o => { viewModel.OnViewClosing(); mainRegion.Remove(view); viewModel.OnViewClose(); },
   o => { return viewModel.CanCloseView();  });

My intent was for the View and ViewModel to continue to be ignorant of eachother as well as whatever Region the View may be residing in, but now I have this bit of code that is very aware of all of the above.

Is there a better way to accomplish this?

Oct 17, 2009 at 10:32 PM

Lots of options. First I would propose a different view (no pun intended) on this that perhaps gets you to where you want to be:

 

Consider -->

 


IViewModel vm = _container.Resolve<IViewModel>("OrderListVm");


- this is all that needs to happen to get the view all 'wired up'. Obviously you previously wired up IViewModel to the concrete type(s).
....



note - Here I am using the vm where it really should be a seperate controller as the vm is handling too much. It violated 'single responsibility' but you should see my point - by using concrete types in Unity
instead of contracts your lack of coupling in v-vm is fine but the larger
and giving up the ability to think about the fundamental contract vs. concrete aspect this makes any v-vm coupling a secondary issue. In fact you would solve both if you had this in a controller I think you will
see.




public class OrderListViewModel : IViewModel, INotifyPropertyChanged {

public OrderListViewModel(IRegionManager regionManager, [Dependency("OrderListView")] FrameworkElement view){

IRegion mainRegion = regionManager.Regions["MainRegion"];

mainRegion.Add(view,"OrderListView");
CloseCommand = new DelegateCommand<object>(
o => { OnViewClosing(); mainRegion.Remove(view); OnViewClose(); },
o => { return CanCloseView(); });

}

DelegateCommand<object> CloseCommand ........

...

etc.


}

 

Damon Carr

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Oct 18, 2009 at 2:04 AM

Check the Screen Factory class described by Ward Bell in this article.