Click here to Skip to main content
15,895,084 members
Articles / Programming Languages / C#

MVVM (Part 2) - Commanding

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
1 Oct 2010CPOL5 min read 32.4K   278   16  
How to create Commands infrastructure in Silverlight

#region using

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using HomeGrownMVVM.Model;
using VvmScaffolding;

#endregion using

namespace HomeGrownMVVM.ViewModel
{
	public abstract class BaseViewModel : IBaseViewModel
	{
		#region Crt'r

		public BaseViewModel()
		{
			Initialize();			
		}

		#endregion Crt'r

		#region Initialize

		private void Initialize()
		{
			ItemSelectedCommand = new CommandBase(ItemSelectedAction);
			LoadedCommand = new CommandBase(LoadedAction);
			KeyDownCommand = new CommandBase(KeyDownAction);
		}

		#endregion Initialize

		#region IBaseViewModel Members

		#region LoadData

		public virtual void LoadData()
		{
		}

		#endregion LoadData

		#region ModelData

		public object ModelData { get; set; }

		#endregion ModelData

		#region DirectDataToView

		public IDirectData DirectDataToView { get; set; }

		#endregion DirectDataToView

		#region Subscribe IInforming

		public void Subscribe(IInforming informingView)
		{
			if (informingView != null)
			{
				informingView.NotifyEvent += InformingView_NotifyEvent;
			}
		}

		protected virtual void InformingView_NotifyEvent(object sender, GenericEventArgs e)
		{
			var presenter = e.Camel as FrameworkElement;
			if (presenter != null)
			{ //it is  a FrameElement which means it contains Tag
				var names = presenter.Tag as string; //read the Tag
				if (string.IsNullOrEmpty(names) == false)
				{//it contains a string lets process it
					e.Handled = true; //tell overriding handlers that i handled the event.
					var separators = new[] {'[', ']', ' '};
					names = names.Trim(separators);
					var saNames = names.Split(separators, StringSplitOptions.RemoveEmptyEntries);
					ModelViewRelation mvr = null;
					switch (saNames.Length)
					{
						case 1: //this VM will bo bound to the View
							mvr = new ModelViewRelation("Dynamic View", saNames[0], "this");
							break;
						case 2: //create a new V and VM
							mvr = new ModelViewRelation("Dynamic View", saNames[0], saNames[1]);
							break;
					}
					CreateAndInject.CreateAndBindViewAndViewModel(mvr, InjectTheView, presenter, this);
				}
			}
		}

		private UIElement InjectTheView(ModelViewRelation mvRelation, UIElement view, UIElement host)
		{
			var presenter = host as ContentPresenter;
			if ((presenter != null) && (view != null))
			{
				presenter.Content = view;
			}
			return view;
		}

		#endregion  Subscribe IInforming

		#region  Subscribe ILaunchChild

		public void Subscribe(ILaunchChild launchingView)
		{
			if (launchingView != null)
			{
				launchingView.LaunchChildEvent += LaunchingView_LaunchChildEvent;
			}
		}

		protected virtual void LaunchingView_LaunchChildEvent(object sender, ModelViewRelationEventArgs e)
		{
			PopUpView(sender, e);
		}

		#endregion  Subscribe ILaunchChild

		#region INotifyPropertyChanged

		public event PropertyChangedEventHandler PropertyChanged;

		protected void OnPropertyChanged(string name)
		{
			DoesPropertyExist(name);
			PropertyChangedEventHandler handler = PropertyChanged;
			if (handler != null)
			{
				handler(this, new PropertyChangedEventArgs(name));
			}
		}

		[Conditional("DEBUG")]
		private void DoesPropertyExist(string name)
		{
			if (this.GetType().GetProperty(name) == null)
			{
				MessageBox.Show(string.Format("PropertyCahnged failed:\n\n{0} is not a property name for {1}", name, this));
			}
		}

		#endregion INotifyPropertyChanged

		#endregion  IBaseViewModel Members

		#region InfoText

		private string infoText = string.Empty;
		public string InfoText
		{
			get { return infoText; }
			set
			{
				infoText = value;
				OnPropertyChanged("InfoText");
			}
		}

		#endregion InfoText

		#region commands properties

		private ICommand keyDownCommand = null;
		public ICommand KeyDownCommand
		{
			get { return keyDownCommand; }
			set
			{
				keyDownCommand = value;
				OnPropertyChanged("KeyDownCommand");
			}
		}

		private ICommand submitCommand = null;
		public ICommand SubmitCommand
		{
			get { return submitCommand; }
			set
			{
				submitCommand = value;
				OnPropertyChanged("SubmitCommand");
			}
		}

		private ICommand itemSelectedCommand = null;
		public ICommand ItemSelectedCommand
		{
			get { return itemSelectedCommand; }
			set
			{
				itemSelectedCommand = value;
				OnPropertyChanged("ItemSelectedCommand");
			}
		}

		private ICommand loadedCommand = null;
		public ICommand LoadedCommand
		{
			get { return loadedCommand; }
			set
			{
				loadedCommand = value;
				OnPropertyChanged("LoadedCommand");
			}
		}

		#endregion commands properties

		#region command actions

		#region LoadedAction

		protected virtual void LoadedAction(object param)
		{
			var pw = param as ParameterWrapper;
			if (pw != null)
			{
				var presenter = pw.Sender as FrameworkElement;
				var names = pw.Parameter as string;
				if ((presenter != null) && (string.IsNullOrEmpty(names) == false))
				{
					var separators = new[] {'[', ']', ' '};
					names = names.Trim(separators);
					var saNames = names.Split(separators, StringSplitOptions.RemoveEmptyEntries);
					ModelViewRelation mvr = null;
					switch (saNames.Length)
					{
						case 1: //this VM will be bound to the View
							mvr = new ModelViewRelation("Dynamic View", saNames[0], "this");
							break;
						case 2: //create a new V and VM
							mvr = new ModelViewRelation("Dynamic View", saNames[0], saNames[1]);
							break;
					}
					CreateAndInject.CreateAndBindViewAndViewModel(mvr, InjectTheView, presenter, this);
				}
			}
		}

		#endregion LoadedAction

		#region ItemSelectedAction

		protected virtual void ItemSelectedAction(object param)
		{
			var pw = param as ParameterWrapper;
			if (pw != null)
			{
				var node = pw.Parameter as MyTreeNode;
				if ((node != null) && (node.NestedNodeList != null))
				{
					InfoText = string.Format("{0} has {1} {2}", node.DisplayName, node.NestedNodeList.Count, node.CollectionType);
				}
				else
				{
					InfoText = string.Empty;
				}
				if (node != null)
				{
					var r = node.Tag;
					if (r != null)
					{
						var mvvmDef = new ModelViewRelation("Details", "DetailsChildWindowView", "DetailsChildWindowViewModel", r.Details);
						PopUpView(this, new ModelViewRelationEventArgs(mvvmDef));
					}
				}
				var tv = pw.Sender as TreeView;
				if (tv != null)
				{
					var tvi = tv.ItemContainerGenerator.ContainerFromItem(tv.Items[0]) as TreeViewItem;
					if (tvi != null)
					{
						tvi.IsSelected = true;
					}
				}
			}
		}

		#endregion ItemSelectedAction

		#region KeyDownAction

		protected virtual void KeyDownAction(object param)
		{
			MessageBox.Show("KeyDown Action is not ready");
		}

		#endregion KeyDownAction

		#endregion command actions

		#region PopUpView

		public void PopUpView(object sender, ModelViewRelationEventArgs e)
		{
			CreateAndInject.CreateAndBindViewAndViewModel(e.Holder, ShowDetails);
		}

		public ChildWindow ShowDetails(ModelViewRelation mvRelation, UIElement view, UIElement host)
		{
			var cw = view as ChildWindow;
			if (cw != null)
			{
				cw.Show();
			}
			return cw;
		}

		#endregion PopUpView
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions