Sono riuscito a rendere possibile l'aggiunta dinamica di una colonna usando solo una riga di codice come questa:
MyItemsCollection.AddPropertyDescriptor(
new DynamicPropertyDescriptor<User, int>("Age", x => x.Age));
Per quanto riguarda la domanda, questa non è una soluzione basata su XAML (poiché, come detto, non esiste un modo ragionevole per farlo), né è una soluzione che opererebbe direttamente con DataGrid.Columns. Funziona effettivamente con ItemsSource associato a DataGrid, che implementa ITypedList e come tale fornisce metodi personalizzati per il recupero di PropertyDescriptor. In un punto del codice è possibile definire "righe di dati" e "colonne di dati" per la griglia.
Se avessi:
IList<string> ColumnNames { get; set; }
//dict.key is column name, dict.value is value
Dictionary<string, string> Rows { get; set; }
potresti usare ad esempio:
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)
e la griglia che utilizza l'associazione a MyItemsCollection verrebbe popolata con le colonne corrispondenti. Queste colonne possono essere modificate (nuove aggiunte o esistenti rimosse) in fase di esecuzione in modo dinamico e la griglia aggiornerà automaticamente la sua raccolta di colonne.
DynamicPropertyDescriptor sopra menzionato è solo un aggiornamento al normale PropertyDescriptor e fornisce una definizione di colonne fortemente tipizzate con alcune opzioni aggiuntive. In caso contrario, DynamicDataGridSource funzionerebbe perfettamente bene con PropertyDescriptor di base.