2009-08-26 9 views
0

J'ai une classe comme ceci:XAML: se lier à un seul enfant dans une collection

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

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

Et mon modèle de vue ressemble à ceci:

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

Mon XAML ressemble à ceci:

<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> 

Essentiellement, donc je peux continuer à développer, j'ai créé un convertisseur de valeur (CurrentTeam) et codés en dur le TeamId que le ConverterParameter afin que je puisse continuer à développer la vue. Mais je suis dans une impasse. Y at-il un moyen (en utilisant XAML) de lier le DataContext du StackPane l au ContestTeam dans la collection Teams qui correspond à la valeur de ScheduleViewModel.TeamId?

Mon dernier recours sera de simplement utiliser l'événement Loaded du StackPanel pour définir DataContext dans le code-behind, mais je voudrais éviter cela. Y a-t-il des Ninjas XAML qui peuvent m'aider à comprendre cela?

+0

Vous pouvez créer un 'IValueConverter' qui dérive de 'DependencyObject' et a' DependencyProperty' qui contient le 'Id' pour' Silverlight'. – Mohsen

Répondre

1

Il n'existe aucun moyen d'effectuer des requêtes dans les liaisons XAML. Dans ce cas, puisque vous avez vraiment deux valeurs d'entrée (Teams et CurrentTeamId), il suffit d'utiliser un MultiBinding et un IMultiValueConverter:

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 
    ... 
} 

puis XAML:

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

Silverlight ne supporte pas encore la multi-liaison - mais j'ai trouvé ce lien: http: //www.scottlogic.co.uk/blog/wpf/2009/06/silverlight-multibindings-how-to-attached-mutiple-bindings-to -a-single-property/ –

+0

Comment implémenter 'ConvertBack' – Mohsen

+0

Pour la plupart des multibindings, il n'y a vraiment aucun moyen de recréer les deux (ou plus) valeurs originales de la finale, donc vous n'avez qu'à lancer NotSupportedException, et c'est tout. Si vous avez besoin d'une liaison bidirectionnelle, vous devez décrire exactement comment vous vous attendez à ce qu'il fonctionne avant de pouvoir répondre à cette question. –

Questions connexes