This is my data structure:
public class Movie : IMovie
{
public string Title { get; set; }
public string Description { get; set; }
public List<IActor> Actors { get; set; }
}
public class Actor : IActor
{
string FirstName { get; set; }
string LastName { get; set; }
}
And this is my viewModel:
public class MovieViewModel : BaseViewModel
{
public ObservableCollection<IMovie> Movies { get; set; } = new ObservableCollection<IMovie>();
public MovieViewModel()
{
foreach (var movie in blc.GetAllMovies())
Movies.Add(movie);
}
}
In my MainWindow
I'am adding dataContext
by this:
this.DataContext = new MovieViewModel();
I have 2 listboxes. When I select a movie in first listbox I want to display all actors in second listbox.
I managed to display movies. For some reason actors arent displayed when clicking on any movie.
<ListBox x:Name="moviesListBox" ItemsSource="{Binding Movies}" SelectedItem="{Binding SelectedMovie, Mode=TwoWay}" />
<ListBox x:Name="actorsListBox" ItemsSource="{Binding SelectedMovie.Actors}" SelectedItem="{Binding SelectedActor, Mode=TwoWay}" />
What's wrong there?
You haven't shown where/how SelectedMovie is defined (how it exists in its viewmodel), but
The viewmodel in which SelectedMovie is contained (presumably DataContext of the form/page containing the ListBox controls) must implement the INotifyPropertyChanged interface (the MVVM Light ViewModelBase does this for you)
The SelectedMovie property must raise the PropertyChanged event in its setter. If you are using MVVM Light, ViewModelBase provides a Set method to do this for you.
Example (using MVVM Light; note I've omitted a lot of details to focus on the core issue):
<Window
DataContext={Binding MyViewModel, Source={StaticResource Locator}}
>
<ListBox x:Name="moviesListBox" ItemsSource="{Binding Movies}" SelectedItem="{Binding SelectedMovie, Mode=TwoWay}" />
<ListBox x:Name="actorsListBox" ItemsSource="{Binding SelectedMovie.Actors}" SelectedItem="{Binding SelectedActor, Mode=TwoWay}" />
</Window>
public MovieViewModel : ViewModelBase
{
public ObservableCollection<IMovie> Movies { get; } = new ObservableCollection<IMovie>();
public MovieViewModel()
{
foreach (var movie in blc.GetAllMovies())
Movies.Add(movie);
}
private Movie _selectedMovie;
public Movie SelectedMovie
{
get
{
return _selectedValue;
}
set
{
Set(ref _selectedValue, value);
}
}
}
public class ViewModelLocator
{
// Constructor to register ViewModels, etc...
//
public MovieViewModel MyViewModel => /* resolve the view model */
}
There is no SelectedMovie
property in your MovieViewModel
. You should add one and raise the PropertyChanged
event whenever it's set as suggested by @C Robinson, or you could bind directly to the SelectedItem
property of the moviesListBox
:
<ListBox x:Name="actorsListBox" ItemsSource="{Binding SelectedItem.Actors, ElementName=actorsListBox}"
SelectedItem="{Binding SelectedActor, Mode=TwoWay}" />
There is no SelectedActor
property in your ViewModel
.
ViewModel
public ObservableCollection<IMovie> Movies { get; set; } = new ObservableCollection<IMovie>();
private IMovie _selectedMovie
public IMovie SelectedMovie
{
get => _selectedMovie;
set
{
_selectedMovie = value;
RaisePropertyChanged(nameof(SelectedMovie));
}
}
So when you will select a movie, SelectedMovie setter will be called. There it will raise property changed event for SelectedMovie, and then UI will update the second list.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.