Git Product home page Git Product logo

Comments (12)

BrunoJuchli avatar BrunoJuchli commented on June 16, 2024 1

@SimonCropp
Hi Simon, thanks for the great work, as always :-)

My testing suggests that even in the case of Validar before PropertyChanged there's no PropertyChanged notification for HasErrors taking place.

Having a look at the code which is generated by Validar, this makes complete sense. This is what Validar weaves into ViewModel:

bool INotifyDataErrorInfo.HasErrors
{
    get
    {
        return ((INotifyDataErrorInfo)this.validationTemplate).HasErrors;
    }
}

PropertyChanged is incapable of tracking changes for this and thus does not weave them.


Sidenote

Running Propertychanged after Validar does not work in case in case the ViewModel has [ImplementPropertyChanged], since, of course, Validar expects the ViewModel to implement INotifyPropertyChanged - and when Validar is run before PropertyChanged, the ViewModel does not implement ÌNotifyPropertyChanged` yet.

Of course this can be worked-around by manually implementing INotifyPropertyChanged on the ViewModel. But that's not so great because it either forces us to derive from base classes like Calburn.Micro's PropertyChangedBase or implement INotifyPropertyChanged and deativate CS0067 because the compiler is complaining that no-one is ever raising a PropertyChangedEvent.


Possible Solutions

Weave Property-Changed for HasErrors

--> Downside: implementing something which is the expertise of PropertyChanged.

Implementation could be:

To the constructor, add (only in case ValidationTemplate implements INotifyDataErrorInfo):

this.validationTemplate.ErrorsChanged += (sender, e) => 
    { 
        var propertyChanged = this.propertyChanged;
        if(propertyChanged != null)
            propertyChanged(this, "HasErrors");
    }

--> Downside: notifies also when validation has been performed but HasErrors value hasn't changed. Improving that would require change-tracking.

Make ValidationTemplate available as property on the ViewModel

Add the following to the `ViewModel:

public ValidationTemplate { get {return this.validationTemplate; } }

or, respectively:

public ValidationTemplate<ViewModel> { get {return this.validationTemplate; } }

or, respectively:

public INotifyDataErrorInfo { get {return this.validationTemplate; } }

or, respectively:

public IDataErrorInfo { get {return this.validationTemplate; } }

Advantages:

  • no need for change tracking.
  • PropertyChanged can be implemented on ValidationTemplate - if necessary.
  • new feature: one could force validation through ViewModel.ValidationTemplate.Validate() p.Ex. upon button click. If i gather correctly, currently there's no way to trigger validations besides changing a property, right?

Disadvantages

  • generic ValidationTemplate might be a bit of a hassle to consume by code. However, user is free to choose which to use.

Questions:

  • does it ever make sense for the ValidationTemplate to implement both, IDataErrorInfo and INotifyDataError?

    • would it make sense to allow the user to choose as which type the ValidationTemplate would be provided? for example:

    [MakeAvailableAs(typeof(IValidation)]
    public class ValidationTemplate : IValidation
    {
    ....
    }

Validar would need to verify whether ValidationTemplate indeed implements IValidation plus weave it accordingly:

 public class ViewModel
 {
      public IValidation ValidationTemplate { get {return _validationTemplate; } }
 }

Pull-Request

So, what's your feedback? If any, which would you like me to implement and send you a PR for? ;-)

from validar.

SylwesterZarebski avatar SylwesterZarebski commented on June 16, 2024 1

@BrunoJuchli You can use explicit validation template field in your viewmodel:

Validation.ValidationTemplate validationTemplate;
[DependsOn("Property1", "Property2")]
public bool HasErrors
{
    get { return this.validationTemplate.HasErrors; }
}

Above code uses Fody.PropertyChanged with Fody.Validar.

If You also use Caliburn.Micro, then You could use Can* convention like CanButtonName to simplify binding (avoid explicit IsEnabled=...)

from validar.

BrunoJuchli avatar BrunoJuchli commented on June 16, 2024 1

@SylwesterZarebski until you add a new property....

from validar.

SimonCropp avatar SimonCropp commented on June 16, 2024

email me your repro [email protected]

from validar.

SimonCropp avatar SimonCropp commented on June 16, 2024

@seanterry the repro you sent me wasnt using fody. can u send me one that is

from validar.

azhozhin avatar azhozhin commented on June 16, 2024

I faced with same issue.
Seems Validar not being processing if it is in wrong place in FodyWeavers.xml.
Example:

<Weavers>
  <Validar />
  <PropertyChanged />
</Weavers>

But this works as expected:

<Weavers>
  <PropertyChanged />
  <Validar />  
</Weavers>

I'll send you example project

from validar.

SimonCropp avatar SimonCropp commented on June 16, 2024

closing this since it would seem @azhozhin has suggested the correct solution. ie you need to run PropertyChanged after Validar

from validar.

BrunoJuchli avatar BrunoJuchli commented on June 16, 2024

btw. is there another, .. better.. approach to disable a "save" or "ok" button when the validation fails?

from validar.

BrunoJuchli avatar BrunoJuchli commented on June 16, 2024

The use case i wanted to have HasErrors property changed notification was using `IsEnabled="{Binding HasErrors, Converter={...}}" on a save button.
I've just stumbled upon this: http://stackoverflow.com/a/18651331/684096

Will have to check whether i can use this as a workaround. Will report back once i've tried it out (should get a chance during the course of this week).

from validar.

BrunoJuchli avatar BrunoJuchli commented on June 16, 2024

I couldn't get "the workaround" working as i wanted it to. So i'm still looking for a way to bind to the INotifyDataErrorInfo.HasErrors property with property-changed notification.

@SimonCropp can you tell me which implementation variant (see above), if any, you prefer? thanks.

from validar.

BrunoJuchli avatar BrunoJuchli commented on June 16, 2024

@SylwesterZarebski
Thanks. The [DependsOn] having to list all properties manually is a serious down-side, though. This is far from refactor friendly - it introduces code which is very likely to cause a bug in the future.

from validar.

SylwesterZarebski avatar SylwesterZarebski commented on June 16, 2024

True, but if You use C#6 (VS2015) You could use it with nameof() construct and be refactor friendly :).

from validar.

Related Issues (18)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.