2009-07-20 4 views
2

Récemment, um, j'ai été châtié pour générer et charger le balisage XAML à l'exécution en utilisant XamlReader.Parse(). On m'a dit qu'il n'y a aucune raison d'utiliser XamlReader - cela peut toujours être fait avec du XAML statique, prédéterminé au moment du design.Est-il possible de configurer un GridView pour afficher des données pivotées en utilisant XAML statique si les informations de colonne sont inconnues au moment du design?

J'ai essayé de demander à cette personne comment je pourrais construire un GridView pour montrer des données pivotées, où le nombre de colonnes et le chemin de liaison pour chaque colonne est inconnu au moment du design. Je n'ai pas encore entendu, mais même si je l'ai fait, j'ai pensé que ce serait une question intéressante à poser, car cela pourrait ouvrir mes yeux (et ceux des autres) à une meilleure façon de faire les choses.

Ma situation spécifique: Chaque "participant" doit effectuer un certain nombre de "blocs", mais je ne sais pas combien de blocs il y aura jusqu'à ce que j'attrape ces données de la base de données. Avec ce contexte à l'esprit, mon objectif est de montrer un GridView qui a les colonnes suivantes:

Participant | Block 1 | Block 2 | ... | Block N | 
(where N is the total number of blocks) 

Ma stratégie actuelle est de boucle dynamique à travers les blocs. Pour chaque bloc, j'instancie un nouveau GridViewColumn, génère un XAML personnalisé pour former un DataTemplate basé sur le BlockIndex, et utilise XamlReader.Parse() pour définir le CellTemplate de la colonne.

Voici le code, juste pour vous assurer que je suis être clair:

public void AddParticipantGridViewColumns() 
{ 
    GridView view = (GridView)_participantListView.View; 
    GridViewColumn column; 
    SetupViewModel setupViewModel = (SetupViewModel)DataContext; 
    foreach (int blockIndex in setupViewModel.BlockIndices) 
    { 
     column = BuildParticipantGridViewColumn(blockIndex); 
     view.Columns.Add(column); 
    } 
} 

public virtual GridViewColumn BuildParticipantGridViewColumn(int blockIndex) 
{ 
    string templateXaml = string.Format(@" 
     <DataTemplate 
      xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" 
      xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" 
      xmlns:local=""clr-namespace:Pse.ExperimentBase;assembly=ExperimentBase"">   
      <DataTemplate.Resources> 
       <local:BlockToBrushConverter 
        x:Key=""_blockToBrushConverter"" /> 
      </DataTemplate.Resources> 
      <TextBlock 
       Style=""{{StaticResource _gridViewCenterItemStyle}}"" 
       Text=""{{Binding Path=Block{0}.ConditionLabel}}"" 
       Foreground=""{{Binding Path=Block{0}, Converter={{StaticResource _blockToBrushConverter}}}}"" /> 
     </DataTemplate>", 
     blockIndex); 
    GridViewColumn column = new GridViewColumn(); 
    column.Header = string.Format("Block {0}", blockIndex); 
    column.CellTemplate = (DataTemplate)XamlReader.Parse(templateXaml); 
    return column; 
} 

est-il un moyen intelligent que je pouvais le faire avec XAML statique seul ou est une solution dynamique, comme celui que je présentais ici, le seul moyen pratique de le faire? De plus, s'il y a une solution statique, préféreriez-vous la remplacer par la solution dynamique?

Merci,

-Dan

Répondre

0

Je ne pense pas qu'il y ait un moyen simple de le faire entièrement en XAML, mais il existe certainement une solution plus statique que le vôtre. Le problème principal n'est pas que vous essayez de configurer dynamiquement votre GridView dans le code-behind (ce qui est normal avec un problème comme celui-ci), mais que vous utilisez le même code XAML N fois dans le code -derrière. Un DataTemplate tel que celui-ci doit toujours être trouvé dans un fichier de marquage, pas comme une chaîne dans une méthode. Dans votre exemple, il semble que vous deviez définir le modèle de données dans le fichier XAML où votre _participantListView est défini.

+0

@Charlie, merci pour votre réponse. Je dois corriger une chose, cependant. Ce n'est pas le même balisage XAML à chaque fois. Chaque DataTemlate possède des chemins de liaison uniques pour les propriétés Text et Foreground du TextBlock. – devuxer

+0

Dans ce cas, MVVM vous permet de convertir ces objets éclectiques très riches en quelque chose d'uniforme, puis de les lier à la collection d'objets uniformes. –

+0

@Oleg, je ne pense pas que je comprends ce que vous dites. Chaque DataTemplate suit un modèle similaire, mais les chemins de liaison sont différents. Voulez-vous dire que le chemin de liaison devrait être contraignant? – devuxer

Questions connexes