2010-02-08 5 views
3

J'ai une fenêtre principale avec un seul contrôle utilisateur, appelé SuperMode. SuperMode se compose d'une collection de personnes et chaque personne dans cette collection a sa propre collection de tâches. Cela semble simple, non?WPF: ItemsControl et DataContext

À partir du fichier SuperMode.xaml:

<UserControl 
    x:Class="Prototype.SuperMode" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:Prototype" 
    DataContext="{Binding RelativeSource={RelativeSource Self}}"> <!-- NOTE! --> 
    <!-- Look at how I'm setting the DataContext, as I think it's 
     important to solve the problem! --> 

    <ScrollViewer CanContentScroll="True"> 
     <ItemsControl ItemsSource="{Binding People}" Margin="1"> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <UniformGrid Rows="1"/> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
     </ItemsControl> 
    </ScrollViewer> 

</UserControl> 

Cela fonctionne bien et je peux voir quatre personnes comme je le pense! Maintenant tout ce que j'ai à faire est d'obtenir le bon XAML pour le contrôle utilisateur Person de sorte que toutes leurs tâches sont également affichées.

Comme vous pouvez le voir, j'utilise la propriété People pour remplir le contrôle avec des éléments. La propriété est de type PeopleObservableCollection<Person>, où Person est un autre contrôle utilisateur en tant que telle ...

De Person.xaml:

<UserControl 
    x:Class="Prototype.Person" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:Prototype"> 

    <Border Background="Black" CornerRadius="4" Margin="1"> 
     <ItemsControl ItemsSource="{Binding Tasks}"> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <StackPanel/> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
     </ItemsControl> 
    </Border> 

</UserControl> 

Tasks ici est une propriété de Person avec le type ObservableCollection<Task>. C'est là que ça se coince! Apparemment, WPF ne peut pas trouver des biens Tasks et en regardant la fenêtre de sortie de VS2008, je trouve ce qui suit:

System.Windows.Data Error: 39 : BindingExpression path error: 'Tasks' property not found on 'object' ''SuperMode' (Name='SuperMode')'. BindingExpression:Path=Tasks; DataItem='SuperMode' (Name='SuperMode'); target element is 'ItemsControl' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')

Maintenant, je suis perdu. Il semble que je dois définir l'attribut DataContext sur chaque Person, sinon il pensera toujours que le contexte de données est SuperMode, mais comment faire?

Répondre

4

Ignorant la conception plutôt désagréable que vous avez (vous devriez regarder dans MVVM), vous devriez être en mesure de régler le DataContext pour l'enfant UserControl s comme suit:

<ItemsControl ItemsSource="{Binding People}" Margin="1"> 
    <ItemsControl.ItemContainerStyle> 
     <Style> 
      <Setter Property="FrameworkElement.DataContext" Value="{Binding RelativeSource={RelativeSource Self}}"/> 
     </Style> 
    </ItemsControl.ItemContainerStyle> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <UniformGrid Rows="1"/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ItemsControl> 
+0

Merci, je vais essayer et reviens à toi. Avez-vous un lien vers un bon endroit où je peux voir un exemple concret de MVVM en action avec le code source et l'explication? –

+0

Essayez ceci: http://msdn.microsoft.com/fr-fr/magazine/dd419663.aspx –

Questions connexes