Nested validations are not reported back to parent viewmodels

Dec 19, 2011 at 9:02 PM

Documentation said:

"As the image above shows, all children in the chain are validated, and when the last child is validated, the view model reports the result of its children and itself back to its parent. This way, it is still possible to disable a command when one of the nested user control view models has an error."

But I can't retreive on parent viewmodel the nested viewmodels validation results.

I'm evaluate the parent viewmodel on the OnValidated event, so I can see the child viewmodels with it's errors. But the errors are not reported back to the parent.

At this point I can't disable a command when a nested view model has an error.

I'm using Catel.Silverlight 2.4.

Dec 20, 2011 at 7:32 AM

The actual errors are contained by the child view model itself. Internally, the viewmodelbase checks whether the HasErrors property of a child view model is true. If so, the HasErrors of the parent view model returns true like this:

public new bool HasErrors
{
    get { return base.HasErrors || _childViewModelsHaveErrors; }
}

I understand that you want to retrieve the ValidationContext of the child items, right? I am not sure whether it is a good idea to add all the errors to the parent view model (quite some error management). What I am currently thinking of is creating a method like this:

IEnumerable<IViewModel> GetChildViewModels()

Then you can retrieve the ValidationContext of each view model and maybe I can even write a GetHierarchyValidationContext that loops all the childs (but this will be a hit on the performance).

Dec 20, 2011 at 2:29 PM
Edited Dec 20, 2011 at 2:31 PM

So, How the InfoBarMessageControl works? I'm pretty sure that I saw it works on a DataWindow with a couple of tabs where each tabitem contains it's own viewmodel.

I'm trying to use it (the InfoBarMessageControl) on my own UserControl but doesn't work as I expected. I'm really stuck now.

Allow me depicts my scenario.

[Shell] --> Is a UserControl<T>.

  [RadRibbonView]

     [RibbonButtonViewModel] --> Each button view model are interested in the well knows view models, so I send here the validation summaries (no problems here), canexecute works.

     [RibbonButtonViewModel] --> ...

  [InfoBarMessageControl] --> I expect show all tabs errors here (but doesn't show), The WarningAndErrorValidator is bound to the shell.

  [RadTabControl]

      [RadTabItem] --> View injected with following the PRISM approach. (Each view (UserControl<T>), content of the RadTabItem) has it own view model (ViewModelBase)).

            [UserControl1] --> Here I have a master/details situation with complex editing approach. Here I have a Button (eg: Add) looks like the validation sequence of the nested control do not affect here, so the can execute never occurs.

                [UserControl2] -->  Here I edit data about the selection, the validation occurs, the controls shows it's red flag, but the errors doesn't report's back to the parent control.

      [RadTabItem] ...

I have an idea how "solve" it, but I need you opinion how solve this issue.

Thanks in advance.

Dec 20, 2011 at 3:18 PM

Each UserControl<TViewModel> implementation automatically wraps itself in a grid and adds a WarningAndErrorValidator. This is some kind of ValidationSummary that the InfoBarMessageControl listens to and gathers all the errors from all the WarningAndErrorValidator instances.

The WarningAndErrorValidator you are talking to is positioned outside the InfoBarMessageControl (which is a contentcontrol), so that's probably the cause of the errors not showing up.

What is your idea to solve it?

Dec 20, 2011 at 4:20 PM
Edited Dec 20, 2011 at 4:34 PM

1. This is my source code, where "root" element is the Shell it self. 

<WorkflowShell:IntermediateShell ...x:Name="root">
...
   <catel:InfoBarMessageControl Grid.Row="1">
        <catel:WarningAndErrorValidator Source="{Binding ElementName=root, Path=ViewModel}" />
   </catel:InfoBarMessageControl>
  <Grid Grid.Row="2">
      <telerik:RadTabControl DisplayMemberPath="Title" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  Name="tabControl1"  Regions:RegionManager.RegionName="MainRegion" DropDownDisplayMode="Visible"/>
  </Grid>
... </WorkflowShell:IntermediateShell>

 


The InfoBarMessageControl never shows.

2. My workaround (for a while) will be report the summary to the parent control and makes the parent control interested in the child ones. The same solution on my RibbonButtonViewModels.

You can include a new ViewModelBase or DataObjectBase or UserControl<T> property which allow to the developers decide whether he wants the errors reports back to the parents view models automatically.
They have to deal with the performance issue if they set the property to true. So, you don't have to write new properties.

Looks like this
<PersonDetailUserControl ... IncludeChildControlsValidationContext="true" />
or
  <ContactInfoUserControl ... ReportValidationContextToParent="true" />
or
conctactInfo = new ContactInfoViewModel() 
conctactInfo.ReportValidationContextToParent = true; --> uncomfortable for master/detail scenario.
or

PersonDetailViewModel personDetailViewModel = new PersonDetailViewModel();
personDetailViewModel.IncludeChildViewModelValidationContext = true;

At any level, you can type

this.ValidationContext.GetValidationSummary("ultranestedvalidtiontag")

and retrieve it properly.
Dec 20, 2011 at 5:08 PM

Better this way

    this.ValidationContext.GetValidationSummary("tag", true); --> The second parameter inculdes childs.

So, add a property to ValidationToViewModelAttribute

    [ValidationToViewModel("Tag", IncludeChildViewModels = true)]

Then when a validation summary is set automatically then raise can execute of the command must be executed if the property has not back a PropertyData.

Dec 20, 2011 at 5:17 PM

Agree, will implement this.

Dec 20, 2011 at 6:06 PM

It will be implemented as an extension method of the ViewModel (since only the view model is aware of child view models, not the ValidationContext itself).

Dec 20, 2011 at 6:17 PM

Agree,

I'm waiting for the beta

...as NuGet package ;).

Dec 20, 2011 at 7:11 PM

Sorry, no nuget package yet, but... there is a new beta with all features you requested :)

Dec 20, 2011 at 8:01 PM

Alex,

Could you "donate" a sample that demonstrates this (e.g. modified version of the existing house-room-table sample where each level has 1 editable field that has one 'required' validation)?

This would make it easier for the Catel community to understand the new feature.

Dec 21, 2011 at 3:27 PM

Apparently there is already a editable house-room-table sample for wpf...

Dec 21, 2011 at 4:46 PM
Edited Dec 21, 2011 at 5:00 PM

What about this?

[ValidationToViewModel(Tag = "Tag", IncludeChildViewModels = true)]

I didn't locate it on the beta version.

Dec 21, 2011 at 5:06 PM

Darn, you are right,. I forgot to implement that one. I think I was too busy preparing the beta nuget packages. Yes, you read it right,  I wrote tons of scripts to make it much easier to deploy Catel to nuget.

I will implement this, and will release a nuget beta for the first time tonight!

Dec 21, 2011 at 8:35 PM

First beta release is released via nuget. Let's see how that works out. The version is 2.4.20111221-beta, since NuGet cannot yet use nightly build versioning (I requested this feature today). 

Let me know how the process works for you.

Dec 22, 2011 at 1:34 PM
Edited Dec 22, 2011 at 1:38 PM

It's a rock

Update-Package Catel.Silverlight -IncludePrerelease
or 

Update-Package Catel.Windows -IncludePrerelease

...but, I reviewed the ViewModelBase source code and noticed that you miss a call to the InvalidateCommands method if at least one "validation summary" is set.

Dec 22, 2011 at 1:50 PM

Tonight I will write a blog post on how to use the NuGet beta versioning and why the version is kind of stupid. I will also take a look at the InvalidateCommands method.

Dec 22, 2011 at 3:09 PM

The method should looks like this, but the InvalidateCommands call is missing.

Sorry, is in ViewModelBaseWithoutServices instead ViewModelBase. 

protected override void OnValidated() 
{
  /* ... All validation summary are set here ... */
  if(this._validationSummaries.Count > 0) // At least one validation summary was set. 
  { 
    this.InvalidateCommands();
  } 
  base.OnValidated(); 
}

Dec 22, 2011 at 4:31 PM

Thanks! I have added the fix and it will be included of the beta that will be released tonight. Now if there would only be some kind of notification mechanism to let people automatically know that a beta has been released. That would be cool.

Too bad that the @catel twitter account is already taken, otherwise we could send out a twitter message automatically.

Dec 22, 2011 at 4:56 PM

See http://blog.catenalogic.com/post/2011/12/22/Beta-versions-of-Catel-via-NuGet.aspx for more information about the way we release beta versions.

Dec 23, 2011 at 3:04 PM
Edited Dec 23, 2011 at 3:57 PM

I'm going back to the catel:InfoBarMessageControl question.

I'm notice that this control only shows when catel styles or themes are loaded.

I introduce these couple of lines on my application and reach that the catel:InfoBarMessageControl show on my custom one.

           <ResourceDictionary Source="/Catel.Silverlight;component/themes/generic.xaml" />

            Catel.Windows.StyleHelper.CreateStyleForwardersForDefaultStyles();

I did not create the application with the catel template then I had to type the lines by my self. 

So, with these lines plus a strange approach I was able to show the message on the catel control but I'm not reach the "natural" approach described on the catel documentation yet. 

I thinking that my problem is that I have a [RadTabControl] plus [RadTabItem] on my visual and logical tree. Container controls that do not implements the IViewModelContainer interface.

"Using a custom window" is well described on the documentation but "Using custom control" is not. ( -- [TODO] --).

So, just a couple of questions

The approach to use custom control is similar to the use custom windows too?

Am I right when I said that the containers controls must implements the IViewModelContainer interface in oder to retreive the child validation results? 

Dec 23, 2011 at 4:04 PM

The only real reference that you need is this one: /Catel.Windows;component/themes/generic/controls/InfoBarMessageControl.generic.xaml

You don't have to create the forwarders, it's for margins only.

I am working to get the documentation as complete as possible, but it's the least nice part of the project, and there are so much things to do that sometimes the documentation is not fully completed. However, when we implement a new feature, we always document it to prevent more documentation to be outdated.

The approach is indeed the same. Just add the behavior and you are good to go. Actually, in Silverlight a Window is just a control, so in fact they are the same. I will try to fix this documentation, but so much to do :)

About the validation: no. The issue is that the UserControl<TViewModel> automatically adds this to your user control:

<catel:WarningAndErrorValidator Source="{Binding}" />

However, if you are using a custom control, this is not implemented and you need to add this yourself. Internally, the WrapControlHelper class is responsible for all this stuff. Since I think it can be useful, I just made it public so you can use it.

Dec 23, 2011 at 4:37 PM

FYI: added documentation about creating a custom user control. Currently generating the documentation, but it takes about 40 minutes (because it's a lot).

Dec 28, 2011 at 7:45 PM
Edited Dec 28, 2011 at 7:54 PM

ValidationToViewModelAttribute with include childviewmodels set to 'true' are not working properly on master details escenario.

I have no a clue at this time, just noticed that the auto-injection is failiing when a new nested level is created.

Typically I have two levels, under certain conditions I create a new one following the master/details approach. (The third level has no validator)

I'm using external validators, then I thought that was an error on my validation approach but I force an error reporting on ValidateFields event at the second level and nothing happeds. The first level summary report including childs have zero errors.

Dec 29, 2011 at 1:00 PM

This is probably because only a property on the child changes, and then the parent view model has no clue of the change. I will take a look at the nested validation to see whether I can keep track of the PropertyChanged event of HasErrors and HasWarnings on the child view models. That should solve the issue.

Dec 29, 2011 at 3:49 PM

I already implemented this stuff. Writing additional unit tests to see where it goes wrong.

Dec 29, 2011 at 4:04 PM

Think I found the issue. When a child view model is added, the view model now checks whether HasErrors or HasWarnings is true. If so, the validation sequence kicks in.

Just published a beta to nuget. Please let me know whether it solves your issue.

Dec 29, 2011 at 4:18 PM

Great,

Just a couple of question, and forgive my impudence (if exists):

 + How Catel's users can contribute with bug detection via unit test?

 + Are you interested in this kind of contribution?

 

Dec 29, 2011 at 4:25 PM

1) Definitely interested! If you ever have issues or ideas, we are always interested :)

2) You can create a fork (but it's quite some work to do that), or just post it here, or if you are really interested in contributing to Catel, you can become a developer :)

Dec 29, 2011 at 5:12 PM

I'm really interesting, but I really have poor internet access. Actually, I will have no internet access during the year end holidays.

I will try to contribute with Catel the next year. We talk about it asap.

---------------------------------------------------------------------------------------------------------------------------------

PD: Happy new year ;).

Dec 29, 2011 at 5:50 PM
Edited Dec 29, 2011 at 5:50 PM

The problem remains.

I'm using Catel.Silverlight.2.4.1112291703-beta.

 

Dec 29, 2011 at 5:50 PM

Darn, then I will have to find out what is going on...

Thanks for letting my know and happy new year to you too :)

Dec 29, 2011 at 10:31 PM

The nuget packages now include symbols. You can now step into the source of catel for all nuget packages of catel released from now on. You just have to set up this once:

http://www.symbolsource.org/Public/Home/VisualStudio

Jan 5, 2012 at 5:02 PM

I'm back.

I trying to download the symbols files but I can't.

First public url http://srv.symbolsource.org/pdb/Public/ looks as death end point, response with 404 Error.

Server Error in '/' Application


The resource cannot be found.

Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.


Version information: Mono Runtime Version: <tt>2.10.5 (Debian 2.10.5-1)</tt>; ASP.NET Version: <tt>4.0.30319.1</tt>

I create an account on symbolsource, and try to access to my private link and fail again.

Intercepting the request/response traffic with fiddler I get more detailed errors

Could you provide an URL that works for you?

 

HTTP/1.1 404 Not Found
Via: 1.1 E22-SRV-ISA-01
Connection: Keep-Alive
Proxy-Connection: Keep-Alive
Content-Length: 79
Date: Thu, 05 Jan 2012 16:46:45 GMT
Content-Type: text/html; charset=utf-8
Server: Apache/2.2.21 (Debian)
X-AspNetMvc-Version: 2.0
X-AspNet-Version: 4.0.30319
Cache-Control: private
Keep-Alive: timeout=5, max=100
PDB Catel.Silverlight.pdb with FDEA4A04A9A548A4975D787C0D9034804 hash not found
-------------------------------------------------
HTTP/1.1 404 Not Found
Via: 1.1 E22-SRV-ISA-01
Connection: Keep-Alive
Proxy-Connection: Keep-Alive
Content-Length: 40
Date: Thu, 05 Jan 2012 16:46:51 GMT
Content-Type: text/html; charset=utf-8
Server: Apache/2.2.21 (Debian)
X-AspNetMvc-Version: 2.0
X-AspNet-Version: 4.0.30319
Cache-Control: private
Keep-Alive: timeout=5, max=100
Supported only compresioned files (.pd_)


 

 
Jan 6, 2012 at 1:56 PM

Welcome back :)

I have requested help on the SymbolSource google group. Will respond when I get a response. As you can see here, there is a valid package for Catel.Silverlight:

http://www.symbolsource.org/Public/Metadata/NuGet/Project/Catel.Silverlight

Jan 9, 2012 at 2:10 PM

See: http://groups.google.com/group/symbolsource/browse_thread/thread/a8fa24afeab8fcd5

Seems like my mistake.

I will try to download the package again, cleaning my nuget cache first.

Jan 9, 2012 at 7:44 PM

I get the symbols but with hash FDEA4A04A9A548A4975D787C0D9034805.

Suddenly it start to work without doing anything.

I will try to find the reason why child view models still without reporting back the validation summary in a master/details scenario.

Jan 9, 2012 at 8:12 PM

Great, thanks for the updates. This is the last change we will make before the release of 2.5, so we can't wait for more info :)

Jan 9, 2012 at 9:07 PM

Sorry 0 KB file as symbol file. The symbol file never was downloaded.

Seems that it works for some one with a normal internet access and speed. A directory with name 'FDEA4A04A9A548A4975D787C0D9034805' was created, containing (a 0 KB file for me) named Catel.Silverlight.pd_.

I'm really need to talk with my internet access providers ;).

Jan 10, 2012 at 5:41 PM

So if I understand correctly, you are able to download the pdb files now? You can walk through the source code? If so, did you find out why it didn't work?

Jan 17, 2012 at 2:02 PM

Actually no. I can't download the symbol files. So, I can't walk through the source code.

It is a problem with my internet access provider.

 

Jan 17, 2012 at 2:07 PM

Hmmm. Then we probably should contact your ISP to give you a better connection :)

Can you mail me your POC (proof of concept)? Then I can fix it. It is the last issue for the new release that I want to fix (so you don't have to wait another month for this fix).

Jan 17, 2012 at 6:50 PM

Issue is fixed.

Jan 17, 2012 at 7:52 PM
Edited Jan 17, 2012 at 7:53 PM

Now the feature is completed.

GEERTD, here is a simplified example

Sorry for the delay.

Jan 17, 2012 at 8:19 PM

Hi alexfdezsauco,

Thanks for the sample! I will download it and will check it out in one of the next few days.

Jan 17, 2012 at 9:46 PM

Latest beta introduce a problem with a tabbed interface. I have no a clue right now.

When I have a clue I will posted on other thread.