/Blocks/Configuration/Src/Design/ViewModel/ValidationModel.cs
C# | 253 lines | 183 code | 36 blank | 34 comment | 21 complexity | 3a50b6fe8b560c68af916e7bd0bc9f88 MD5 | raw file
- //===============================================================================
- // Microsoft patterns & practices Enterprise Library
- // Core
- //===============================================================================
- // Copyright Š Microsoft Corporation. All rights reserved.
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
- // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
- // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- // FITNESS FOR A PARTICULAR PURPOSE.
- //===============================================================================
-
- using System;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- using System.Configuration;
- using System.Windows.Input;
- using Microsoft.Practices.EnterpriseLibrary.Configuration.Design.Validation;
- using Microsoft.Practices.EnterpriseLibrary.Configuration.Design.ViewModel.Services;
- using Microsoft.Practices.Unity.Utility;
-
- namespace Microsoft.Practices.EnterpriseLibrary.Configuration.Design.ViewModel
- {
- /// <summary>
- /// The <see cref="ValidationModel"/> tracks all <see cref="ValidationResult"/> instances
- /// by elements in <see cref="ElementLookup"/>.
- /// </summary>
- /// <remarks>
- /// The <see cref="ValidationModel"/> monitors changes in <see cref="ElementLookup"/> and as new <see cref="ElementViewModel"/> are
- /// added begins montoring their <see cref="ElementViewModel.ValidationResults"/> and their properties' validation results.
- /// <br/>
- /// As results are added or removed for each element, this model keeps this list up-to-date for display in the design-time user interface.
- /// </remarks>
- public class ValidationModel
- {
- private readonly ElementLookup lookup;
- private readonly CompositeValidationResultsCollection resultsCollection = new CompositeValidationResultsCollection();
- private readonly NavigateValidationResultCommand navigateValidationResultCommand;
- private readonly List<ElementViewModel> elementsMonitored = new List<ElementViewModel>();
- private bool populating = false;
-
- ///<summary>
- /// Initializes a new instance of <see cref="ValidationModel"/>.
- ///</summary>
- ///<param name="lookup">The element loookup service to use for monitoring the addition and removal of <see cref="ElementViewModel"/> items.</param>
- public ValidationModel(ElementLookup lookup)
- {
- this.lookup = lookup;
- this.navigateValidationResultCommand = new NavigateValidationResultCommand(this);
- ResetCollection();
- lookup.CollectionChanged += ElementsChanged;
- }
-
- private void ElementsChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- if (e.Action == NotifyCollectionChangedAction.Add)
- {
- foreach (var item in e.NewItems)
- {
- var elementViewModel = item as ElementViewModel;
- if (elementViewModel == null) continue;
- AddElementResultsCollections(elementViewModel);
- }
- }
-
- if (e.Action == NotifyCollectionChangedAction.Remove)
- {
- foreach (var item in e.OldItems)
- {
- var elementViewModel = item as ElementViewModel;
- if (elementViewModel == null) continue;
- RemoveElementResultsCollections(elementViewModel);
- }
- }
- if (e.Action == NotifyCollectionChangedAction.Reset)
- {
- ResetCollection();
- }
- }
-
- private void ResetCollection()
- {
- resultsCollection.NotifyEnabled = false;
- ClearElementsMonitored();
- resultsCollection.Clear();
- PopulateCollection();
- resultsCollection.NotifyEnabled = true;
- }
-
- private void PopulateCollection()
- {
- populating = true;
-
- foreach (var section in lookup.FindInstancesOfConfigurationType(typeof(ConfigurationSection)))
- {
- AddElementResultsCollections(section);
- }
-
- populating = false;
- }
-
- private void RemoveElementResultsCollections(ElementViewModel element)
- {
- resultsCollection.Remove(element.ValidationResults);
-
- foreach (var prop in element.Properties)
- {
- resultsCollection.Remove(prop.ValidationResults);
- }
-
- foreach (var child in element.ChildElements)
- {
- RemoveElementResultsCollections(child);
- }
-
- RemoveElementPropertyMonitoring(element);
-
- }
-
- private void AddElementResultsCollections(ElementViewModel element)
- {
- resultsCollection.Add(element.ValidationResults);
-
- foreach (var prop in element.Properties)
- {
- resultsCollection.Add(prop.ValidationResults);
- }
-
- foreach (var child in element.ChildElements)
- {
- AddElementResultsCollections(child);
- }
-
- AddElementPropertyMonitoring(element);
- }
-
- /// <summary>
- /// Orientates the designer to the configuration element associated with the given <see cref="ValidationResult"/>.
- /// </summary>
- /// <param name="validationResult">The <see cref="ValidationResult"/> that should be navigated to.</param>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods", Justification = "Validated with Guard class")]
- public void Navigate(ValidationResult validationResult)
- {
- Guard.ArgumentNotNull(validationResult, "validationResult");
-
- var elementWithError = lookup.GetElementById(validationResult.ElementId);
- if (elementWithError != null)
- {
- if (!(elementWithError is SectionViewModel))
- {
- elementWithError.ContainingSection.ExpandSection();
- }
- elementWithError.PropertiesShown = true;
- elementWithError.Select();
- }
- }
-
- /// <summary>
- /// Provides an <see cref="ICommand"/> implementation that allows to execute the <see cref="ValidationModel.Navigate"/> method from within XAML.
- /// </summary>
- public ICommand NavigateCommand
- {
- get { return this.navigateValidationResultCommand; }
- }
-
- ///<summary>
- /// Gets the set of validation results collected from all elements.
- ///</summary>
- public IEnumerable<ValidationResult> ValidationResults
- {
- get { return resultsCollection; }
- }
-
- private void RemoveElementPropertyMonitoring(ElementViewModel element)
- {
- this.elementsMonitored.Remove(element);
- element.Properties.CollectionChanged -= ElementPropertiesCollectionChangedHandler;
- }
-
- private void AddElementPropertyMonitoring(ElementViewModel element)
- {
- if (!elementsMonitored.Contains(element))
- {
- this.elementsMonitored.Add(element);
- element.Properties.CollectionChanged += ElementPropertiesCollectionChangedHandler;
- }
- }
-
-
- private void ClearElementsMonitored()
- {
- foreach (var element in elementsMonitored)
- {
- element.Properties.CollectionChanged -= ElementPropertiesCollectionChangedHandler;
- }
-
- elementsMonitored.Clear();
- }
-
- private void ElementPropertiesCollectionChangedHandler(object sender, NotifyCollectionChangedEventArgs e)
- {
- if (populating) return;
-
- if (e.Action == NotifyCollectionChangedAction.Reset)
- {
- ResetCollection();
- }
- else
- {
- if (e.OldItems != null)
- {
- foreach (var oldItem in e.OldItems)
- {
- resultsCollection.Remove(((Property)oldItem).ValidationResults);
- }
- }
-
- if (e.NewItems != null)
- {
- foreach (var newItem in e.NewItems)
- {
- resultsCollection.Add(((Property)newItem).ValidationResults);
- }
- }
- }
- }
-
- private class NavigateValidationResultCommand : ICommand
- {
- private readonly ValidationModel validationModel;
-
- public NavigateValidationResultCommand(ValidationModel validationModel)
- {
- this.validationModel = validationModel;
- }
-
- public bool CanExecute(object parameter)
- {
- return parameter is ValidationResult;
- }
-
- #pragma warning disable 67
- public event EventHandler CanExecuteChanged;
- #pragma warning restore 67
-
- public void Execute(object parameter)
- {
- ValidationResult result = (ValidationResult)parameter;
- validationModel.Navigate(result);
- }
- }
-
- }
- }