Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Changed validation error icons

  • Loading branch information...
commit ef01dac6bb8d5b019436a1336b5208748a4c9860 1 parent 6fc7e8c
JoergEg authored
View
2  CQRSSample.Commands/CQRSSample.Commands.csproj
@@ -34,11 +34,13 @@
<Reference Include="FluentValidation">
<HintPath>..\External Libs\FluentValidation\FluentValidation.dll</HintPath>
</Reference>
+ <Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Command.cs" />
<Compile Include="CreateCustomerCommand.cs" />
+ <Compile Include="DynamicCommand.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RelocatingCustomerCommand.cs" />
</ItemGroup>
View
15 CQRSSample.Commands/DynamicCommand.cs
@@ -1,7 +1,16 @@
-namespace CQRSSample.Commands
+using System.Dynamic;
+
+namespace CQRSSample.Commands
{
- public class DynamicCommand
+ public class DynamicCommand<T> : DynamicObject where T : Command
{
- private readonly dynamic _innerCommand;
+ private readonly dynamic _innerCommand;
+
+ public DynamicCommand(T command)
+ {
+ _innerCommand = command;
+ }
+
+ public T InnerCommand { get { return _innerCommand; } }
}
}
View
9 CQRSSample.Commands/RelocatingCustomerCommand.cs
@@ -1,4 +1,5 @@
using System;
+using FluentValidation;
namespace CQRSSample.Commands
{
@@ -20,4 +21,12 @@ public RelocatingCustomerCommand(Guid id, string street, string streetNumber, st
City = city;
}
}
+
+ public class RelocatingCustomerValidator : AbstractValidator<RelocatingCustomerCommand>
+ {
+ public RelocatingCustomerValidator()
+ {
+ RuleFor(command => command.City).NotEmpty().NotNull();
+ }
+ }
}
View
1  CQRSSample.WpfClient/App.xaml
@@ -11,7 +11,6 @@
</ResourceDictionary>
<ResourceDictionary Source="Themes\ExpressionDark.xaml" />
<ResourceDictionary Source="ApplicationFramework\Resources\ConverterResource.xaml" />
- <ResourceDictionary Source="ApplicationFramework\Resources\Style.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
View
BIN  CQRSSample.WpfClient/ApplicationFramework/Icons/customer.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  CQRSSample.WpfClient/ApplicationFramework/Icons/no.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
26 CQRSSample.WpfClient/ApplicationFramework/Resources/Style.xaml
@@ -1,26 +0,0 @@
-<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
-
- <!-- Validating TextBox-->
- <Style x:Key="ValidatingTextBox" TargetType="{x:Type TextBox}">
- <Setter Property="Margin" Value="3" />
- <Setter Property="Validation.ErrorTemplate">
- <Setter.Value>
- <ControlTemplate>
- <DockPanel DockPanel.Dock="Right" >
- <AdornedElementPlaceholder />
- <Image Source="/ApplicationFramework/Icons/customers.png" Width="15" Height="15" ToolTip="{Binding Path=AdornedElement.ToolTip, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Adorner}}}" />
- </DockPanel>
- </ControlTemplate>
- </Setter.Value>
- </Setter>
- <Style.Triggers>
- <Trigger Property="Validation.HasError" Value="True">
- <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self},
- Path=(Validation.Errors)[0].ErrorContent}" />
- </Trigger>
- </Style.Triggers>
- </Style>
-
-
-</ResourceDictionary>
View
22 CQRSSample.WpfClient/ApplicationFramework/ScreenWithValidatingCommand.cs
@@ -0,0 +1,22 @@
+using Caliburn.Micro;
+using CQRSSample.Commands;
+using FluentValidation;
+using FluentValidation.Results;
+
+namespace CQRSSample.WpfClient.ApplicationFramework
+{
+ public class ScreenWithValidatingCommand<T> : Screen where T : Command
+ {
+ public ValidatingCommand<T> Command { get; protected set; }
+
+ public IValidator<T> Validator { get; set; }
+
+ /// <summary>
+ /// Validates the command
+ /// </summary>
+ protected virtual ValidationResult Validate()
+ {
+ return Command.Validate();
+ }
+ }
+}
View
76 CQRSSample.WpfClient/ApplicationFramework/ValidatingCommand.cs
@@ -0,0 +1,76 @@
+using System;
+using System.ComponentModel;
+using System.Dynamic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text;
+using CQRSSample.Commands;
+using FluentValidation;
+using FluentValidation.Results;
+
+namespace CQRSSample.WpfClient.ApplicationFramework
+{
+ public class ValidatingCommand<T> : DynamicCommand<T>, IDataErrorInfo where T : Command
+ {
+ private readonly IValidator<T> _validator;
+
+ public ValidatingCommand(T command, IValidator<T> validator)
+ : base(command)
+ {
+ _validator = validator;
+ }
+
+ public override bool TryGetMember(GetMemberBinder binder, out object result)
+ {
+ var ex = Expression.Property(Expression.Constant(InnerCommand), binder.Name);
+ result = Expression.Lambda(ex).Compile().DynamicInvoke();
+ return true;
+ }
+
+ public override bool TrySetMember(SetMemberBinder binder, object value)
+ {
+ var method = InnerCommand.GetType().GetProperty(binder.Name).GetSetMethod();
+ method.Invoke(InnerCommand, new[] { value });
+
+ return true;
+ }
+
+ /// <summary>
+ /// Validates the command
+ /// </summary>
+ public virtual ValidationResult Validate()
+ {
+ return _validator.Validate(InnerCommand);
+ }
+
+ public string this[string columnName]
+ {
+ get
+ {
+ var validationResults = Validate();
+
+ if (validationResults == null) return string.Empty;
+
+ var columnResults = validationResults.Errors.FirstOrDefault(x => string.Compare(x.PropertyName, columnName, true) == 0);
+
+ return columnResults != null ? columnResults.ErrorMessage : string.Empty;
+ }
+ }
+
+ public string Error
+ {
+ get
+ {
+ var message = new StringBuilder();
+
+ foreach (var validationFailure in Validate().Errors)
+ {
+ message.Append(validationFailure.ErrorMessage);
+ message.Append(Environment.NewLine);
+ }
+
+ return message.ToString();
+ }
+ }
+ }
+}
View
6 CQRSSample.WpfClient/CQRSSample.WpfClient.csproj
@@ -84,6 +84,8 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="ApplicationFramework\Converters\CollapsedWhenNullConverter.cs" />
+ <Compile Include="ApplicationFramework\ScreenWithValidatingCommand.cs" />
+ <Compile Include="ApplicationFramework\ValidatingCommand.cs" />
<Compile Include="Infrastructure\Installers\ViewModelInstaller.cs" />
<Compile Include="Modules\CustomerDetails\CreateCustomer\CreateCustomerView.xaml.cs">
<DependentUpon>CreateCustomerView.xaml</DependentUpon>
@@ -222,6 +224,10 @@
<ItemGroup>
<Resource Include="ApplicationFramework\Icons\customers.png" />
</ItemGroup>
+ <ItemGroup>
+ <Resource Include="ApplicationFramework\Icons\customer.png" />
+ <Resource Include="ApplicationFramework\Icons\no.png" />
+ </ItemGroup>
<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.
View
2  CQRSSample.WpfClient/Modules/CustomerDetails/CustomerRelocating/CustomerRelocatingView.xaml
@@ -20,7 +20,7 @@
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="10">
<TextBlock Margin="0 0 10 0">City:</TextBlock>
- <TextBox Text="{Binding Command.City, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, UpdateSourceTrigger=PropertyChanged}" Style="{DynamicResource ValidatingTextBox}" Width="400" />
+ <TextBox Text="{Binding Command.City, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" Width="400" />
</StackPanel>
<Button x:Name="Save" Width="100" Margin="0 10 0 0">Save</Button>
View
139 CQRSSample.WpfClient/Modules/CustomerDetails/CustomerRelocating/CustomerRelocatingViewModel.cs
@@ -1,20 +1,13 @@
using System;
-using System.ComponentModel;
-using System.Dynamic;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Reflection;
-using System.Text;
using Caliburn.Micro;
using CQRSSample.Commands;
using CQRSSample.Infrastructure;
using CQRSSample.ReadModel;
-using FluentValidation;
-using FluentValidation.Results;
+using CQRSSample.WpfClient.ApplicationFramework;
namespace CQRSSample.WpfClient.Modules.CustomerDetails.CustomerRelocating
{
- public class CustomerRelocatingViewModel : ValidatingScreenWithCommand<RelocatingCustomerCommand>
+ public class CustomerRelocatingViewModel : ScreenWithValidatingCommand<RelocatingCustomerCommand>
{
private readonly IBus _bus;
private readonly IEventAggregator _eventAggregator;
@@ -39,7 +32,6 @@ public void WithCustomer(Guid customerId)
public void Save()
{
- //TODO: Validation
if(!Validate().IsValid)
return;
@@ -51,133 +43,6 @@ public void Save()
}
}
- public class RelocatingCustomerValidator : AbstractValidator<RelocatingCustomerCommand>
- {
- public RelocatingCustomerValidator()
- {
- RuleFor(command => command.City).NotEmpty().NotNull();
- }
- }
-
- public class ValidatingCommand<T> : DynamicObject, IDataErrorInfo where T : Command
- {
- private readonly dynamic _innerCommand;
-
- public ValidatingCommand(T command, IValidator<T> validator)
- {
- _innerCommand = command;
- Validator = validator;
- }
-
- public T InnerCommand{ get { return _innerCommand; }}
-
- public override bool TryGetMember(GetMemberBinder binder, out object result)
- {
- var ex = Expression.Property(Expression.Constant(InnerCommand), binder.Name);
- result = Expression.Lambda(ex).Compile().DynamicInvoke();
- return true;
- }
-
- public override bool TrySetMember(SetMemberBinder binder, object value)
- {
- var method = InnerCommand.GetType().GetProperty(binder.Name).GetSetMethod();
- //var setter = (Action<Command, object>)Delegate.CreateDelegate(typeof(Action<Command, object>), method);
- method.Invoke(InnerCommand, new[]{value} );
-
- //setter(InnerCommand, value);
- return true;
- }
-
- public IValidator<T> Validator { get; private set; }
-
- /// <summary>
- /// Validates the command
- /// </summary>
- public virtual ValidationResult Validate()
- {
- return Validator.Validate(InnerCommand);
- }
-
- public string this[string columnName]
- {
- get
- {
- var validationResults = Validate();
-
- if (validationResults == null) return string.Empty;
-
- var columnResults = validationResults.Errors.FirstOrDefault(x => string.Compare(x.PropertyName, columnName, true) == 0);
-
- return columnResults != null ? columnResults.ErrorMessage : string.Empty;
- }
- }
-
- public string Error
- {
- get
- {
- var message = new StringBuilder();
-
- foreach (var validationFailure in Validate().Errors)
- {
- message.Append(validationFailure.ErrorMessage);
- message.Append(Environment.NewLine);
- }
-
- return message.ToString();
- }
- }
- }
-
- public class ValidatingScreenWithCommand<T> : Screen, IDataErrorInfo where T : Command
- {
- public ValidatingScreenWithCommand()
- {
- var c = new RelocatingCustomerCommand(Guid.NewGuid());
- }
-
- public ValidatingCommand<T> Command { get; protected set; }
-
- public IValidator<T> Validator { get; set; }
-
- /// <summary>
- /// Validates the command
- /// </summary>
- protected virtual ValidationResult Validate()
- {
- return Command.Validate();
- }
-
- public string this[string columnName]
- {
- get
- {
- var validationResults = Validate();
-
- if (validationResults == null) return string.Empty;
-
- var columnResults = validationResults.Errors.FirstOrDefault(x => string.Compare(x.PropertyName, columnName, true) == 0);
-
- return columnResults != null ? columnResults.ErrorMessage : string.Empty;
- }
- }
-
- public string Error
- {
- get
- {
- var message = new StringBuilder();
-
- foreach (var validationFailure in Validate().Errors)
- {
- message.Append(validationFailure.ErrorMessage);
- message.Append(Environment.NewLine);
- }
-
- return message.ToString();
- }
- }
- }
public class CustomerRelocatingSavedEvent
{
View
2  CQRSSample.WpfClient/Modules/Shell/ShellView.xaml
@@ -21,7 +21,7 @@
<ribbon:RibbonButton x:Name="SearchCustomer" LargeImageSource="..\..\ApplicationFramework\Icons\customers.png" Label="Customer search" />
</ribbon:RibbonGroup>
<ribbon:RibbonGroup Header="Customer Details">
- <ribbon:RibbonButton x:Name="AddNewCustomer" LargeImageSource="..\..\ApplicationFramework\Icons\customers.png" Label="Add new customer" />
+ <ribbon:RibbonButton x:Name="AddNewCustomer" LargeImageSource="..\..\ApplicationFramework\Icons\customer.png" Label="Add new customer" />
</ribbon:RibbonGroup>
</ribbon:RibbonTab>
View
19 CQRSSample.WpfClient/Themes/ExpressionDark.xaml
@@ -1506,6 +1506,25 @@
<Setter Property="Foreground" Value="{DynamicResource TextBrush}" />
<Setter Property="Background" Value="{DynamicResource ControlBackgroundBrush}"/>
<Setter Property="BorderBrush" Value="#FF000000"/>
+
+ <!--Validation-->
+ <Setter Property="Margin" Value="3" />
+ <Setter Property="Validation.ErrorTemplate">
+ <Setter.Value>
+ <ControlTemplate>
+ <DockPanel DockPanel.Dock="Right" >
+ <AdornedElementPlaceholder />
+ <Image Source="/ApplicationFramework/Icons/no.png" Width="15" Height="15" ToolTip="{Binding Path=AdornedElement.ToolTip, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Adorner}}}" />
+ </DockPanel>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
+ <Style.Triggers>
+ <Trigger Property="Validation.HasError" Value="True">
+ <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self},
+ Path=(Validation.Errors)[0].ErrorContent}" />
+ </Trigger>
+ </Style.Triggers>
</Style>
<ControlTemplate x:Key="TextBoxTemplate" TargetType="{x:Type TextBox}">
Please sign in to comment.
Something went wrong with that request. Please try again.