Silverlight 将datagrid绑定到一个ViewModel,将列/组合框绑定到另一个

Silverlight 将datagrid绑定到一个ViewModel,将列/组合框绑定到另一个,silverlight,mvvm,Silverlight,Mvvm,我有一个视图播放器,datacontext设置为ViewModel MainPlayServiceWModel中的ObservableCollection播放器 在视图中,我有一个datagrid,其中包含列TeamId、名称和位置。 我希望使用组合框将TeamId列绑定到MainTeamViewModel中的可用团队列表,该列表具有集合属性teams,但当然,我希望每当我为球员更新团队时,MainPlayerViewModel都会更新 我希望你能跟我来。。 这是我的xaml: <data

我有一个视图播放器,datacontext设置为ViewModel MainPlayServiceWModel中的ObservableCollection播放器

在视图中,我有一个datagrid,其中包含列TeamId、名称和位置。 我希望使用组合框将TeamId列绑定到MainTeamViewModel中的可用团队列表,该列表具有集合属性teams,但当然,我希望每当我为球员更新团队时,MainPlayerViewModel都会更新

我希望你能跟我来。。 这是我的xaml:

<data:DataGridTemplateColumn.CellEditingTemplate>
  <DataTemplate>
   <ComboBox DataContext="{Binding MainTeam, Mode=OneWay, Source={StaticResource Locator}}" 
    Height="23" HorizontalAlignment="Left" 
    Name="cmbTeams" VerticalAlignment="Top" Width="100" ItemsSource="{Binding Teams, 
    Mode=TwoWay}" SelectedValue="{Binding Path=Model.teamid, Mode=TwoWay}"   
    DisplayMemberPath="Model.teamid"/>
  </DataTemplate>
 </data:DataGridTemplateColumn.CellEditingTemplate>

当我编辑单元格时,它会显示可用团队的列表,但我从列表中选择的selectedvalue不会出现在TeamId列中

我该怎么办

亲切问候,

迈克

更新: 尽管我得到了帮助,但我还是无法将一个视图绑定到两个不同的视图模型。 我猜提供的解决方案远远超出我的想象。。 我无法将datagrid的datacontext设置为MainTeam,因为它有一个球员的ItemsSource和一个与selectedplayer双向绑定的selecteditem。 无论如何,我决定保留它1视图/1视图模型,并在我的PlayerViewModel上创建了一个名为teamsVM的公共属性:

    public MainTeamViewModel teamsVM
    {
       get
       {
           return ViewModelLocator.Container.Resolve<MainTeamViewModel>();
       }
    }
public主团队视图模型团队支持向量机
{
得到
{
返回ViewModelLocator.Container.Resolve();
}
}
现在,我可以将Itemsource设置为这个新属性,并且在我更改团队时,我的玩家行会得到更新:

    <DataTemplate>
     <ComboBox 
       Height="23" HorizontalAlignment="Left" 
       Name="cmbTeams" VerticalAlignment="Top" Width="100" 
       ItemsSource="{Binding teamsVM.Teams, 
       Mode=TwoWay}" SelectedValue="{Binding Model.teamid, Mode=TwoWay}"   
       DisplayMemberPath="Model.teamid" SelectedValuePath="Model.teamid"/>
    </DataTemplate>

问候,


迈克

我发现这段代码有两个地方不对劲

您缺少组合框的
SelectedValuePath
。即使您将所有团队绑定到它,所选项目的id也是空的,因为缺少SelectedValuePath

您还有一个DataContext和一个ItemsSource。除非视图模型具有“teams”属性和“player”属性(在这种情况下可以使用DataContext),否则仅使用要显示的团队的ItemsSource和要绑定到玩家的teamId的SelectedValue。(虽然Id在代码中设置了DataContext…)

所以你最终会得到这样的结果:

ItemsSource="{Binding Teams, Mode=TwoWay}"                  //Bind to all teams.
SelectedValue="{Binding Player, Path=TeamId, Mode=TwoWay}"  //Bind to the teamId of the player.
DisplayMemberPath="TeamName"                                //that's the Name of each team.
SelectedValuePath="TeamId"                                  //that's the Id of the team.
这里有两个问题:

  • 首先,@bleepzer指出,您没有在组合框中指定值/显示路径
  • 其次,您试图从数据模板中访问网格之外的数据上下文(即主视图模型的数据上下文)中的属性。在silverlight 4中没有相对源绑定(您将在SL 5或WPF中使用),因此您必须使用元素绑定来归档所需内容
下面是一个基于您的代码的示例。它不完整,因为它遗漏了一些所需的DataGrid元素,但它展示了以下概念:

<data:DataGrid x:Name="myDataGrid" 
               DataContext="{Binding MainTeam, Mode=OneWay, Source={StaticResource Locator}}" >
  <!-- additional stuff needed here -->
    <data:DataGridTemplateColumn.CellEditingTemplate>
      <DataTemplate>
        <ComboBox Height="23" HorizontalAlignment="Left" 
                  Name="cmbTeams" VerticalAlignment="Top" Width="100" 
                  ItemsSource="{Binding ElementName=myDataGrid, Path=DataContext.Teams}" 
                  SelectedValuePath="TeamId"
                  DisplayMemberPath="TeamName"
                  SelectedValue="{Binding Path=Model.teamid, Mode=TwoWay}"/>
      </DataTemplate>
    </data:DataGridTemplateColumn.CellEditingTemplate>
  <!-- additional stuff needed here -->
<data:DataGrid>

以下是描述:

  • 将名称添加到数据网格中
  • 确保数据网格具有正确的数据上下文,方法是将其显式设置为示例中的数据,或从父层次结构继承该数据
  • 修改组合框的
    itemsource
    属性,以使用前面指定的元素名称指向数据网格。由于您现在位于元素而不是数据上下文中,因此必须使用
    DataContex.Teams
    访问网格数据上下文中的
    Teams
    属性。ItemsSource不需要双向绑定,因为视图不会将任何内容写回视图模型
  • 指定
    SelectedValuePath
    DisplayMemberPath
    属性
  • 最后,使用双向绑定将组合框的
    SelectedValue
    属性绑定到您的行模型
    TeamId
    属性-现在需要,因为视图应该更新模型的值重要:组合框的
    SelectedValue
    属性必须在
    ItemsSource
    之后绑定,以防止组合框出现一些问题

  • thnx对于您的回复,我得到:如果我这样做,属性'System.Windows.Data.Binding.Path'会被设置多次?thnx Obalix,在我的例子中,我的usercontrol的datacontext是一个播放器ViewModel(datacontext=“{Binding MainPlayer,Mode=OneWay,Source={StaticResource Locator})其中列出了具有id、名称列的玩家,并且只有一列团队是我“在cellediting模式下”想要从中获取团队的。如果我是对的,网格的datacontext应该绑定MainPlayer?无论数据网格上的上下文是什么都不重要,一旦设置ItemsSource属性,每行现在都有一个数据上下文代表ng ItemsSource中的一项。若要访问网格的数据上下文(通常存储团队集合的位置),无论是在列模板还是行模板中,当您在数据模板中时,都必须应用所述模式。该模式无法正常工作,但我通过解决方法解决了它(请参阅上面的更新),thnx Obalix