Search code examples
c#wpfdatagridinotifycollectionchanged

Errors Changed inside Collection Changed event does not get raised


I have an fullproperty like that in my VM:

public ObservableCollection<ServiceHost> ServiceHosts
{
    get => serviceHosts;
    set
    {
        if (serviceHosts == value) { return; }
        serviceHosts = value;
        OnPropertyChanged();
    }
}

In my other ViewModel for my MainWindow I'm using the CollectionChanged event on the ServiceHosts property to get the item that was added, convert it to my expected Type and listen to ErrorsChanged event that is a property from that type.
This looks like that:

ServiceHostViewModel.ServiceHosts.CollectionChanged += ServiceHostsOnCollectionChanged;

private void ServiceHostsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.Action == NotifyCollectionChangedAction.Add)
    {
        if (e.NewItems[0] is ServiceHost newItems)
        {
            newItems.Validator = new ServiceHostValidator();
            newItems.ErrorsChanged += (o, args) => UpdateAllErrors();
            newServiceHost.ValidateAllProperties();

        }
    }
}

Unfortunately the ErrorsChanged event never triggers the UpdateAllErrors method, even when the cells show a red border, this event doesn't execute and I don't know why.
Here is a working example where I also use the ErrorsChanged event, but here I add the data to ServiceHosts from code and not the UI:

private void SetErrorsChangedEventToAllServiceHosts(XmlParserBase xmlParserBase)
{
    foreach (var serviceHost in xmlParserBase.GetServiceHostClients(new ServiceHostValidator()))
    {
        ServiceHostViewModel.ServiceHosts.Add(serviceHost);
        serviceHost.ErrorsChanged += (sender, args) => UpdateAllErrors();
    }
}

Why does the ErrorsChanged event in the ServiceHostsOnCollectionChanged doesn't work?
Any help is appreciate.

Update by comment: Here is some code from my model class

public class ServiceHost : INotifyDataErrorInfo
{
    public IValidator<ServiceHost> Validator;

    public ServiceHost(IValidator<ServiceHost> validator)
    {
        this.Validator = validator;
        this.Validator.ErrorsChanged += (s, e) => OnErrorsChanged(e);
    }
}

Solution

  • I just found a working solution. Like I mentioned in the comments to @mm8 I found out that this code:

    Validator.ErrorsChanged += (s, e) => OnErrorsChanged(e);
    

    which was in my constructor, never got called because by using e.NewItems[0] is ServiceHost newServiceHost to check my runtime type I didn't create a new instance and therefore didn't called the constructor. I tried moving that part outside the constructor and inside ValidateAllProperties method which works fine now.

    In my case this method gets called immediately after I'm subscribing to ErrorsChanged property from MainWindow VM.

    newServiceHost.ErrorsChanged += (o, args) => UpdateAllErrors();
    

    If you have assumptions or better ideas let me know.