Tichau
Tichau

Reputation: 305

How to bind multiple nested properties in WPF

Here is my problem, I have the following data structure:

public class Job : INotifyPropertyChanged {
    public StateEnum State {
        get { return this.state; }

        private set {
            this.state = value;
            this.OnPropertyChanged();
        }
    }
}

public class MainWindow : Window, INotifyPropertyChanged 
    public List<Job> Jobs {
        get { return this.jobs; }

        private set {
            this.jobs = value;
            this.OnPropertyChanged();
        }
    }
}

I want to display a global state summary of the jobs in the main window.

I first tried to make a data binding on the Jobs list, then use a custom IValueConverter to display the global state. Problem: It is not refreshed when the job states change (since it is bind to the collection and not the states).

ProgressState="{Binding Jobs, Converter={StaticResource JobsToProgressState}, ElementName=MainWindow}"

So I was trying to find a solution where I can bind all the nested properties of the jobs to a IMultiValueConverter. I did not find any syntax to make this work.

Is it possible to do something like that?

EDIT: I want to do something like

ProgressState="{Binding Jobs[*].State, Converter={StaticResource JobsToProgressState}, ElementName=MainWindow}"

And retrieve an array containing all job states (StateEnum[]) in the JobsToProgressState converter.

Upvotes: 2

Views: 243

Answers (1)

user7861944
user7861944

Reputation:

The problem is that OnPropertyChanged is not fired when a record of an IList changes. You need to delegate the OnPropertyChanged of the Job up to your Jobs-List.

This rough implementation will do what you want.

public class Job : INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged; 
    public StateEnum State {
        get { return this.state; }

        private set {
            this.state = value;
            this.OnPropertyChanged();
        }
    }
}

public class MainWindow : Window, INotifyPropertyChanged 
    public List<Job> Jobs {
        get { return this.jobs; }

        private set {
            this.jobs = value;

            foreach(var job in this.jobs)
            {
                job.PropertyChanged += job_PropertyChanged;
            }
        }
    }

    private void job_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        this.OnPropertyChanged("Jobs");
    }
}

Don't forget to unwire your event registrations when you don't need them any more.

Upvotes: 1

Related Questions