Click here to Skip to main content
15,884,099 members
Articles / Desktop Programming / WPF

Zip My Code

Rate me:
Please Sign up or sign in to vote.
4.78/5 (17 votes)
20 Dec 2009CPOL3 min read 71.6K   2K   48  
A utility stripping your source code to the essential core and then compressing it to a nice CodeProject article attachment.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using ZipMyCode.Service.FrameworkDialogs;
using ZipMyCode.Service.FrameworkDialogs.FolderBrowse;
using ZipMyCode.UI.Mvvm;
using DialogResult = System.Windows.Forms.DialogResult;

namespace ZipMyCode.Service
{
	/// <summary>
	/// Service responsible for showing dialogs.
	/// </summary>
	class DialogService : IDialogService
	{
		private HashSet<FrameworkElement> views;


		/// <summary>
		/// Initializes a new instance of the <see cref="DialogService"/> class.
		/// </summary>
		public DialogService()
		{
			views = new HashSet<FrameworkElement>();
		}


		#region IDialogService Members

		/// <summary>
		/// Registers a View.
		/// </summary>
		/// <param name="view">The registered View.</param>
		public void Register(FrameworkElement view)
		{
			if (views.Contains(view)) throw new ArgumentException("View has already been registered.");

			// Get owner window
			Window owner = view as Window;
			if (owner == null)
			{
				owner = Window.GetWindow(view);
			}

			if (owner == null)
			{
				throw new InvalidOperationException("View is not contained within a Window.");
			}

			// Register for owner window closing, since we then should unregister View reference,
			// preventing memory leaks
			owner.Closed += OwnerClosed;

			views.Add(view);
		}


		/// <summary>
		/// Unregisters a View.
		/// </summary>
		/// <param name="view">The unregistered View.</param>
		public void Unregister(FrameworkElement view)
		{
			if (!views.Contains(view)) throw new ArgumentException("View has never been registered.");

			views.Remove(view);
		}


		/// <summary>
		/// Shows a dialog.
		/// </summary>
		/// <param name="ownerViewModel">
		/// A ViewModel that represents the owner window of the dialog.
		/// </param>
		/// <param name="viewModel">The ViewModel of the new dialog.</param>
		/// <returns>
		/// A nullable value of type bool that signifies how a window was closed by the user.
		/// </returns>
		public bool? ShowDialog<T>(object ownerViewModel, DialogViewModelBase viewModel)
			where T : Window
		{
			// Create dialog and set properties
			T dialog = Activator.CreateInstance<T>();
			dialog.Owner = FindOwnerWindow(ownerViewModel);
			dialog.DataContext = viewModel;

			// Make OK command close dialog
			viewModel.OkCommand = new RelayCommand((o) => dialog.DialogResult = true, viewModel.CanOk);

			// Show dialog
			return dialog.ShowDialog();
		}


		/// <summary>
		/// Shows a message box.
		/// </summary>
		/// <param name="ownerViewModel">
		/// A ViewModel that represents the owner window of the message box.
		/// </param>
		/// <param name="messageBoxText">A string that specifies the text to display.</param>
		/// <param name="caption">A string that specifies the title bar caption to display.</param>
		/// <param name="button">
		/// A MessageBoxButton value that specifies which button or buttons to display.
		/// </param>
		/// <param name="icon">A MessageBoxImage value that specifies the icon to display.</param>
		/// <returns>
		/// A MessageBoxResult value that specifies which message box button is clicked by the user.
		/// </returns>
		public MessageBoxResult ShowMessageBox(
			object ownerViewModel,
			string messageBoxText,
			string caption,
			MessageBoxButton button,
			MessageBoxImage icon)
		{
			return MessageBox.Show(FindOwnerWindow(ownerViewModel), messageBoxText, caption, button, icon);
		}


		/// <summary>
		/// Shows the FolderBrowserDialog.
		/// </summary>
		/// <param name="ownerViewModel">
		/// A ViewModel that represents the owner window of the dialog.
		/// </param>
		/// <param name="viewModel">The ViewModel of the FolderBrowserDialog.</param>
		/// <returns>The DialogResult.OK if successful; otherwise DialogResult.Cancel.</returns>
		public DialogResult ShowFolderBrowserDialog(
			object ownerViewModel,
			FolderBrowserDialogViewModel viewModel)
		{
			// Create FolderBrowserDialog with specified ViewModel
			FolderBrowserDialog dialog = new FolderBrowserDialog(viewModel);

			// Show dialog
			return dialog.ShowDialog(new WindowWrapper(FindOwnerWindow(ownerViewModel)));
		}

		#endregion


		#region Attached properties

		/// <summary>
		/// Attached property describing whether a FrameworkElement is acting as a View in MVVM.
		/// </summary>
		public static readonly DependencyProperty IsRegisteredViewProperty =
			DependencyProperty.RegisterAttached(
			"IsRegisteredView",
			typeof(bool),
			typeof(DialogService),
			new UIPropertyMetadata(IsRegisteredViewPropertyChanged));


		/// <summary>
		/// Gets value describing whether FrameworkElement is acting as View in MVVM.
		/// </summary>
		public static bool GetIsRegisteredView(FrameworkElement target)
		{
			return (bool)target.GetValue(IsRegisteredViewProperty);
		}


		/// <summary>
		/// Sets value describing whether FrameworkElement is acting as View in MVVM.
		/// </summary>
		public static void SetIsRegisteredView(FrameworkElement target, bool value)
		{
			target.SetValue(IsRegisteredViewProperty, value);
		}


		/// <summary>
		/// Is responsible for handling IsRegisteredViewProperty changes, i.e. whether
		/// FrameworkElement is acting as View in MVVM or not.
		/// </summary>
		private static void IsRegisteredViewPropertyChanged(
			DependencyObject target,
			DependencyPropertyChangedEventArgs e)
		{
			// The Visual Studio Designer or Blend will run this code when setting the attached
			// property, however at that point there is no IDialogService registered
			// in the ServiceLocator which will cause the Resolve method to throw a ArgumentException.
			if (DesignerProperties.GetIsInDesignMode(target)) return;

			FrameworkElement view = target as FrameworkElement;
			if (view != null)
			{
				// Cast values
				bool newValue = (bool)e.NewValue;
				bool oldValue = (bool)e.OldValue;

				if (newValue)
				{
					ServiceLocator.Resolve<IDialogService>().Register(view);
				}
				else
				{
					ServiceLocator.Resolve<IDialogService>().Unregister(view);
				}
			}
		}

		#endregion


		/// <summary>
		/// Finds window corresponding to specified ViewModel.
		/// </summary>
		private Window FindOwnerWindow(object viewModel)
		{
			FrameworkElement view = views.SingleOrDefault(v => ReferenceEquals(v.DataContext, viewModel));
			if (view == null)
			{
				throw new ArgumentException("Viewmodel is not referenced by any registered View.");
			}

			// Get owner window
			Window owner = view as Window;
			if (owner == null)
			{
				owner = Window.GetWindow(view);
			}

			// Make sure owner window was found
			if (owner == null)
			{
				throw new InvalidOperationException("View is not contained within a Window.");
			}

			return owner;
		}


		/// <summary>
		/// Handles owner window closed, View service should then unregister all Views acting within
		/// the closed window.
		/// </summary>
		private void OwnerClosed(object sender, EventArgs e)
		{
			Window owner = sender as Window;
			if (owner != null)
			{
				// Find Views acting within closed window
				IEnumerable<FrameworkElement> windowViews =
					from view in views
					where Window.GetWindow(view) == owner
					select view;

				// Unregister Views in window
				foreach (FrameworkElement view in windowViews.ToArray())
				{
					Unregister(view);
				}
			}
		}
	}
}

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
Software Developer Axis Communications
Sweden Sweden
Got my first computer in the 90's and loved it even though it sounded like a coffeemaker.

Now getting paid for designing cool applications, and drinks the coffee instead of listening to it being made.

Comments and Discussions