![](/img/trans.png)
[英]ComboBox ItemsSource from MarkupExtension SelectedItem out of sync
[英]Bind ItemsSource from SelectedItem
這是我的數據結構:
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}" />
那有什么不對?
您尚未顯示SelectedMovie的定義位置/方式(其在視圖模型中的存在方式),但是
包含SelectedMovie的視圖模型(可能是包含ListBox控件的表單/頁面的DataContext)必須實現INotifyPropertyChanged接口(MVVM Light ViewModelBase為您完成此操作)
SelectedMovie屬性必須在其setter中引發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 */
}
MovieViewModel
沒有SelectedMovie
屬性。 只要按@C Robinson的建議進行設置,就應該添加一個並引發PropertyChanged
事件,或者可以直接綁定到moviesListBox
的SelectedItem
屬性:
<ListBox x:Name="actorsListBox" ItemsSource="{Binding SelectedItem.Actors, ElementName=actorsListBox}"
SelectedItem="{Binding SelectedActor, Mode=TwoWay}" />
您的ViewModel
沒有SelectedActor
屬性。
視圖模型
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將更新第二個列表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.