Bind Combo Box based on another Combo Box's se

2019-07-18 20:52发布

问题:

I currently have a Combo Box which is populated with Artist names and I need to bind it to another once the Artist is selected. These are set up as follows in my view:

<ComboBox Height="23" HorizontalAlignment="Left" Margin="65,81,0,0" Name="comboBox1" ItemsSource="{Binding Artists}" SelectedItem="{Binding SelectedArtist}" VerticalAlignment="Top" Width="120" />
    <ComboBox Height="23" HorizontalAlignment="Left" Margin="65,115,0,0" Name="comboBox2" VerticalAlignment="Top" ItemsSource="{Binding Albums}" SelectedItem="{Binding SelectedAlbums}" Width="120" />

In my ViewModel I have the following:

private void initialiseArtists()
    {
        MusicDataClassesDataContext dataClasses = new MusicDataClassesDataContext();

        artistList = (from m in dataClasses.tblArtists select m.ArtistName).ToList();
    }

    public List<String> Artists
    {
        get
        {
            return this.artistList;
        }
    }

    public string SelectedArtist
    {
        set
        {
            this.selectedArtist = value;
            initialiseAlbums();
        }
    }

    private void initialiseAlbums()
    {
        if (selectedArtist != null)
        {
            MusicDataClassesDataContext dataClasses = new MusicDataClassesDataContext();

            var getArtist = dataClasses.tblArtists.FirstOrDefault(band => band.ArtistName == selectedArtist);
            albumList = (from album in dataClasses.tblAlbums
                         where album.ArtistID == getArtist.ArtistID
                         select album.AlbumName).ToList();

            //dataClasses.tblAlbums.SelectMany(album => album.ArtistID == getArtist.ArtistID).ToList();
        }
    }

    public List<String> Albums
    {
        set
        {
            initialiseAlbums();
        }
        get
        {
            return this.albumList;
        }
    }

I was assuming that the Selected Item event would populate the second Combo Box but I was mistaken.

回答1:

You have to notify the view that the Albums property changed. That's why you have to implement the INotifyPropertyChanged interface and call the PropertyChanged event after building your albums list.

For example

public class Musics : INotifyPropertyChanged
{
   public event PropertyChangedEventHandler PropertyChanged;

   private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

   private void initialiseAlbums()
   {
       if (selectedArtist != null)
       {
            //Your code
            OnPropertyChanged("Albums");
       }
    }
}

Its good workaround to use ObservableCollection<> instead of List<>.



回答2:

I was assuming that the Selected Item event would populate the second Combo Box but I was mistaken

there is no selecteditem event. what you have is a SelectedItem Binding. and if you want your view to react to an action in your viewmodel you have to raise INotifyPropertyChanged.

so after your initialiseAlbums(); you have to call OnPropertyChanged("Albums"); at least.

ps: you can also create parentchildrelationobjects, makes such stuff more easier.

public class MyArtist
{
   public string Name{get;set;}
   public IList<Album> Albums {get;set}
}


回答3:

Change it to SelectedItem="{Binding SelectedArtist, Mode=TwoWay}".

Edit: And add a getter to the SelectedArtist property.



标签: c# wpf mvvm