Mercurial > silverbladetech
changeset 96:188f8b366e87
Unit test project correctly setup as normal class library DLL.
line wrap: on
line diff
Binary file SilverlightValidation/Libs/Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight.dll has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.PL/Commands/RelayCommand.cs Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,40 @@ +using System; +using System.Windows.Input; + +namespace SilverlightValidation.Commands +{ + public class RelayCommand : ICommand + { + public event EventHandler CanExecuteChanged = delegate { }; + + readonly Action<object> _execute; + readonly Predicate<object> _canExecute; + + public RelayCommand(Action<object> execute, + Predicate<object> canExecute = null) + { + if (execute == null) throw new ArgumentNullException("execute"); + + _execute = execute; + _canExecute = canExecute; + } + + + public void UpdateCanExecuteCommand() + { + CanExecuteChanged(this, new EventArgs()); + } + + + public bool CanExecute(object parameter) + { + return _canExecute == null || _canExecute(parameter); + } + + + public void Execute(object parameter) + { + _execute(parameter); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.PL/Data/Factory.cs Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using SilverlightValidation.Models; + +namespace SilverlightValidation.Data +{ + public class Factory + { + public static IList<UserModel> CreateUserModels() + { + return new List<UserModel>(5) + { + new UserModel() { Username = "StevenH", Password = "Password1", Email = "steven@hotmail.com", DateOfBirth = new DateTime(1977, 09, 01), Description = ""}, + new UserModel() { Username = "RichardJ", Password = "12N456a", Email = "dicky@gmail.com", DateOfBirth = new DateTime(1983, 03, 13), Description = "Loves .Net!"}, + new UserModel() { Username = "BobbyP", Password = "pa33Word", Email = "bob@yahoo.co.uk", DateOfBirth = new DateTime(1992, 08, 30), Description = ""}, + new UserModel() { Username = "DavidM", Password = "poIu789", Email = "daveyboy@marsh.com", DateOfBirth = new DateTime(1965, 06, 21), Description = "Java fan boy"}, + new UserModel() { Username = "JessieJ", Password = "jlkJh567", Email = "jj@apple.co.uk", DateOfBirth = new DateTime(1990, 10, 15), Description = ""} + }; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.PL/Diagrams/Overview.cd Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8"?> +<ClassDiagram MajorVersion="1" MinorVersion="1"> + <Class Name="SilverlightValidation.Models.UserModel"> + <Position X="2.5" Y="1.75" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAAAAAAACAgAAAAAQAAAAAAAAAQAEACAAAAAAAAABA=</HashCode> + <FileName>Models\UserModel.cs</FileName> + </TypeIdentifier> + <Lollipop Position="0.2" /> + </Class> + <Class Name="SilverlightValidation.Validators.UserModelValidator" Collapsed="true"> + <Position X="2" Y="7.75" Width="2" /> + <TypeIdentifier> + <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAA=</HashCode> + <FileName>Validators\UserModelValidator.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="SilverlightValidation.ViewModels.UserListViewModel"> + <Position X="6.25" Y="5.5" Width="2.75" /> + <TypeIdentifier> + <HashCode>AAAAAAAAAAAAAAECAAAAAAAAAAAAABAYABEACAAAAAA=</HashCode> + <FileName>ViewModels\UserListViewModel.cs</FileName> + </TypeIdentifier> + </Class> + <Class Name="SilverlightValidation.ViewModels.UserViewModel"> + <Position X="4.25" Y="1.75" Width="1.75" /> + <TypeIdentifier> + <HashCode>UAAAoIAADCIgAAAAMYAACAAAAAAQABAKQEAAAAAgIAA=</HashCode> + <FileName>ViewModels\UserViewModel.cs</FileName> + </TypeIdentifier> + <Lollipop Position="0.2" /> + </Class> + <Class Name="SilverlightValidation.ViewModels.ViewModelBase"> + <Position X="6.25" Y="1.75" Width="2.75" /> + <TypeIdentifier> + <HashCode>AAAAAAACAABQAAABAAAAAgAAgAAAAACIAAAAAAARAAA=</HashCode> + <FileName>ViewModels\ViewModelBase.cs</FileName> + </TypeIdentifier> + <Lollipop Position="0.2" /> + </Class> + <Class Name="SilverlightValidation.Messages.UserViewResponseMessage"> + <Position X="9.25" Y="5" Width="2.25" /> + <TypeIdentifier> + <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAA=</HashCode> + <FileName>Messages\UserViewResponseMessage.cs</FileName> + </TypeIdentifier> + </Class> + <Interface Name="SilverlightValidation.Interfaces.ICloneable<T>"> + <Position X="2.5" Y="4.5" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABA=</HashCode> + <FileName>Interfaces\ICloneable.cs</FileName> + </TypeIdentifier> + </Interface> + <Interface Name="SilverlightValidation.Interfaces.IUserModel"> + <Position X="2.5" Y="5.75" Width="1.5" /> + <TypeIdentifier> + <HashCode>AAAAAAAAACAgAAAAAQAAAAAAAAAQAAACAAAAAAAAAAA=</HashCode> + <FileName>Interfaces\IUserModel.cs</FileName> + </TypeIdentifier> + </Interface> + <Font Name="Segoe UI" Size="9" /> +</ClassDiagram> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.PL/Interfaces/ICloneable.cs Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,7 @@ +namespace SilverlightValidation.Interfaces +{ + public interface ICloneable<T> + { + T Clone(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.PL/Interfaces/IUserModel.cs Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,12 @@ +using System; +namespace SilverlightValidation.Interfaces +{ + public interface IUserModel + { + string Username { get; set; } + string Email { get; set; } + string Password { get; set; } + DateTime? DateOfBirth { get; set; } + string Description { get; set; } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.PL/Messages/UserViewResponseMessage.cs Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,10 @@ +using GalaSoft.MvvmLight.Messaging; +using SilverlightValidation.ViewModels; + +namespace SilverlightValidation.Messages +{ + public class UserViewResponseMessage : MessageBase + { + public UserViewModel UserViewModel { get; set; } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.PL/Models/UserModel.cs Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,25 @@ +using System; +using System.ComponentModel; +using SilverlightValidation.Interfaces; + +namespace SilverlightValidation.Models +{ + public class UserModel : IUserModel, ICloneable<UserModel> + { + public string Username { get; set; } + public string Email { get; set; } + public string Password { get; set; } + public DateTime? DateOfBirth { get; set; } + public string Description { get; set; } + + public static UserModel Create() + { + return new UserModel() { Username = "", Email = "", Password = "", DateOfBirth = null, Description = "" }; + } + + public UserModel Clone() + { + return (UserModel) this.MemberwiseClone(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.PL/Properties/AssemblyInfo.cs Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("SilverlightValidation.PL")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SilverlightValidation.PL")] +[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f669b434-6d0f-48d5-917b-00c92d4ccfee")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.PL/SilverlightValidation.PL.csproj Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{13B5F568-F402-4A2A-9A23-0FDF0B5564E3}</ProjectGuid> + <ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>SilverlightValidation.PL</RootNamespace> + <AssemblyName>SilverlightValidation.PL</AssemblyName> + <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier> + <TargetFrameworkVersion>v5.0</TargetFrameworkVersion> + <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion> + <SilverlightApplication>false</SilverlightApplication> + <ValidateXaml>true</ValidateXaml> + <ThrowErrorsInValidation>true</ThrowErrorsInValidation> + </PropertyGroup> + <!-- This property group is only here to support building this project using the + MSBuild 3.5 toolset. In order to work correctly with this older toolset, it needs + to set the TargetFrameworkVersion to v3.5 --> + <PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'"> + <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>Bin\Debug</OutputPath> + <DefineConstants>DEBUG;TRACE;SILVERLIGHT</DefineConstants> + <NoStdLib>true</NoStdLib> + <NoConfig>true</NoConfig> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>Bin\Release</OutputPath> + <DefineConstants>TRACE;SILVERLIGHT</DefineConstants> + <NoStdLib>true</NoStdLib> + <NoConfig>true</NoConfig> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="FluentValidation"> + <HintPath>..\Libs\FluentValidation.dll</HintPath> + </Reference> + <Reference Include="GalaSoft.MvvmLight.SL5, Version=4.0.21.32885, Culture=neutral, PublicKeyToken=c114982fcf1a3a2e, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\Libs\GalaSoft.MvvmLight.SL5.dll</HintPath> + </Reference> + <Reference Include="mscorlib" /> + <Reference Include="System.Windows" /> + <Reference Include="system" /> + <Reference Include="System.Core" /> + <Reference Include="System.Windows.Controls, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\Libs\System.Windows.Controls.dll</HintPath> + </Reference> + <Reference Include="System.Windows.Controls.Navigation, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> + <HintPath>..\Libs\System.Windows.Controls.Navigation.dll</HintPath> + </Reference> + </ItemGroup> + <ItemGroup> + <Compile Include="Commands\RelayCommand.cs" /> + <Compile Include="Data\Factory.cs" /> + <Compile Include="Interfaces\ICloneable.cs" /> + <Compile Include="Interfaces\IUserModel.cs" /> + <Compile Include="Messages\UserViewResponseMessage.cs" /> + <Compile Include="Models\UserModel.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Validators\UserModelValidator.cs" /> + <Compile Include="ViewModels\UserListViewModel.cs" /> + <Compile Include="ViewModels\UserViewModel.cs" /> + <Compile Include="ViewModels\ViewModelBase.cs" /> + </ItemGroup> + <ItemGroup> + <None Include="Diagrams\Overview.cd" /> + </ItemGroup> + <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" /> + <ProjectExtensions> + <VisualStudio> + <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}"> + <SilverlightProjectProperties /> + </FlavorProperties> + </VisualStudio> + </ProjectExtensions> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.PL/Validators/UserModelValidator.cs Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,36 @@ +using System; +using FluentValidation; +using SilverlightValidation.Interfaces; + +namespace SilverlightValidation.Validators +{ + public class UserModelValidator : AbstractValidator<IUserModel> + { + public UserModelValidator() + { + RuleFor(x => x.Username) + .Length(3, 8) + .WithMessage("Must be between 3-8 characters."); + + RuleFor(x => x.Password) + .Matches(@"^\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*$") + .WithMessage("Must contain lower, upper and numeric chars."); + + RuleFor(x => x.Email) + .EmailAddress() + .WithMessage("A valid email address is required."); + + RuleFor(x => x.DateOfBirth) + .Must(BeAValidDateOfBirth) + .WithMessage("Must be within 100 years of today."); + } + + private bool BeAValidDateOfBirth(DateTime? dateOfBirth) + { + if (dateOfBirth == null) return false; + if (dateOfBirth.Value > DateTime.Today || dateOfBirth < DateTime.Today.AddYears(-100)) + return false; + return true; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.PL/ViewModels/UserListViewModel.cs Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,65 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Windows.Controls; +using System.Windows.Input; +using SilverlightValidation.Commands; +using SilverlightValidation.Models; +using SilverlightValidation.Validators; +using GalaSoft.MvvmLight.Messaging; +using SilverlightValidation.Messages; + +namespace SilverlightValidation.ViewModels +{ + public class UserListViewModel + { + private ChildWindow _window; + + public UserListViewModel(ChildWindow window, IList<UserModel> models, UserModelValidator validator) + { + _window = window; + + Data = new ObservableCollection<UserViewModel>(); + + foreach (var model in models) + Data.Add(new UserViewModel(model, validator)); + + AddCommand = new RelayCommand(AddCommandExecute); + DeleteCommand = new RelayCommand(DeleteCommandExecute); + + Messenger.Default.Register<UserViewResponseMessage>(this, UserViewResponseMessageReceived); + } + + private void UserViewResponseMessageReceived(UserViewResponseMessage userViewResponseMessage) + { + if (userViewResponseMessage.UserViewModel != null) + Data.Add(userViewResponseMessage.UserViewModel); + _window.Close(); + } + + #region Properties + + public ObservableCollection<UserViewModel> Data { get; set; } + + public UserViewModel SelectedItem { get; set; } + + #endregion + + #region Commands + + public ICommand AddCommand { get; set; } + public ICommand DeleteCommand { get; set; } + + private void AddCommandExecute(object obj) + { + _window.Show(); + } + + private void DeleteCommandExecute(object obj) + { + if (SelectedItem!=null) + Data.Remove(SelectedItem); + } + + #endregion + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.PL/ViewModels/UserViewModel.cs Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,223 @@ +using System; +using System.ComponentModel; +using System.Linq; +using System.Windows; +using System.Windows.Input; +using FluentValidation; +using SilverlightValidation.Interfaces; +using SilverlightValidation.Validators; +using SilverlightValidation.Models; +using SilverlightValidation.Commands; +using GalaSoft.MvvmLight.Messaging; +using SilverlightValidation.Messages; + +namespace SilverlightValidation.ViewModels +{ + public class UserViewModel : ViewModelBase, IUserModel, IEditableObject + { + #region Fields + + private readonly UserModelValidator _validator; + private UserModel _data; + private UserModel _backup; + + #endregion + + #region Constructor + + public UserViewModel(UserModel model, UserModelValidator validator) + { + _validator = validator; + _data = model; + _backup = model.Clone(); + + OkCommand = new RelayCommand(OkCommandExecute); + CancelCommand = new RelayCommand(CancelCommandExecute); + } + + #endregion + + #region Methods + + private void SetProperties(IUserModel source) + { + _data.Username = source.Username; + _data.Password = source.Password; + _data.Email = source.Email; + _data.DateOfBirth = source.DateOfBirth; + _data.Description = source.Description; + } + + #endregion + + #region Properties + + private const string UsernameProperty = "Username"; + public string Username + { + get { return _data.Username; } + set + { + if (_data.Username != value) + { + _data.Username = value; + RaisePropertyChanged(UsernameProperty); + IsChanged = true; + } + + ClearError(UsernameProperty); + var validationResult = _validator.Validate(this, UsernameProperty); + if (!validationResult.IsValid) + validationResult.Errors.ToList().ForEach(x => SetError(UsernameProperty, x.ErrorMessage)); + } + } + + private const string PasswordProperty = "Password"; + public string Password + { + get { return _data.Password; } + set + { + if (_data.Password != value) + { + _data.Password = value; + RaisePropertyChanged(PasswordProperty); + IsChanged = true; + } + + ClearError(PasswordProperty); + var validationResult = _validator.Validate(this, PasswordProperty); + if (!validationResult.IsValid) + validationResult.Errors.ToList().ForEach(x => SetError(PasswordProperty, x.ErrorMessage)); + } + } + + private const string EmailProperty = "Email"; + public string Email + { + get { return _data.Email; } + set + { + if (_data.Email != value) + { + _data.Email = value; + RaisePropertyChanged(EmailProperty); + IsChanged = true; + } + + ClearError(EmailProperty); + var validationResult = _validator.Validate(this, EmailProperty); + if (!validationResult.IsValid) + validationResult.Errors.ToList().ForEach(x => SetError(EmailProperty, x.ErrorMessage)); + } + } + + private const string DateOfBirthProperty = "DateOfBirth"; + public DateTime? DateOfBirth + { + get { return _data.DateOfBirth; } + set + { + if (_data.DateOfBirth != value) + { + _data.DateOfBirth = value; + RaisePropertyChanged(DateOfBirthProperty); + IsChanged = true; + } + + ClearError(DateOfBirthProperty); + var validationResult = _validator.Validate(this, DateOfBirthProperty); + if (!validationResult.IsValid) + validationResult.Errors.ToList().ForEach(x => SetError(DateOfBirthProperty, x.ErrorMessage)); + } + } + + private const string DescriptionProperty = "Description"; + public string Description + { + get { return _data.Description; } + set + { + if (_data.Description != value) + { + _data.Description = value; + RaisePropertyChanged(DescriptionProperty); + IsChanged = true; + } + + ClearError(DescriptionProperty); + var validationResult = _validator.Validate(this, DescriptionProperty); + if (!validationResult.IsValid) + validationResult.Errors.ToList().ForEach(x => SetError(DescriptionProperty, x.ErrorMessage)); + } + } + + #endregion + + #region Commands + + public ICommand OkCommand { get; set; } + public ICommand CancelCommand { get; set; } + + private void OkCommandExecute(object obj) + { + RefreshToViewErrors(); + + if (IsChanged && !HasErrors) + { + // save here + Messenger.Default.Send<UserViewResponseMessage>( + new UserViewResponseMessage() { UserViewModel = this }); + } + } + + // in case user hasn't touched the form + private void RefreshToViewErrors() + { + Username = _data.Username; + Password = _data.Password; + Email = _data.Email; + DateOfBirth = _data.DateOfBirth; + } + + private void CancelCommandExecute(object obj) + { + Messenger.Default.Send<UserViewResponseMessage>( + new UserViewResponseMessage() { UserViewModel = null }); + } + + #endregion + + private void ResetFormData() + { + SetProperties(_backup); + ClearAllErrors(); + IsChanged = false; + } + + public bool IsChanged { get; private set; } + + #region IEditableObject for datagrid + + private bool inEdit; + public void BeginEdit() + { + if (inEdit) return; + inEdit = true; + } + + public void CancelEdit() + { + if (!inEdit) return; + inEdit = false; + ResetFormData(); + } + + public void EndEdit() + { + if (!inEdit) return; + } + + #endregion + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.PL/ViewModels/ViewModelBase.cs Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,73 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; + +namespace SilverlightValidation.ViewModels +{ + public class ViewModelBase : INotifyPropertyChanged, INotifyDataErrorInfo + { + #region INotifyPropertyChanged method plus event + + public event PropertyChangedEventHandler PropertyChanged = delegate { }; + + protected void RaisePropertyChanged(string propertyName) + { + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + + #endregion + + #region INotifyDataErrorInfo methods and helpers + + private readonly Dictionary<string, List<string>> _errors = new Dictionary<string, List<string>>(); + + public void SetError(string propertyName, string errorMessage) + { + if (!_errors.ContainsKey(propertyName)) + _errors.Add(propertyName, new List<string> { errorMessage }); + + RaiseErrorsChanged(propertyName); + } + + protected void ClearError(string propertyName) + { + if (_errors.ContainsKey(propertyName)) + { + _errors.Remove(propertyName); + RaiseErrorsChanged(propertyName); + } + } + + protected void ClearAllErrors() + { + var errors = _errors.Select(error => error.Key).ToList(); + + foreach (var propertyName in errors) + ClearError(propertyName); + } + + public void RaiseErrorsChanged(string propertyName) + { + ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName)); + } + + public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged = delegate { }; + + public IEnumerable GetErrors(string propertyName) + { + if (propertyName == null) return null; + return _errors.ContainsKey(propertyName) + ? _errors[propertyName] + : null; + } + + public bool HasErrors + { + get { return _errors.Count > 0; } + } + + #endregion + } +}
--- a/SilverlightValidation/SilverlightValidation.Tests/Properties/AppManifest.xml Sat May 05 11:07:41 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" - xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" -> - <Deployment.Parts> - </Deployment.Parts> - -</Deployment>
--- a/SilverlightValidation/SilverlightValidation.Tests/Properties/AssemblyInfo.cs Sat May 05 11:07:41 2012 +0100 +++ b/SilverlightValidation/SilverlightValidation.Tests/Properties/AssemblyInfo.cs Sat May 05 13:29:56 2012 +0100 @@ -1,6 +1,4 @@ -// Copyright © 2012 - -using System.Reflection; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -22,7 +20,7 @@ [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("1196b633-7f87-485e-bd47-f3d2943a59e4")] +[assembly: Guid("843ea0ec-635f-4592-b3e6-5893be73bc5e")] // Version information for an assembly consists of the following four values: // @@ -31,7 +29,8 @@ // Build Number // Revision // -// You can specify all the values or you can default the Revision and Build Numbers +// You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file +[assembly: AssemblyFileVersion("1.0.0.0")]
--- a/SilverlightValidation/SilverlightValidation.Tests/SilverlightValidation.Tests.csproj Sat May 05 11:07:41 2012 +0100 +++ b/SilverlightValidation/SilverlightValidation.Tests/SilverlightValidation.Tests.csproj Sat May 05 13:29:56 2012 +0100 @@ -3,124 +3,59 @@ <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <ProductVersion>9.0.30729</ProductVersion> + <ProductVersion>8.0.30703</ProductVersion> <SchemaVersion>2.0</SchemaVersion> - <ProjectGuid>{12AE7560-AD64-4635-8A6B-772256FF0EDD}</ProjectGuid> - <ProjectTypeGuids>{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids> + <ProjectGuid>{02CCF8C7-1311-453F-BF82-3564AD9E7B8C}</ProjectGuid> <OutputType>Library</OutputType> <AppDesignerFolder>Properties</AppDesignerFolder> <RootNamespace>SilverlightValidation.Tests</RootNamespace> <AssemblyName>SilverlightValidation.Tests</AssemblyName> - <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier> - <TargetFrameworkVersion>v5.0</TargetFrameworkVersion> - <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion> - <SilverlightApplication>true</SilverlightApplication> - <SupportedCultures /> - <XapOutputs>true</XapOutputs> - <GenerateSilverlightManifest>true</GenerateSilverlightManifest> - <XapFilename>SilverlightValidation.Tests.xap</XapFilename> - <SilverlightManifestTemplate>Properties\AppManifest.xml</SilverlightManifestTemplate> - <SilverlightAppEntry>SilverlightValidation.Tests.App</SilverlightAppEntry> - <TestPageFileName>TestPage.html</TestPageFileName> - <CreateTestPage>true</CreateTestPage> - <ValidateXaml>true</ValidateXaml> - <EnableOutOfBrowser>false</EnableOutOfBrowser> - <OutOfBrowserSettingsFile>Properties\OutOfBrowserSettings.xml</OutOfBrowserSettingsFile> - <UsePlatformExtensions>false</UsePlatformExtensions> - <ThrowErrorsInValidation>true</ThrowErrorsInValidation> - <LinkedServerProject /> - </PropertyGroup> - <!-- - // - // Silverlight Code Coverage Instrumentation - // List any libraries or assemblies that you would like to instrument during - // a code coverage pass. An example, for ClassLibrary1, is provided, and - // commented out below as a starting point: - // - --> - <!-- - <ItemGroup> - <InstrumentSilverlightAssemblies Include="SilverlightClassLibrary1"> - <Visible>false</Visible> - </InstrumentSilverlightAssemblies> - </ItemGroup> - --> - <!-- This property group is only here to support building this project using the - MSBuild 3.5 toolset. In order to work correctly with this older toolset, it needs - to set the TargetFrameworkVersion to v3.5 --> - <PropertyGroup Condition="'$(MSBuildToolsVersion)' == '3.5'"> - <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> + <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> <DebugType>full</DebugType> <Optimize>false</Optimize> - <OutputPath>Bin\Debug</OutputPath> - <DefineConstants>DEBUG;TRACE;SILVERLIGHT</DefineConstants> - <NoStdLib>true</NoStdLib> - <NoConfig>true</NoConfig> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <DebugType>pdbonly</DebugType> <Optimize>true</Optimize> - <OutputPath>Bin\Release</OutputPath> - <DefineConstants>TRACE;SILVERLIGHT</DefineConstants> - <NoStdLib>true</NoStdLib> - <NoConfig>true</NoConfig> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> </PropertyGroup> <ItemGroup> - <Reference Include="Microsoft.Silverlight.Testing"> - <HintPath>..\Libs\Microsoft.Silverlight.Testing.dll</HintPath> - </Reference> - <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight"> - <HintPath>..\Libs\Microsoft.VisualStudio.QualityTools.UnitTesting.Silverlight.dll</HintPath> - </Reference> - <Reference Include="NUnit.Silverlight.Compatibility"> - <HintPath>..\Libs\NUnit.Silverlight.Compatibility.dll</HintPath> + <Reference Include="nunit.framework, Version=2.6.0.12051, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL"> + <HintPath>..\packages\NUnit.2.6.0.12054\lib\nunit.framework.dll</HintPath> </Reference> - <Reference Include="NUnit.Silverlight.Framework"> - <HintPath>..\Libs\NUnit.Silverlight.Framework.dll</HintPath> - </Reference> - <Reference Include="NUnit.Silverlight.Metadata"> - <HintPath>..\Libs\NUnit.Silverlight.Metadata.dll</HintPath> - </Reference> - <Reference Include="System.Windows" /> - <Reference Include="mscorlib" /> - <Reference Include="system" /> + <Reference Include="System" /> <Reference Include="System.Core" /> - <Reference Include="System.Net" /> + <Reference Include="System.Xml.Linq" /> + <Reference Include="System.Data.DataSetExtensions" /> + <Reference Include="Microsoft.CSharp" /> + <Reference Include="System.Data" /> <Reference Include="System.Xml" /> - <Reference Include="System.Windows.Browser" /> </ItemGroup> <ItemGroup> + <Compile Include="ViewModels\UserListViewModelTests.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="ViewModels\UserListViewModel.cs" /> - <Compile Include="ViewModels\UserViewModel.cs" /> - </ItemGroup> - <ItemGroup> - <None Include="Properties\AppManifest.xml" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\SilverlightValidation\SilverlightValidation.csproj"> - <Project>{0C1CC1FC-915A-4428-8952-CDC79EABC3F4}</Project> - <Name>SilverlightValidation</Name> - </ProjectReference> + <Compile Include="ViewModels\UserViewModelTests.cs" /> </ItemGroup> <ItemGroup> - <Folder Include="Validators\" /> + <None Include="packages.config" /> </ItemGroup> - <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" /> - <Import Condition="$(SilverlightVersion)=='v3.0'" Project="$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SilverlightToolkit\Tools\v3.0)Microsoft.Silverlight.Toolkit.Build.targets" /> - <Import Condition="$(SilverlightVersion)=='v4.0'" Project="$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SilverlightToolkit\Tools\v4.0)Microsoft.Silverlight.Toolkit.Build.targets" /> - <ProjectExtensions> - <VisualStudio> - <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}"> - <SilverlightProjectProperties /> - </FlavorProperties> - </VisualStudio> - </ProjectExtensions> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> </Project> \ No newline at end of file
--- a/SilverlightValidation/SilverlightValidation.Tests/ViewModels/UserListViewModel.cs Sat May 05 11:07:41 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ - -using NUnit.Framework; - -namespace SilverlightValidation.Tests.ViewModels -{ - [TestFixture] - public class UserListViewModelTests - { - [Test] - public void Given_When_Then() - { - Assert.True(true); - } - } -} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.Tests/ViewModels/UserListViewModelTests.cs Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,15 @@ +using System; +using NUnit.Framework; + +namespace SilverlightValidation.Tests.ViewModels +{ + [TestFixture] + class UserListViewModelTests + { + [Test] + public void Given_When_Then() + { + Assert.True(true); + } + } +}
--- a/SilverlightValidation/SilverlightValidation.Tests/ViewModels/UserViewModel.cs Sat May 05 11:07:41 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ - -using NUnit.Framework; - -namespace SilverlightValidation.Tests.ViewModels -{ - [TestFixture] - public class UserViewModelTests - { - [Test] - public void Given_When_Then() - { - Assert.True(true); - } - } -} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.Tests/ViewModels/UserViewModelTests.cs Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,14 @@ +using NUnit.Framework; + +namespace SilverlightValidation.Tests.ViewModels +{ + [TestFixture] + class UserViewModelTests + { + [Test] + public void Given_When_Then() + { + Assert.True(true); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SilverlightValidation/SilverlightValidation.Tests/packages.config Sat May 05 13:29:56 2012 +0100 @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<packages> + <package id="NUnit" version="2.6.0.12054" /> +</packages> \ No newline at end of file
--- a/SilverlightValidation/SilverlightValidation.sln Sat May 05 11:07:41 2012 +0100 +++ b/SilverlightValidation/SilverlightValidation.sln Sat May 05 13:29:56 2012 +0100 @@ -5,7 +5,9 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SilverlightValidation.Web", "SilverlightValidation.Web\SilverlightValidation.Web.csproj", "{E65C6757-932B-4D01-9A8A-6D02F8FAA25A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SilverlightValidation.Tests", "SilverlightValidation.Tests\SilverlightValidation.Tests.csproj", "{12AE7560-AD64-4635-8A6B-772256FF0EDD}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SilverlightValidation.PL", "SilverlightValidation.PL\SilverlightValidation.PL.csproj", "{13B5F568-F402-4A2A-9A23-0FDF0B5564E3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SilverlightValidation.Tests", "SilverlightValidation.Tests\SilverlightValidation.Tests.csproj", "{02CCF8C7-1311-453F-BF82-3564AD9E7B8C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -21,10 +23,14 @@ {E65C6757-932B-4D01-9A8A-6D02F8FAA25A}.Debug|Any CPU.Build.0 = Debug|Any CPU {E65C6757-932B-4D01-9A8A-6D02F8FAA25A}.Release|Any CPU.ActiveCfg = Release|Any CPU {E65C6757-932B-4D01-9A8A-6D02F8FAA25A}.Release|Any CPU.Build.0 = Release|Any CPU - {12AE7560-AD64-4635-8A6B-772256FF0EDD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {12AE7560-AD64-4635-8A6B-772256FF0EDD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {12AE7560-AD64-4635-8A6B-772256FF0EDD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {12AE7560-AD64-4635-8A6B-772256FF0EDD}.Release|Any CPU.Build.0 = Release|Any CPU + {13B5F568-F402-4A2A-9A23-0FDF0B5564E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {13B5F568-F402-4A2A-9A23-0FDF0B5564E3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {13B5F568-F402-4A2A-9A23-0FDF0B5564E3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {13B5F568-F402-4A2A-9A23-0FDF0B5564E3}.Release|Any CPU.Build.0 = Release|Any CPU + {02CCF8C7-1311-453F-BF82-3564AD9E7B8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {02CCF8C7-1311-453F-BF82-3564AD9E7B8C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {02CCF8C7-1311-453F-BF82-3564AD9E7B8C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {02CCF8C7-1311-453F-BF82-3564AD9E7B8C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE
--- a/SilverlightValidation/SilverlightValidation/Commands/RelayCommand.cs Sat May 05 11:07:41 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -using System; -using System.Windows.Input; - -namespace SilverlightValidation.Commands -{ - public class RelayCommand : ICommand - { - public event EventHandler CanExecuteChanged = delegate { }; - - readonly Action<object> _execute; - readonly Predicate<object> _canExecute; - - public RelayCommand(Action<object> execute, - Predicate<object> canExecute = null) - { - if (execute == null) throw new ArgumentNullException("execute"); - - _execute = execute; - _canExecute = canExecute; - } - - - public void UpdateCanExecuteCommand() - { - CanExecuteChanged(this, new EventArgs()); - } - - - public bool CanExecute(object parameter) - { - return _canExecute == null || _canExecute(parameter); - } - - - public void Execute(object parameter) - { - _execute(parameter); - } - } -}
--- a/SilverlightValidation/SilverlightValidation/Data/Factory.cs Sat May 05 11:07:41 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using SilverlightValidation.Models; - -namespace SilverlightValidation.Data -{ - public class Factory - { - public static IList<UserModel> CreateUserModels() - { - return new List<UserModel>(5) - { - new UserModel() { Username = "StevenH", Password = "Password1", Email = "steven@hotmail.com", DateOfBirth = new DateTime(1977, 09, 01), Description = ""}, - new UserModel() { Username = "RichardJ", Password = "12N456a", Email = "dicky@gmail.com", DateOfBirth = new DateTime(1983, 03, 13), Description = "Loves .Net!"}, - new UserModel() { Username = "BobbyP", Password = "pa33Word", Email = "bob@yahoo.co.uk", DateOfBirth = new DateTime(1992, 08, 30), Description = ""}, - new UserModel() { Username = "DavidM", Password = "poIu789", Email = "daveyboy@marsh.com", DateOfBirth = new DateTime(1965, 06, 21), Description = "Java fan boy"}, - new UserModel() { Username = "JessieJ", Password = "jlkJh567", Email = "jj@apple.co.uk", DateOfBirth = new DateTime(1990, 10, 15), Description = ""} - }; - } - } -}
--- a/SilverlightValidation/SilverlightValidation/Diagrams/Overview.cd Sat May 05 11:07:41 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<ClassDiagram MajorVersion="1" MinorVersion="1"> - <Class Name="SilverlightValidation.Models.UserModel"> - <Position X="2.5" Y="1.75" Width="1.5" /> - <TypeIdentifier> - <HashCode>AAAAAAAAACAgAAAAAQAAAAAAAAAQAEACAAAAAAAAABA=</HashCode> - <FileName>Models\UserModel.cs</FileName> - </TypeIdentifier> - <Lollipop Position="0.2" /> - </Class> - <Class Name="SilverlightValidation.Validators.UserModelValidator" Collapsed="true"> - <Position X="2" Y="7.75" Width="2" /> - <TypeIdentifier> - <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAA=</HashCode> - <FileName>Validators\UserModelValidator.cs</FileName> - </TypeIdentifier> - </Class> - <Class Name="SilverlightValidation.ViewModels.UserListViewModel"> - <Position X="6.25" Y="5.5" Width="2.75" /> - <TypeIdentifier> - <HashCode>AAAAAAAAAAAAAAECAAAAAAAAAAAAABAYABEACAAAAAA=</HashCode> - <FileName>ViewModels\UserListViewModel.cs</FileName> - </TypeIdentifier> - </Class> - <Class Name="SilverlightValidation.ViewModels.UserViewModel"> - <Position X="4.25" Y="1.75" Width="1.75" /> - <TypeIdentifier> - <HashCode>UAAAoIAADCIgAAAAMYAACAAAAAAQABAKQEAAAAAgIAA=</HashCode> - <FileName>ViewModels\UserViewModel.cs</FileName> - </TypeIdentifier> - <Lollipop Position="0.2" /> - </Class> - <Class Name="SilverlightValidation.ViewModels.ViewModelBase"> - <Position X="6.25" Y="1.75" Width="2.75" /> - <TypeIdentifier> - <HashCode>AAAAAAACAABQAAABAAAAAgAAgAAAAACIAAAAAAARAAA=</HashCode> - <FileName>ViewModels\ViewModelBase.cs</FileName> - </TypeIdentifier> - <Lollipop Position="0.2" /> - </Class> - <Class Name="SilverlightValidation.Messages.UserViewResponseMessage"> - <Position X="9.25" Y="5" Width="2.25" /> - <TypeIdentifier> - <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAA=</HashCode> - <FileName>Messages\UserViewResponseMessage.cs</FileName> - </TypeIdentifier> - </Class> - <Interface Name="SilverlightValidation.Interfaces.ICloneable<T>"> - <Position X="2.5" Y="4.5" Width="1.5" /> - <TypeIdentifier> - <HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABA=</HashCode> - <FileName>Interfaces\ICloneable.cs</FileName> - </TypeIdentifier> - </Interface> - <Interface Name="SilverlightValidation.Interfaces.IUserModel"> - <Position X="2.5" Y="5.75" Width="1.5" /> - <TypeIdentifier> - <HashCode>AAAAAAAAACAgAAAAAQAAAAAAAAAQAAACAAAAAAAAAAA=</HashCode> - <FileName>Interfaces\IUserModel.cs</FileName> - </TypeIdentifier> - </Interface> - <Font Name="Segoe UI" Size="9" /> -</ClassDiagram> \ No newline at end of file
--- a/SilverlightValidation/SilverlightValidation/Interfaces/ICloneable.cs Sat May 05 11:07:41 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -namespace SilverlightValidation.Interfaces -{ - public interface ICloneable<T> - { - T Clone(); - } -}
--- a/SilverlightValidation/SilverlightValidation/Interfaces/IUserModel.cs Sat May 05 11:07:41 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -using System; -namespace SilverlightValidation.Interfaces -{ - public interface IUserModel - { - string Username { get; set; } - string Email { get; set; } - string Password { get; set; } - DateTime? DateOfBirth { get; set; } - string Description { get; set; } - } -}
--- a/SilverlightValidation/SilverlightValidation/Messages/UserViewResponseMessage.cs Sat May 05 11:07:41 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -using GalaSoft.MvvmLight.Messaging; -using SilverlightValidation.ViewModels; - -namespace SilverlightValidation.Messages -{ - public class UserViewResponseMessage : MessageBase - { - public UserViewModel UserViewModel { get; set; } - } -}
--- a/SilverlightValidation/SilverlightValidation/Models/UserModel.cs Sat May 05 11:07:41 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -using System; -using System.ComponentModel; -using SilverlightValidation.Interfaces; - -namespace SilverlightValidation.Models -{ - public class UserModel : IUserModel, ICloneable<UserModel> - { - public string Username { get; set; } - public string Email { get; set; } - public string Password { get; set; } - public DateTime? DateOfBirth { get; set; } - public string Description { get; set; } - - public static UserModel Create() - { - return new UserModel() { Username = "", Email = "", Password = "", DateOfBirth = null, Description = "" }; - } - - public UserModel Clone() - { - return (UserModel) this.MemberwiseClone(); - } - } -}
--- a/SilverlightValidation/SilverlightValidation/SilverlightValidation.csproj Sat May 05 11:07:41 2012 +0100 +++ b/SilverlightValidation/SilverlightValidation/SilverlightValidation.csproj Sat May 05 13:29:56 2012 +0100 @@ -63,16 +63,7 @@ <Reference Include="FluentValidation"> <HintPath>..\Libs\FluentValidation.dll</HintPath> </Reference> - <Reference Include="GalaSoft.MvvmLight.Extras.SL5, Version=4.0.21.32933, Culture=neutral, PublicKeyToken=e7f91b7703710fe7, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> - <HintPath>..\Libs\GalaSoft.MvvmLight.Extras.SL5.dll</HintPath> - </Reference> - <Reference Include="GalaSoft.MvvmLight.SL5, Version=4.0.21.32885, Culture=neutral, PublicKeyToken=c114982fcf1a3a2e, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> - <HintPath>..\Libs\GalaSoft.MvvmLight.SL5.dll</HintPath> - </Reference> <Reference Include="mscorlib" /> - <Reference Include="System.ComponentModel.DataAnnotations, Version=5.0.5.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217, processorArchitecture=MSIL" /> <Reference Include="System.Windows" /> <Reference Include="system" /> <Reference Include="System.Core" /> @@ -95,23 +86,13 @@ <Compile Include="App.xaml.cs"> <DependentUpon>App.xaml</DependentUpon> </Compile> - <Compile Include="Data\Factory.cs" /> - <Compile Include="Interfaces\ICloneable.cs" /> - <Compile Include="Interfaces\IUserModel.cs" /> - <Compile Include="Messages\UserViewResponseMessage.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="Commands\RelayCommand.cs" /> - <Compile Include="ViewModels\UserListViewModel.cs" /> - <Compile Include="Models\UserModel.cs" /> - <Compile Include="Validators\UserModelValidator.cs" /> <Compile Include="Views\UserListView.xaml.cs"> <DependentUpon>UserListView.xaml</DependentUpon> </Compile> <Compile Include="Views\UserView.xaml.cs"> <DependentUpon>UserView.xaml</DependentUpon> </Compile> - <Compile Include="ViewModels\UserViewModel.cs" /> - <Compile Include="ViewModels\ViewModelBase.cs" /> </ItemGroup> <ItemGroup> <ApplicationDefinition Include="App.xaml"> @@ -128,10 +109,14 @@ </Page> </ItemGroup> <ItemGroup> - <None Include="Diagrams\Overview.cd" /> <None Include="Properties\AppManifest.xml" /> </ItemGroup> - <ItemGroup /> + <ItemGroup> + <ProjectReference Include="..\SilverlightValidation.PL\SilverlightValidation.PL.csproj"> + <Project>{13B5F568-F402-4A2A-9A23-0FDF0B5564E3}</Project> + <Name>SilverlightValidation.PL</Name> + </ProjectReference> + </ItemGroup> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets.
--- a/SilverlightValidation/SilverlightValidation/Validators/UserModelValidator.cs Sat May 05 11:07:41 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -using System; -using FluentValidation; -using SilverlightValidation.Interfaces; - -namespace SilverlightValidation.Validators -{ - public class UserModelValidator : AbstractValidator<IUserModel> - { - public UserModelValidator() - { - RuleFor(x => x.Username) - .Length(3, 8) - .WithMessage("Must be between 3-8 characters."); - - RuleFor(x => x.Password) - .Matches(@"^\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*$") - .WithMessage("Must contain lower, upper and numeric chars."); - - RuleFor(x => x.Email) - .EmailAddress() - .WithMessage("A valid email address is required."); - - RuleFor(x => x.DateOfBirth) - .Must(BeAValidDateOfBirth) - .WithMessage("Must be within 100 years of today."); - } - - private bool BeAValidDateOfBirth(DateTime? dateOfBirth) - { - if (dateOfBirth == null) return false; - if (dateOfBirth.Value > DateTime.Today || dateOfBirth < DateTime.Today.AddYears(-100)) - return false; - return true; - } - } -}
--- a/SilverlightValidation/SilverlightValidation/ViewModels/UserListViewModel.cs Sat May 05 11:07:41 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Windows.Input; -using SilverlightValidation.Commands; -using SilverlightValidation.Models; -using SilverlightValidation.Validators; -using SilverlightValidation.Views; -using GalaSoft.MvvmLight.Messaging; -using SilverlightValidation.Messages; - -namespace SilverlightValidation.ViewModels -{ - public class UserListViewModel - { - UserView window; - - public UserListViewModel(IList<UserModel> models, UserModelValidator validator) - { - Data = new ObservableCollection<UserViewModel>(); - - foreach (var model in models) - Data.Add(new UserViewModel(model, validator)); - - AddCommand = new RelayCommand(AddCommandExecute); - DeleteCommand = new RelayCommand(DeleteCommandExecute); - - Messenger.Default.Register<UserViewResponseMessage>(this, UserViewResponseMessageReceived); - } - - private void UserViewResponseMessageReceived(UserViewResponseMessage userViewResponseMessage) - { - if (userViewResponseMessage.UserViewModel != null) - Data.Add(userViewResponseMessage.UserViewModel); - window.Close(); - } - - #region Properties - - public ObservableCollection<UserViewModel> Data { get; set; } - - public UserViewModel SelectedItem { get; set; } - - #endregion - - #region Commands - - public ICommand AddCommand { get; set; } - public ICommand DeleteCommand { get; set; } - - private void AddCommandExecute(object obj) - { - window = new UserView(); - window.Show(); - } - - private void DeleteCommandExecute(object obj) - { - if (SelectedItem!=null) - Data.Remove(SelectedItem); - } - - #endregion - } -} \ No newline at end of file
--- a/SilverlightValidation/SilverlightValidation/ViewModels/UserViewModel.cs Sat May 05 11:07:41 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,223 +0,0 @@ -using System; -using System.ComponentModel; -using System.Linq; -using System.Windows; -using System.Windows.Input; -using FluentValidation; -using SilverlightValidation.Interfaces; -using SilverlightValidation.Validators; -using SilverlightValidation.Models; -using SilverlightValidation.Commands; -using GalaSoft.MvvmLight.Messaging; -using SilverlightValidation.Messages; - -namespace SilverlightValidation.ViewModels -{ - public class UserViewModel : ViewModelBase, IUserModel, IEditableObject - { - #region Fields - - private readonly UserModelValidator _validator; - private UserModel _data; - private UserModel _backup; - - #endregion - - #region Constructor - - public UserViewModel(UserModel model, UserModelValidator validator) - { - _validator = validator; - _data = model; - _backup = model.Clone(); - - OkCommand = new RelayCommand(OkCommandExecute); - CancelCommand = new RelayCommand(CancelCommandExecute); - } - - #endregion - - #region Methods - - private void SetProperties(IUserModel source) - { - _data.Username = source.Username; - _data.Password = source.Password; - _data.Email = source.Email; - _data.DateOfBirth = source.DateOfBirth; - _data.Description = source.Description; - } - - #endregion - - #region Properties - - private const string UsernameProperty = "Username"; - public string Username - { - get { return _data.Username; } - set - { - if (_data.Username != value) - { - _data.Username = value; - RaisePropertyChanged(UsernameProperty); - IsChanged = true; - } - - ClearError(UsernameProperty); - var validationResult = _validator.Validate(this, UsernameProperty); - if (!validationResult.IsValid) - validationResult.Errors.ToList().ForEach(x => SetError(UsernameProperty, x.ErrorMessage)); - } - } - - private const string PasswordProperty = "Password"; - public string Password - { - get { return _data.Password; } - set - { - if (_data.Password != value) - { - _data.Password = value; - RaisePropertyChanged(PasswordProperty); - IsChanged = true; - } - - ClearError(PasswordProperty); - var validationResult = _validator.Validate(this, PasswordProperty); - if (!validationResult.IsValid) - validationResult.Errors.ToList().ForEach(x => SetError(PasswordProperty, x.ErrorMessage)); - } - } - - private const string EmailProperty = "Email"; - public string Email - { - get { return _data.Email; } - set - { - if (_data.Email != value) - { - _data.Email = value; - RaisePropertyChanged(EmailProperty); - IsChanged = true; - } - - ClearError(EmailProperty); - var validationResult = _validator.Validate(this, EmailProperty); - if (!validationResult.IsValid) - validationResult.Errors.ToList().ForEach(x => SetError(EmailProperty, x.ErrorMessage)); - } - } - - private const string DateOfBirthProperty = "DateOfBirth"; - public DateTime? DateOfBirth - { - get { return _data.DateOfBirth; } - set - { - if (_data.DateOfBirth != value) - { - _data.DateOfBirth = value; - RaisePropertyChanged(DateOfBirthProperty); - IsChanged = true; - } - - ClearError(DateOfBirthProperty); - var validationResult = _validator.Validate(this, DateOfBirthProperty); - if (!validationResult.IsValid) - validationResult.Errors.ToList().ForEach(x => SetError(DateOfBirthProperty, x.ErrorMessage)); - } - } - - private const string DescriptionProperty = "Description"; - public string Description - { - get { return _data.Description; } - set - { - if (_data.Description != value) - { - _data.Description = value; - RaisePropertyChanged(DescriptionProperty); - IsChanged = true; - } - - ClearError(DescriptionProperty); - var validationResult = _validator.Validate(this, DescriptionProperty); - if (!validationResult.IsValid) - validationResult.Errors.ToList().ForEach(x => SetError(DescriptionProperty, x.ErrorMessage)); - } - } - - #endregion - - #region Commands - - public ICommand OkCommand { get; set; } - public ICommand CancelCommand { get; set; } - - private void OkCommandExecute(object obj) - { - RefreshToViewErrors(); - - if (IsChanged && !HasErrors) - { - // save here - Messenger.Default.Send<UserViewResponseMessage>( - new UserViewResponseMessage() { UserViewModel = this }); - } - } - - // in case user hasn't touched the form - private void RefreshToViewErrors() - { - Username = _data.Username; - Password = _data.Password; - Email = _data.Email; - DateOfBirth = _data.DateOfBirth; - } - - private void CancelCommandExecute(object obj) - { - Messenger.Default.Send<UserViewResponseMessage>( - new UserViewResponseMessage() { UserViewModel = null }); - } - - #endregion - - private void ResetFormData() - { - SetProperties(_backup); - ClearAllErrors(); - IsChanged = false; - } - - public bool IsChanged { get; private set; } - - #region IEditableObject for datagrid - - private bool inEdit; - public void BeginEdit() - { - if (inEdit) return; - inEdit = true; - } - - public void CancelEdit() - { - if (!inEdit) return; - inEdit = false; - ResetFormData(); - } - - public void EndEdit() - { - if (!inEdit) return; - } - - #endregion - } -}
--- a/SilverlightValidation/SilverlightValidation/ViewModels/ViewModelBase.cs Sat May 05 11:07:41 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; - -namespace SilverlightValidation.ViewModels -{ - public class ViewModelBase : INotifyPropertyChanged, INotifyDataErrorInfo - { - #region INotifyPropertyChanged method plus event - - public event PropertyChangedEventHandler PropertyChanged = delegate { }; - - protected void RaisePropertyChanged(string propertyName) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - - #endregion - - #region INotifyDataErrorInfo methods and helpers - - private readonly Dictionary<string, List<string>> _errors = new Dictionary<string, List<string>>(); - - public void SetError(string propertyName, string errorMessage) - { - if (!_errors.ContainsKey(propertyName)) - _errors.Add(propertyName, new List<string> { errorMessage }); - - RaiseErrorsChanged(propertyName); - } - - protected void ClearError(string propertyName) - { - if (_errors.ContainsKey(propertyName)) - { - _errors.Remove(propertyName); - RaiseErrorsChanged(propertyName); - } - } - - protected void ClearAllErrors() - { - var errors = _errors.Select(error => error.Key).ToList(); - - foreach (var propertyName in errors) - ClearError(propertyName); - } - - public void RaiseErrorsChanged(string propertyName) - { - ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName)); - } - - public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged = delegate { }; - - public IEnumerable GetErrors(string propertyName) - { - if (propertyName == null) return null; - return _errors.ContainsKey(propertyName) - ? _errors[propertyName] - : null; - } - - public bool HasErrors - { - get { return _errors.Count > 0; } - } - - #endregion - } -}
--- a/SilverlightValidation/SilverlightValidation/Views/UserListView.xaml.cs Sat May 05 11:07:41 2012 +0100 +++ b/SilverlightValidation/SilverlightValidation/Views/UserListView.xaml.cs Sat May 05 13:29:56 2012 +0100 @@ -15,7 +15,7 @@ InitializeComponent(); HtmlPage.Document.SetProperty("title", "Silverlight Validation"); - vm = new UserListViewModel(Factory.CreateUserModels(), new UserModelValidator()); + vm = new UserListViewModel(new UserView(), Factory.CreateUserModels(), new UserModelValidator()); this.DataContext = vm; }