首页 文章

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

提问于
浏览
0

我有一个View Player,datacontext被设置为来自ViewModel MainPlayerViewModel的ObservableCollection玩家 .

在视图中,我有一个包含TeamId,Name和Position列的数据网格 . 我想将TeamId列与组合框绑定到MainTeamViewModel中可用团队的列表,MainTeamViewModel具有集合属性团队,但当然我希望每当我为团队更新团队时都会更新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列中

我怎么把它关掉?

亲切的问候,

麦克风

UPDATE: 尽管我收到了帮助,但我没有将数据网格的datacontext设置为MainTeam,因为它有一个玩家的ItemsSource和一个选定的玩家绑定的选择项 . 无论如何,我决定保留它1 View / 1 ViewModel并在我的名为teamsVM的PlayerViewModel上创建一个公共属性:

public MainTeamViewModel teamsVM
    {
       get
       {
           return ViewModelLocator.Container.Resolve<MainTeamViewModel>();
       }
    }

现在,我可以将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>

问候,

麦克风

2 回答

  • 0

    我发现这个代码有两个问题 .

    你错过了ComboBox的 SelectedValuePath . 即使您将所有团队绑定到它,所选项的id也为null,因为缺少SelectedValuePath .

    您还有一个DataContext和一个ItemsSource . 对于要显示的团队,只使用ItemsSource,并将SelectedValue绑定到玩家的teamId,除非您的视图模型具有“团队”属性和“播放器”属性,在这种情况下可以使用DataContext . (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.
    
  • 0

    这里有两个问题:

    • 首先,因为@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>
    

    以下是描述:

    • 为数据网格添加名称 .

    • 确保数据网格具有正确的数据上下文,方法是通过在示例中明确设置它,或者从父层次结构继承它 .

    • 使用您之前指定的元素名称修改 ComboBoxItemsSource 属性以指向数据网格 . 由于您现在处于元素而不是数据上下文,因此必须使用 DataContex.Teams 来访问网格数据上下文中的 Teams 属性 . ItemsSource不需要双向绑定,因为视图不会将任何内容写回视图模型 .

    • 指定 SelectedValuePathDisplayMemberPath 属性 .

    • 最后,使用双向绑定将组合框的 SelectedValue 属性绑定到行模型 TeamId 属性 - 现在需要,因为视图应更新模型的值 . Important :组合框的 SelectedValue 属性必须绑定 after ItemsSource 以防止组合框出现问题 .

相关问题