J'ai réussi à rendre possible l'ajout dynamique d'une colonne en utilisant juste une ligne de code comme ceci :
MyItemsCollection.AddPropertyDescriptor(
new DynamicPropertyDescriptor<User, int>("Age", x => x.Age));
En ce qui concerne la question, il ne s'agit pas d'une solution basée sur XAML (puisque, comme indiqué, il n'existe pas de moyen raisonnable de le faire), ni d'une solution qui fonctionnerait directement avec DataGrid.Columns. Elle fonctionne en fait avec DataGrid bound ItemsSource, qui implémente ITypedList et, en tant que tel, fournit des méthodes personnalisées pour la récupération des PropertyDescriptor. En un seul endroit du code, vous pouvez définir les "lignes de données" et les "colonnes de données" de votre grille.
Si vous l'aviez fait :
IList<string> ColumnNames { get; set; }
//dict.key is column name, dict.value is value
Dictionary<string, string> Rows { get; set; }
que vous pourriez utiliser par exemple :
var descriptors= new List<PropertyDescriptor>();
//retrieve column name from preprepared list or retrieve from one of the items in dictionary
foreach(var columnName in ColumnNames)
descriptors.Add(new DynamicPropertyDescriptor<Dictionary, string>(ColumnName, x => x[columnName]))
MyItemsCollection = new DynamicDataGridSource(Rows, descriptors)
et votre grille utilisant la liaison à MyItemsCollection sera peuplée des colonnes correspondantes. Ces colonnes peuvent être modifiées (ajout de nouvelles colonnes ou suppression de colonnes existantes) au moment de l'exécution de manière dynamique et la grille rafraîchira automatiquement sa collection de colonnes.
DynamicPropertyDescriptor mentionné ci-dessus n'est qu'une mise à niveau du PropertyDescriptor ordinaire et fournit une définition des colonnes fortement typées avec quelques options supplémentaires. DynamicDataGridSource fonctionnerait autrement très bien avec le PropertyDescriptor de base.