2009-07-06 10 views
5

Je suis en train d'implémenter le pattern MVVC et j'ai du mal à lier une propriété dans le viewmodel depuis un DataTemplate dans une grille de données. Si j'ai un bloc de texte en dehors du DataTemplate dans la colonne, cela fonctionne bien (puisque je référence directement le datacontext du UserConrol, c'est-à-dire la machine virtuelle) mais à partir du DataTemplate il ne retournera pas la propriété de texte brut. Il retournera cependant une propriété de l'élément IEnumerable itéré.Silverlight DataGrid.Celltemplate Liaison à ViewModel

<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" 
    x:Class="Timesheet.Silverlight.Modules.Views.HistoryView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:Commands="clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;assembly=Microsoft.Practices.Composite.Presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:ViewModels="clr-namespace:Timesheet.Silverlight.Modules.ViewModels" 
    x:Name="View"> 
    <StackPanel>    
    <TextBlock Text="{Binding Path=DataContext.testText, ElementName=View}" />  
      <data:DataGrid Height="280" Width="500" ItemsSource="{Binding TimeSlots}" AutoGenerateColumns="False" >       
      <data:DataGrid.Columns> 
       <data:DataGridTextColumn Header="Allocation Area" Binding="{Binding TimeAllocationArea.TimeAllocationName}" Width="200" /> 
       <data:DataGridTextColumn Header="Start" Binding="{Binding StartTime}" Width="80" /> 
       <data:DataGridTextColumn Header="End" Binding="{Binding Path=DataContext.testText, ElementName=View}" Width="80" /> 
       <data:DataGridTemplateColumn Header="Modify" Width="200" > 
        <data:DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <StackPanel Orientation="Horizontal"> 
           <TextBlock Text="{Binding Path=DataContext.testText, ElementName=View}" /> 
          </StackPanel> 
         </DataTemplate> 
        </data:DataGridTemplateColumn.CellTemplate> 
       </data:DataGridTemplateColumn> 
      </data:DataGrid.Columns> 
     </data:DataGrid>  
    </StackPanel> 
</UserControl> 

Existe-t-il une sorte de problème avec le DataTemplate? Notez que "{Binding Path = DataContext.testText, ElementName = View}" fonctionne pour tous les éléments à l'exception de celui dans le DataTemplate. (Note Je sais que le 1er Textblock en dehors de la DG n'a pas besoin de ElementName etc mais je viens de le faire de cette façon pour me prouver qu'il fait référence à la bonne chose)

Répondre

2

Je ne sais pas si cela s'applique à SL, mais vous pouvez vérifier ceci:

"La collection de Columns est juste une propriété dans le Datagrid, cette collection n'est pas dans l'arbre logique (ou visuel), donc le DataContext n'est pas hérité, ce qui conduit à ce qu'il n'y ait rien se lier à. "

http://blogs.msdn.com/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx

+1

Le message de Jaime est spécifique à WPF mais explique définitivement pourquoi cela ne fonctionne pas dans WPF et Silverlight. Toutefois, la solution de contournement dans la publication de Jaime ne fonctionnera pas pour la liaison de données élément à élément, donc cela ne résout pas ce problème. –

1

Vous pouvez toujours lier des données aux ressources statiques dans vos DataTemplates même lorsque les données élément à élément de liaison ne fonctionne pas. Une méthode permettant aux vues de référencer le modèle de vue dans le modèle MVVM est de stocker le modèle de vue dans une ressource statique, telle que ViewModelLocator utilisé par le MVVM Light Toolkit.

En supposant que votre modèle d'affichage s'appelle TestViewModel, je peux modifier votre exemple XAML pour utiliser un ViewModelLocator et finir avec ceci.

<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" 
    x:Class="Timesheet.Silverlight.Modules.Views.HistoryView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:Commands="clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;assembly=Microsoft.Practices.Composite.Presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:ViewModels="clr-namespace:Timesheet.Silverlight.Modules.ViewModels" 
    x:Name="View" 
    DataContext="{Binding TestViewModel, Source={StaticResource Locator}}" 
    > 
    <StackPanel>    
     <TextBlock Text="{Binding Path=DataContext.testText, ElementName=View}" />  
     <data:DataGrid Height="280" Width="500" ItemsSource="{Binding TimeSlots}" AutoGenerateColumns="False" >       
      <data:DataGrid.Columns> 
       <data:DataGridTextColumn Header="Allocation Area" Binding="{Binding TimeAllocationArea.TimeAllocationName}" Width="200" /> 
       <data:DataGridTextColumn Header="Start" Binding="{Binding StartTime}" Width="80" /> 
       <data:DataGridTextColumn Header="End" Binding="{Binding Path=DataContext.testText, ElementName=View}" Width="80" /> 
       <data:DataGridTemplateColumn Header="Modify" Width="200" > 
        <data:DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <StackPanel Orientation="Horizontal"> 
           <!--<TextBlock Text="{Binding Path=DataContext.testText, ElementName=View}" />--> 
           <TextBlock Text="{Binding Source={StaticResource Locator}, Path=TestViewModel.testText}" /> 
          </StackPanel> 
         </DataTemplate> 
        </data:DataGridTemplateColumn.CellTemplate> 
       </data:DataGridTemplateColumn> 
      </data:DataGrid.Columns> 
     </data:DataGrid>  
    </StackPanel> 
</UserControl> 
Questions connexes