2010-11-05 5 views
0

J'ai un contrôle de grille de propriété qui a de nombreux éditeurs de cellules qui est automatiquement appliqué en utilisant un CellEditorTemplateSelector. Chaque ligne de la grille de propriétés est liée à un PropertyItemViewModel simple.Comment lier un DataGridTemplateColumn à une valeur de colonne au lieu d'une valeur de ligne?

Maintenant, j'essaie de réutiliser tous ces éditeurs de cellules et de les présenter dans un DataGrid pour pouvoir comparer plusieurs valeurs d'objets côte à côte. J'ai donc ajouté un objet PropertiesRow qui contient une liste de PropertyItemViewModel (identique à la grille de propriétés ci-dessus).

Pour présenter chaque cellule, j'ai un modèle de données simple qui utilise le même sélecteur de modèle que la grille de propriétés.

<DataTemplate x:Key="CellDataTemplate"> 
    <ContentControl 
     Content="{Binding Mode=OneWay}" 
     ContentTemplateSelector="{StaticResource CellEditorTemplateSelector}" />    
</DataTemplate> 

Cependant, pour que cela fonctionne, le modèle prévoit une PropertyItemViewModel (pas le PropertiesRow), donc je dois nourrir en quelque sorte à travers une liaison qui récupère le bon de PropertiesRow.PropertyItems[columnIndex]. Alors, quand j'ajouter les colonnes dans le code, j'ai essayé quelque chose comme ceci:

void AddColumns() 
{ 
    foreach (Property shownProperty in _ShownProperties) 
    { 
     _DataGrid.Columns.Add(new DataGridTemplateColumn() 
     { 
      Header = shownProperty.Name; 
      Binding = new Binding("PropertyItems[" + index + "]"); 
      CellTemplate = (DataTemplate) FindResource("CellDataTemplate"); 
     }); 
    } 
} 

Cependant, DataGridTemplateColumn n'a pas de propriété Binding! J'ai donc essayé de générer un DataTemplate intermédiaire pour chaque colonne, mais cela commence à être très complexe, et je pense qu'il doit y avoir une façon plus simple de le faire.

Des suggestions?

Répondre

0

J'ai trouvé un moyen de le faire, ce qui n'est pas propre aux standards MVVM car il joue directement avec les DataGridCells, mais ça marche bien dans le cas contraire.

J'ai quitté mon modèle cellulaire tel qu'il est, sauf qu'au lieu de le laisser lié à mon objet PropertiesRow, qui n'a pas d'indication dont la colonne où nous sommes, je lie l'aide d'une source par rapport liant à la société mère DataGridCell:

<DataTemplate x:Key="CellDataTemplate"> 
    <ContentControl 
     Content="{Binding Mode=OneWay, 
    RelativeSource={RelativeSource FindAncestor, 
           AncestorType={x:Type Controls:DataGridCell}}, 
    Converter={StaticResource CellToColumnValueConverter}}}" 
     ContentTemplateSelector="{StaticResource CellEditorTemplateSelector}" />    
</DataTemplate> 

J'ai ensuite ajouté une CellToColumnValueConverter qui prend la DataGridCell et la transforme en un PropertyItem en utilisant l'indice de la colonne:

public class CellToColumnValueConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     DataGridCell cell = (DataGridCell) value; 
     int displayIndex = cell.Column.DisplayIndex; 
     PropertiesRow r = (PropertiesRow) cell.DataContext; 
     return r.PropertyItems[displayIndex]; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
2

j'avais des problèmes avec le XAML ci-dessus mais je m'y suis que cela fonctionne. A dû mettre Path='' ou le compilateur était mécontent.

Content="{Binding Mode=OneWay, Path='', 
        RelativeSource={RelativeSource FindAncestor, AncestorType=DataGridCell, 
            AncestorLevel=1}, 
        Converter={StaticResource CellToColumnValueConverter}}" 
Questions connexes