XAML:绑定到集合中的单个子节点

时间:2009-08-26 21:33:26

标签: xaml silverlight-3.0

我有一个这样的课程:

public class Contest {
    List<ContestTeam> Teams { get; set; }
}

public class ContestTeam {
    int TeamId { get; set; }
    int FinalScore { get; set; }
}

我的视图模型看起来像这样:

public class ScheduleViewModel {
    int CurrentTeamId { get; }
    List<Contest> Schedule { get; }
}

我的XAML看起来像这样:

<ListBox ItemsSource="{Binding Path=Schedule}">
    <ListBox.ItemTemplate>
        <DataTemplate>

            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition  />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>

                <StackPanel Grid.Row="0" Orientation="Horizontal">
                    <!-- TODO: DataContext is currently hard coded to 425 - this needs to be fixed -->
                    <StackPanel Orientation="Horizontal" 
                            DataContext="{Binding Path=Teams, Converter={StaticResource CurrentTeam}, ConverterParameter=425}">

                        <TextBlock Text="{Binding SomeProperty}" />
                    </StackPanel>

                    <Button Content="Delete" />
                </StackPanel>

                <ListBox Grid.Row="1" ItemsSource="{Binding Teams}">
                    <!-- a list of all the teams -->
                </ListBox>
            </Grid>

        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

基本上,我可以继续开发我创建了一个值转换器(CurrentTeam)并将TeamId硬编码为ConverterParameter,这样我就可以继续开发视图了。但我有点陷入僵局。有没有办法(使用XAML)将DataContext l的StackPane绑定到ContestTeam集合中与Teams的值匹配的ScheduleViewModel.TeamId

我最后的办法是使用Loaded的{​​{1}}事件在代码隐藏中设置StackPanel,但我想避免这种情况。有没有XAML Ninjas可以帮助我解决这个问题?

1 个答案:

答案 0 :(得分:1)

无法在XAML绑定中进行查询。在这种情况下,由于您确实有两个输入值(TeamsCurrentTeamId),因此只需使用MultiBindingIMultiValueConverter

public class FindContestByIdConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType,
                          object parameter, CultureInfo culture)
    {
        var teams = (IEnumerable<ContestTeam>)values[0];
        var teamId = (int)values[1];
        return teams.Single(t => t.TeamId == teamId);
    }

    // ConvertBack that throws NotSupportedException
    ...
}

然后是XAML:

<StackPanel>
  <StackPanel.DataContext>
    <MultiBinding Converter="{StaticResource FindContestByIdConverter}">
      <Binding Path="Teams"/>
      <Binding Path="CurrentTeamId" />
    </MultiBinding>
  </StackPanel.DataContext>
  ...
</StackPanel>