【问题标题】:How can I bind to properties of the ViewModel and properties of collection items in the ViewModel?如何绑定到 ViewModel 的属性和 ViewModel 中集合项的属性?
【发布时间】:2011-08-16 23:02:19
【问题描述】:

我会尽力解释这一点......

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

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

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

谁能指出我正确的方向?

【问题讨论】:

    标签: c# winforms mvvm datagridview bindingsource


    【解决方案1】:

    因此,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 是视图的 DataContext。控件绑定到专辑和 SelectedAlbum。注意,如果 ViewModel 不必对 SelectedAlbum 进行操作,我们可以在 View 中处理当前选择的专辑。这只是一个例子。

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

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

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

    您的 DataGrid 绑定到 SelectedAlbum 的 Songs 属性

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

    一切都比预期的要好。

    【讨论】:

    • 感谢您的回复。我正在使用 WinForms,但这个例子显然很清楚,在结合你和查尔斯的答案后,我能够实现它。
    【解决方案2】:

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

    【讨论】:

    • 我创建了第二个绑定源并将它的源数据源作为第一个绑定源。然后我将新的绑定源绑定到数据网格视图……但没有任何改变。它只是重复原始绑定源中可用的属性。
    • @Brent 您是否将 Songs 集合设置为第二个 BindingSource 的 DataMember?
    • 我从一开始就一直在尝试做这样的事情——指定要渲染的歌曲属性。根据显示成员的描述,这听起来确实像我想要的。唯一的问题是,在第二个绑定源和数据网格视图(一旦第二个绑定源绑定到它)上,Visual Studio 中的显示成员属性中没有可用的内容。我可以手动输入它,但什么也没有发生(我假设我可以为显示成员值输入“Songs”,因为属性本​​身被命名为“Songs”......)
    • @Brent 您可能需要使用 Bindable 和/或 Browsable 属性来装饰视图模型上的“Songs”属性。
    猜你喜欢
    • 2011-08-26
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    • 2015-01-25
    • 2013-06-25
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多