如何在ViewModel中绑定ViewModel的属性和集合项的属性?

时间:2011-08-16 23:02:20

标签: c# winforms mvvm datagridview bindingsource

我会尽力解释这个......

我只是想了解观点,查看模型和演示者,所以我创建了一个小程序来说明一些细节。我的小应用程序基本上存储了专辑。专辑列在一个组合框中,我有艺术家,流派和年份的字段,都是文本框。到目前为止,没有问题...我创建了一个绑定源并将其绑定到视图模型(具有标题,艺术家,流派和年份的属性),并且它按预期工作。我可以在组合框中循环,各种文本框将根据组合框选择而改变。

然后我决定要为每张专辑添加一个歌曲列表,所以我在视图模型中添加了一个新的歌曲属性,并在视图中添加了一个数据网格视图。这是我变得非常困惑的地方。如果我将用于其他所有内容的绑定源绑定到数据网格视图,它显然只是想渲染视图模型的直接字段(基本上重复我在文本框中显示的内容,仅以网格格式显示)。

假设我已充分描述了问题,我该怎么做才能在文本框中显示相册字段,在数据网格视图中显示歌曲?我想我已经得出结论,我只需要第二个绑定源,但是如果可能的话我想避免使用它。我尝试过一些显而易见的事情,例如将数据网格视图的DataMember属性指向“Songs”(视图模型中歌曲集合的属性名称)而没有任何运气。

有人能指出我正确的方向吗?

2 个答案:

答案 0 :(得分:0)

我总是使用第二个BindingSource完成此操作,该第一个BindingSource将第一个BindingSource设置为DataSource。

答案 1 :(得分:0)

因此,ViewModel会加载并准备代表相册的模型,而View会观察ViewModel并以他们能够理解的方式向用户呈现相册。

首先,让我们看看模型。你有一个专辑,它有一首或多首歌。

public sealed class Album
{
  public string Name {get;set;}
  public string Artist {get;set;}
  public IEnumerable<Song> Songs {get;set;}
}

public sealed class Song
{
  public string Name {get;set;}
  public TimeSpan Length {get;set;}
}

ViewModel加载所有相册的公共集合

public sealed class ViewModel : INotifyPropertyChanged
{
  public ObservableCollection<Album> Albums {get;set;}
  public Album SelectedAlbum {get;set;} // implement INPC for this property
}

ViewModel是View的DataContext。控件绑定到Albums和SelectedAlbum。请注意,如果ViewModel不必对SelectedAlbum执行操作,我们可以在View中处理当前所选的Album all。这只是一个例子。

<ComboBox 
    ItemsSource="{Binding Albums}" 
    SelectedItem="{Binding SelectedAlbum}" />

您的控件绑定相对于SelectedAlbum以显示有关它的信息

<TextBlock Text="{Binding SelectedAlbum.Name}" />

您的DataGrid绑定到SelectedAlbum的

<DataGrid ItemsSource="{Binding SelectedAlbum.Songs}" />

一切都比预期好。