Search code examples
c#wpfxamlobservablecollectionpropertychanged

Implement Onpropertychanged with ObservableCollection (C#, WPF)


I have ComboBox with "ProjectList":

MainWindow.xaml

<ComboBox ItemsSource="{Binding Path=ProjectList}" IsSynchronizedWithCurrentItem="True" />

Elements are adding inside below method and working ok:

MainViewModel.cs

[AddINotifyPropertyChangedInterface]
public class MainViewModel{

 public ObservableCollection<string> ProjectList { get; internal set; } 
  = new ObservableCollection<string>(); 

  public async Task GetProjects(){
  ...
   foreach (AItem item in....)
   {
     ProjectList.Add(item.name)
   }
 }    
}

Note - I have installed "PropertyChanged.Fody".

Now I have added second ComboBox "TaskList" to xaml:

<ComboBox ItemsSource="{Binding Path=TaskList}" IsSynchronizedWithCurrentItem="True" />

List here should be created based on selected item into "ProjectList". Method is mostly the same, only has a parameter:

public ObservableCollection<string> TaskList { get; internal set; } 
 = new ObservableCollection<string>();

public async Task GetTask(string projectId = ""){
      ...
       foreach (AItem item in....)
       {
         TaskList.Add(item.name2)
       }
 }   

Now I want to addopt this to my MVVM.

Problem is: when and how to run GetTask()? Instead of "internal set" for ObservableCollection TaskList should be implemented "onpropertychanged"?


Solution

  • when you select Project the next cb should load (run) taskList

    Then you should either bind the SelectedItem property of the ComboBox to a string source property and call the GetTask method in the setter of this one, e.g.:

        private string _selectedProject;
        public string SelectedProject
        {
            get { return _selectedProject; }
            set
            {
                _selectedProject = value;
                GetTask(_selectedProject);
            }
        }
    

    ...or invoke a command when the selection changes: Either from the setter:

    set
    {
        _selectedProject = value;
        YourCommand.Execute(null);
    }
    

    ...or from the XAML markup using an interaction trigger.

    Properties should not not really be kicking off asynchronous background operations in their setters. Please refer to my answer here for more information about this:

    Is wrong to invoke an async method from property setter in WPF view model?