2010-12-06 14 views
5

J'utilise une norme .NET DataGrid comme ceci:prisme/MVVM: lier des colonnes à DataGrid

<DataGrid ItemsSource="{Binding Datensaetze}" AutoGenerateColumns="False"> 
<DataGrid.Columns> 
    <DataGridTextColumn Header="my col 1" Binding="{Binding MyCol1}"/> 
    <DataGridTextColumn Header="my col 2" Binding="{Binding MyCol2}"/> 
    <DataGridTextColumn Header="my col 3" Binding="{Binding MyCol3}"/> 
</DataGrid.Columns> 
</DataGrid> 

Cela fonctionne bien. Maintenant, je veux définir les colonnes dans le ViewModel, et au lieu de définir des colonnes fixes dans xaml, je veux les générer à la volée. Toutefois, si j'essaie de lier les colonnes à tout ce que j'obtiens une erreur, en disant

DataGrid.Columns est une propriété en lecture seule et ne peut pas être lié.

Y at-il un moyen de lier dynamiquement les colonnes DataGrid à quelque chose dans le code derrière?

Répondre

9

Oui, la propriété Columns est ReadOnly, donc nous ne pouvons pas la lier directement. Si vous souhaitez lier des colonnes, vous pouvez essayer d'utiliser une propriété jointe à laquelle vous vous liez, qui à son tour met à jour les colonnes.

Mise à jour
En utilisant delta des changements en cas CollectionChanged.

Ensuite, vous pouvez lier la propriété BindableColumns à votre ColumnsCollection

<DataGrid AutoGenerateColumns="False" 
      local:DataGridColumnsBehavior.BindableColumns="{Binding ColumnCollection}"> 
    <!-- ... --> 
</DataGrid> 
+0

Je me sers de cette amende, mais j'ai couru dans un problème où je dois mettre à jour le ObservableCollection sur un fil de fond (J'utilise le Dispatcher pour faire ça). Le code ci-dessus tombe alors dans le délégué CollectionChanged avec l'erreur "Le thread appelant ne peut pas accéder à cet objet car un thread différent le possède". Des suggestions que je peux faire? –

+0

Je suis dans la même situation qu'Andrew Stephens. Je ne peux pas trouver un moyen de contourner cela. Quelqu'un aide-t-il? – ncourcy84

+0

Je pense que vous devez d'abord séparer la source des éléments avant de pouvoir la mettre à jour dans le fil d'arrière-plan. Vous ne pouvez accéder à aucun objet lié à une interface utilisateur (avec raisepropertychanged/collectionchanged) dans le thread d'arrière-plan. Une autre option consiste à utiliser un objet différent que vous devez modifier/accéder dans le thread d'arrière-plan. Utilisez ensuite Continuer avec (si vous utilisez la tâche), puis passez cet objet au bloc ContinueWith. – Lance