Logré hacer posible agregar dinámicamente una columna usando solo una línea de código como esta:
MyItemsCollection.AddPropertyDescriptor(
new DynamicPropertyDescriptor<User, int>("Age", x => x.Age));
Con respecto a la pregunta, esta no es una solución basada en XAML (ya que, como se mencionó, no hay una forma razonable de hacerlo), tampoco es una solución que funcione directamente con DataGrid.Columns. Realmente opera con DataGrid enlazado ItemsSource, que implementa ITypedList y, como tal, proporciona métodos personalizados para la recuperación de PropertyDescriptor. En un lugar en el código puede definir "filas de datos" y "columnas de datos" para su cuadrícula.
Si tuvieras:
IList<string> ColumnNames { get; set; }
//dict.key is column name, dict.value is value
Dictionary<string, string> Rows { get; set; }
podrías usar por ejemplo:
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)
y la cuadrícula que usa el enlace a MyItemsCollection se completará con las columnas correspondientes. Esas columnas se pueden modificar (nuevas agregadas o eliminadas existentes) en tiempo de ejecución dinámicamente y la cuadrícula actualizará automáticamente su colección de columnas.
DynamicPropertyDescriptor mencionado anteriormente es solo una actualización del PropertyDescriptor normal y proporciona una definición de columnas fuertemente tipada con algunas opciones adicionales. DynamicDataGridSource de lo contrario funcionaría muy bien con un PropertyDescriptor básico.
CollectionChanged
evento de la colección de columnas, sin embargo, nunca lo anula. De esa manera,DataGrid
se mantendrá vivo mientras exista el modelo de vista, incluso si la plantilla de control que contenía elDataGrid
en primer lugar ha sido reemplazada mientras tanto. ¿Hay alguna forma garantizada de cancelar el registro de ese controlador de eventos nuevamente cuandoDataGrid
ya no se requiere?dataGrid.Columns.Add(column)
DataGridColumn con el encabezado 'X' ya existe en la colección Columns de una DataGrid. DataGrids no puede compartir columnas y no puede contener instancias de columnas duplicadas.