Ci sono almeno tre modi per farlo:
- Modifica colonne del DataGrid manualmente dal code-behind
- Utilizzare un DataTable come ItemsSource *
Utilizzare un CustomTypeDescriptor
* consigliato per semplicità
Primo approccio: utilizzare code-behind per generare le colonne del DataGrid in fase di esecuzione. È semplice da implementare, ma forse ti sembra un po 'schifoso, specialmente se stai utilizzando MVVM. Così si sarebbe avere il DataGrid con colonne fisse:
<DataGrid x:Name="grid">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding id}" Header="id" />
<DataGridTextColumn Binding="{Binding image}" Header="image" />
</DataGrid.Columns>
</DataGrid>
Quando hai il tuo "Nomi" pronto, quindi modificare la griglia con l'aggiunta/rimozione di colonne, ad esempio:
// add new columns to the data grid
void AddColumns(string[] newColumnNames)
{
foreach (string name in newColumnNames)
{
grid.Columns.Add(new DataGridTextColumn {
// bind to a dictionary property
Binding = new Binding("Custom[" + name + "]"),
Header = name
});
}
}
vorrete per creare una classe wrapper, che dovrebbe contenere la classe originale, oltre a un dizionario per contenere le proprietà personalizzate. Diciamo che la vostra classe di fila principale è "utente", allora che ci si vuole una classe wrapper qualcosa di simile:
public class CustomUser : User
{
public Dictionary<string, object> Custom { get; set; }
public CustomUser() : base()
{
Custom = new Dictionary<string, object>();
}
}
popolano il ItemsSource
con una collezione di questa nuova classe "CustomUser":
void PopulateRows(User[] users, Dictionary<string, object>[] customProps)
{
var customUsers = users.Select((user, index) => new CustomUser {
Custom = customProps[index];
});
grid.ItemsSource = customUsers;
}
Quindi legare insieme, per esempio:
var newColumnNames = new string[] { "Name1", "Name2" };
var users = new User[] { new User { id="First User" } };
var newProps = new Dictionary<string, object>[] {
new Dictionary<string, object> {
"Name1", "First Name of First User",
"Name2", "Second Name of First User",
},
};
AddColumns(newColumnNames);
PopulateRows(users, newProps);
2 ° approccio: usa uno DataTable. Questo fa uso dell'infrastruttura di tipo personalizzato sotto il cofano, ma è più facile da usare.Basta legare del ItemsSource
a una proprietà DataTable.DefaultView
DataGrid:
<DataGrid ItemsSource="{Binding Data.DefaultView}" AutoGenerateColumns="True" />
Quindi è possibile definire le colonne come più vi piace, ad esempio:
Data = new DataTable();
// create "fixed" columns
Data.Columns.Add("id");
Data.Columns.Add("image");
// create custom columns
Data.Columns.Add("Name1");
Data.Columns.Add("Name2");
// add one row as an object array
Data.Rows.Add(new object[] { 123, "image.png", "Foo", "Bar" });
terzo approccio: Sfruttate l'estensibilità del Sistema di tipo .Net. In particolare, utilizzare un CustomTypeDescriptor
. Questo ti permette di creare un tipo personalizzato in fase di runtime; che a sua volta ti permette di dire al DataGrid che il tuo tipo ha le proprietà "Nome1", "Nome2", ... "NomeN", o qualsiasi altra cosa tu voglia. Vedere here per un semplice esempio di questo approccio.
è l'unico modo di visualizzare queste informazioni? –
Non sono sicuro di cosa stai chiedendo. – Wr4thon
Johannes vede la mia risposta, in modo che tu possa capire perché lo stavo chiedendo. –