J'ai besoin de modifier DataGrid de sorte que chaque en-tête de colonne ait une zone de texte, une liste déroulante et une case à cocher, et tous doivent être liés à une propriété. J'ai passé beaucoup de temps à essayer de l'implémenter avec un DataGrid par défaut, mais je ne pense pas que ce soit possible, j'ai donc décidé de créer un DataGrid personnalisé.Comment lier des colonnes DataGrid personnalisées
Jusqu'à présent, j'ai une propriété de liaison BindableColumns
qui stocke DataTable
, donc j'ai les données que j'ai besoin d'afficher. Le problème est que je ne sais pas comment passer ces données à OnAutoGeneratedColumns
, donc je peux ajouter des colonnes à la propriété Columns
de DataGrid
.
public class BindableGrid : DataGrid
{
public DataTable BindableColumns
{
get { return (DataTable)GetValue(BindableColumnsProperty); }
set { SetValue(BindableColumnsProperty, value); }
}
public static readonly DependencyProperty BindableColumnsProperty =
DependencyProperty.Register("BindableColumns", typeof(DataTable), typeof(BindableGrid), new PropertyMetadata(null, BindableColumnsPropertyChanged));
private static void BindableColumnsPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
// This is where I get DataTable after binding
}
protected override void OnAutoGeneratedColumns(EventArgs e)
{
// This is where I need the DataTable to generate columns.
// I don't know how to invoke this method myself.
Columns.Add(new DataGridTemplateColumn
{
Header = "Test1",
HeaderTemplate = new DataTemplate()
});
}
}
Et XAML:
<controls:BindableGrid ItemsSource="{Binding Data}" BindableColumns="{Binding Data}" AutoGenerateColumns="True">
</controls:BindableGrid>
EDIT:
Merci à @Ramin je colonnes de travail. J'ai eu quelques problèmes avec l'ajout dynamique de lignes, car DataGrid
attend des lignes en tant que classe avec exactement les mêmes noms de variables que les liaisons de la colonne. Pour toute personne ayant des problèmes, voici comment je l'ai résolu:
for (var rowIndex = 0; rowIndex < data.Rows.Count; rowIndex++)
{
dynamic row = new ExpandoObject();
for (var i = 0; i < data.Columns.Count; i++)
// Create variables named after bindings, and assign values
((IDictionary<string, object>)row)[data.Columns[i].ColumnName.Replace(' ', '_')] = data.Rows[rowIndex].ItemArray[i];
// Add row to DataGrid
dg.Items.Add(row);
}
Est-ce que cela fonctionnera pour un tableau de colonnes? Parce que je ne sais pas combien de colonnes je vais avoir dans mon 'DataTable'. Je laisse l'utilisateur charger les fichiers csv qui sont convertis en 'DataTable', donc le nombre de colonnes est différent pour chaque fichier. – FCin
voir la partie modifiée. – Ron
Je l'ai presque réussi à travailler, mais je ne peux pas ajouter dynamiquement des lignes, à cause de la reliure. 'dg.Items.Add();' nécessite un objet avec des propriétés nommées comme les bindings, mais en C# je ne peux pas créer dynamiquement des classes. – FCin