从SelectedItem绑定ItemsSource

时间:2019-03-13 20:40:38

标签: c# wpf

这是我的数据结构:

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; }
}

这是我的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);
        }
    }

在我的MainWindow中,我以此添加dataContext

this.DataContext = new MovieViewModel();

我有2个列表框。当我在第一个列表框中选择电影时,我想在第二个列表框中显示所有演员。

我设法放映电影。由于某些原因,演员在点击任何电影时都无法显示。

<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}" />

那里怎么了?

3 个答案:

答案 0 :(得分:0)

您尚未显示SelectedMovie的定义位置/方式(它在视图模型中的存在方式),但是

  1. 其中包含SelectedMovie的视图模型(可能是包含ListBox控件的表单/页面的DataContext)必须实现INotifyPropertyChanged接口(MVVM Light ViewModelBase会为您完成此操作)

  2. SelectedMovie属性必须在其设置方法中引发PropertyChanged事件。如果您使用的是MVVM Light,则ViewModelBase提供了Set方法来为您执行此操作。

示例(使用MVVM Light;请注意,我省略了很多细节来关注核心问题):

<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 */
}

答案 1 :(得分:0)

您的SelectedMovie中没有MovieViewModel属性。只要@C Robinson建议设置,就应该添加一个事件并引发PropertyChanged事件,或者可以直接绑定到SelectedItem的{​​{1}}属性:

moviesListBox

答案 2 :(得分:0)

您的SelectedActor中没有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));
   }
}

因此,当您选择电影时,将调用SelectedMovie setter。在那里它将引发SelectedMovie的属性更改事件,然后UI将更新第二个列表。