le binding particulier d'une collection à un DataGrid
Bonjour,
je désirais binder la collection de type List<Pompe> à un datagrid de la manière suivante.
Voici la définition de la classe Pompe:
Code:
1 2 3 4 5
| public class Pompe
{
public string CodePompe { get; set;};
public ObservableColletion<Caracteristique> { get; set;};
} |
Ainsi je désirais que mon DataGrid présente les données de la manière suivante:
- Un contrôle Expander dont l'en-tête est le codepompe
- Le contrôle Expander affiche en dessous la collection de caractéristique.
Voici ce que j'ai fait pour y parvenir mais étant débutant, je galère pas mal:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
<Window.Resources>
<DataTemplate x:Key="TemplatePompe" DataType="{x:Type local:Pompe}">
<Expander x:Name="ExpTrend" IsExpanded="True" Background="White" Foreground="Black">
<Expander.Header>
<TextBlock Text="{Binding Path=CodePompe}"/>
</Expander.Header>
<ItemsPresenter />
</Expander>
</DataTemplate>
</Window.Resources>
<DataGrid ItemsSource="{Binding}" RowDetailsTemplate="{StaticResource TemplatePompe}">
<DataGrid.Columns>
<DataGridTextColumn Header="Puissance" Binding="{Binding Path=Puissance}"/>
<DataGridTextColumn Header="Tension" Binding="{Binding Path=Tension}"/>
[...]
</DataGrid.Columns>
</DataGrid> |
Initialement je voulais binder la collection de type ObservableColletion<Caracteristique> au ItemsPresenter mais ce n'est pas possible. Du coup, je ne sais pas trop comment faire.
Je me suis dit qu'il n'était peut-être pas nécessaire de faire un controltempate.
Comment puis-je faire ?
Merci d'avance,
Etienne
datagrid dans un datagrid avec expander
Bonjour etiennegaloup
Excuse -moi mais ca me rappelle Jean de La Fontaine qui disait si bien dans Le Loup et l'Agneau
" Si ce n'est toi, c'est donc ton frère.
- Je n'en ai point. - C'est donc quelqu'un des tiens
.......
Sans autre forme de procès".Il le croqua aux dires du fabuliste.
Comme l'as dit Nathanael ,tu peux mettre un itemsControl.....et faire comme le loup de la fable : l'itemsControl ou l'un des siens savoir : datagrid,listview pour ceux qui t'interessent.Tu aurais du y penser comme notre loup,parbleu...
Voic donc ta liste d'objets classe Pompe et ta liste d'objet classe Caracteristique tel que j'ai compris ta problematique :afficher une objet liste pointant sur une autre liste(en BD c'est maitre-detail) .
code commun classes Pompe et Caracteristique:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
//CODE DE LA CLASSE POMPE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;
namespace WpfDataGridViewExpanderCSharp
{
class Pompe : INotifyPropertyChanged
{
private String _CodePompe;
private ObservableCollection<Caracteristique> _lstCaracteristiques ;
public Pompe()
{
this._CodePompe = "";
this._lstCaracteristiques = new ObservableCollection<Caracteristique>();
}
public String CodePompe
{
get { return this._CodePompe; }
set
{
this._CodePompe = value ; NotifyPropertyChanged("CodePompe");
}
}
public ObservableCollection<Caracteristique> lstCaracteristiques
{
get { return this._lstCaracteristiques; }
set
{
this._lstCaracteristiques = value; NotifyPropertyChanged("lstCaracteristiques");
}
}
#region INotifyPropertyChanged Membres
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
//CODE DE LA CLASSE CARACTERISTIQUE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace WpfDataGridViewExpanderCSharp
{
class Caracteristique:INotifyPropertyChanged
{
private string _Marque;
private int _Puissance;
private int _Tension;
public Caracteristique()
{
this._Marque = "";
this._Puissance = 0;
this._Tension = 0;
}
public String Marque
{
get { return this._Marque; }
set
{
this._Marque = value; NotifyPropertyChanged("Marque");
}
}
public int Puissance
{
get { return this._Puissance; }
set
{
this._Puissance = value; NotifyPropertyChanged("Puissance");
}
}
public int Tension
{
get { return this._Tension; }
set
{
this._Tension = value; NotifyPropertyChanged("Tension");
}
}
#region INotifyPropertyChanged Membres
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
} |
code behind du winform utilisant un datagrid incorpore dans expander:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
//CODE WINFORM UTILISANT UN DATAGRID EN LIEU ET PLACE DE L'ITEMS CONTROL
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
namespace WpfDataGridViewExpanderCSharp
{
/// <summary>
/// Logique d'interaction pour Window1.xaml
/// </summary>
public partial class Window1 : Window
{
Pompe objPompe ;
Caracteristique objCaracteristique ;
ObservableCollection<Pompe> listePompes = new ObservableCollection<Pompe>();
public Window1()
{
InitializeComponent();
this.myDataGrid.ItemsSource = getData();
}
private ObservableCollection<Pompe> getData()
{
for (int i = 0; i < 5; i++)
{
objPompe = new Pompe();
objPompe.CodePompe = "Code" + (10*(i + 1)).ToString();
for (int j = 0; j < 3; j++)
{
switch (j)
{
case 0:
objCaracteristique = new Caracteristique();
objCaracteristique.Marque = "Hytorc-France";
objCaracteristique.Puissance = 500;
objCaracteristique.Tension = 1000;
objPompe.lstCaracteristiques.Add(objCaracteristique);
break;
case 1 :
objCaracteristique = new Caracteristique();
objCaracteristique.Marque = "Hydraucom";
objCaracteristique.Puissance = 200;
objCaracteristique.Tension = 380;
objPompe.lstCaracteristiques.Add(objCaracteristique);
break;
case 2:
objCaracteristique = new Caracteristique();
objCaracteristique.Marque = "HydroLeduc";
objCaracteristique.Puissance = 300;
objCaracteristique.Tension = 380;
objPompe.lstCaracteristiques.Add(objCaracteristique);
break;
default:
break;
}
}
//ajoute à Pompes
listePompes.Add(objPompe);
}
return listePompes;
}
private void btnAddPompe_Click(object sender, RoutedEventArgs e)
{
objPompe = new Pompe();
objPompe.CodePompe = "Code" + (10 * (listePompes.Count + 1)).ToString();
//Caracteristique 1
objCaracteristique = new Caracteristique();
objCaracteristique.Marque = "Hyd Pump1";
objCaracteristique.Puissance = 500;
objCaracteristique.Tension = 1000;
objPompe.lstCaracteristiques.Add(objCaracteristique);
//Caracteristique 2
objCaracteristique = new Caracteristique();
objCaracteristique.Marque = "Hyd Pump2";
objCaracteristique.Puissance = 500;
objCaracteristique.Tension = 1000;
objPompe.lstCaracteristiques.Add(objCaracteristique);
//Caracteristique 3
objCaracteristique = new Caracteristique();
objCaracteristique.Marque = "Hyd Pump3";
objCaracteristique.Puissance = 500;
objCaracteristique.Tension = 1000;
objPompe.lstCaracteristiques.Add(objCaracteristique);
//Ajoute à la liste Pompes
listePompes.Add(objPompe);
//Rebind
this.myDataGrid.ItemsSource = listePompes;
}
}
} |
code xaml du winform utilisant un datagrid incorpore dans expander:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
<Window x:Class="WpfDataGridViewExpanderCSharp.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfDataGridViewExpanderCSharp"
xmlns:my="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
Title="Pompes .Expander avec un DataGrid"
Height="300" Width="300"
>
<!--ItemsControl => dans ce Form on met un 2eme DataGrid dans l'Expander-->
<Window.Resources>
<!--Style en-tete colonnes datagrid-->
<Style
x:Key="MyColHeaderStyle">
<Setter
Property="my:DataGrid.Foreground"
Value="Blue"/>
<Setter
Property="my:DataGrid.BorderBrush"
Value="Black"/>
<Setter
Property="my:DataGrid.BorderThickness"
Value="2"/>
<Setter
Property="my:DataGrid.Background"
Value="White"/>
<Setter
Property="my:DataGrid.FontSize"
Value="14"/>
<Setter
Property="my:DataGrid.FontWeight"
Value="Bold"/>
</Style>
<!--Style lignes datagrid-->
<Style x:Key="MyRowStyle" >
<Setter
Property="my:DataGrid.Foreground"
Value="White"></Setter>
<Setter
Property="my:DataGrid.Background"
Value="Red"/>
<Setter
Property="my:DataGrid.FontFamily"
Value="Arial Bold"/>
<Setter
Property="my:DataGrid.FontSize"
Value="12"/>
<Setter
Property="my:DataGrid.FontWeight"
Value="Bold"/>
</Style>
<DataTemplate
x:Key="TemplatePompe"
DataType="{x:Type local:Pompe}">
<Expander
x:Name="ExpTrend"
IsExpanded="True"
Background="White"
Foreground="Chartreuse">
<Expander.Header>
<TextBlock
Text="{Binding Path=CodePompe}"/>
</Expander.Header>
<ScrollViewer
Height="50">
<my:DataGrid
CanUserAddRows="True"
ItemsSource="{Binding Path=lstCaracteristiques}">
</my:DataGrid>
</ScrollViewer>
</Expander>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" ></RowDefinition>
<RowDefinition Height="Auto" ></RowDefinition>
<RowDefinition Height="Auto" ></RowDefinition>
</Grid.RowDefinitions>
<Label
Grid.Row="0"
x:Name="Titre"
VerticalAlignment="Top"
HorizontalContentAlignment="Center"
FontSize="14"
FontFamily="times new roman"
FontStyle="Italic"
Background="LavenderBlush"
BorderThickness="3"
BorderBrush="BlueViolet"
Content="Expander avec un DataGrid">
</Label>
<my:DataGrid
Grid.Row="1"
x:Name="myDataGrid"
CanUserAddRows="True"
AutoGenerateColumns="True"
ColumnHeaderHeight="30"
VerticalAlignment="Top"
RowStyle="{StaticResource MyRowStyle}"
ColumnHeaderStyle="{StaticResource MyColHeaderStyle}"
ItemsSource="{Binding}"
RowDetailsTemplate="{StaticResource TemplatePompe}" />
<Button
Grid.Row="2"
Name="btnAddPompe"
Click="btnAddPompe_Click"
Width="100"
FontFamily="Arial Bold"
VerticalAlignment="Bottom"
FontSize="12">Ajouter Pompe</Button>
</Grid>
</Window> |
code behind du winform utilisant un un listview incorpore dans expander:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
//CODE WINFORM UTILISANT UN LISTVIEW EN LIEU ET PLACE DE L'ITEMS CONTROL
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
namespace WpfDataGridViewExpanderCSharp
{
/// <summary>
/// Logique d'interaction pour Window2.xaml
/// </summary>
public partial class Window2 : Window
{
Pompe objPompe ;
Caracteristique objCaracteristique ;
ObservableCollection<Pompe> listePompes = new ObservableCollection<Pompe>();
public Window2()
{
InitializeComponent();
this.myDataGrid.ItemsSource = getData();
}
private ObservableCollection<Pompe> getData()
{
for (int i = 0; i < 5; i++)
{
objPompe = new Pompe();
objPompe.CodePompe = "Code" + (10*(i + 1)).ToString();
for (int j = 0; j < 3; j++)
{
switch (j)
{
case 0:
objCaracteristique = new Caracteristique();
objCaracteristique.Marque = "Hytorc-France";
objCaracteristique.Puissance = 500;
objCaracteristique.Tension = 1000;
objPompe.lstCaracteristiques.Add(objCaracteristique);
break;
case 1 :
objCaracteristique = new Caracteristique();
objCaracteristique.Marque = "Hydraucom";
objCaracteristique.Puissance = 200;
objCaracteristique.Tension = 380;
objPompe.lstCaracteristiques.Add(objCaracteristique);
break;
case 2:
objCaracteristique = new Caracteristique();
objCaracteristique.Marque = "HydroLeduc";
objCaracteristique.Puissance = 300;
objCaracteristique.Tension = 380;
objPompe.lstCaracteristiques.Add(objCaracteristique);
break;
default:
break;
}
}
//ajoute à Pompes
listePompes.Add(objPompe);
}
return listePompes;
}
private void btnAddPompe_Click(object sender, RoutedEventArgs e)
{
objPompe = new Pompe();
objPompe.CodePompe = "Code" + (10 * (listePompes.Count + 1)).ToString();
//Caracteristique 1
objCaracteristique = new Caracteristique();
objCaracteristique.Marque = "Hyd Pump1";
objCaracteristique.Puissance = 500;
objCaracteristique.Tension = 1000;
objPompe.lstCaracteristiques.Add(objCaracteristique);
//Caracteristique 2
objCaracteristique = new Caracteristique();
objCaracteristique.Marque = "Hyd Pump2";
objCaracteristique.Puissance = 500;
objCaracteristique.Tension = 1000;
objPompe.lstCaracteristiques.Add(objCaracteristique);
//Caracteristique 3
objCaracteristique = new Caracteristique();
objCaracteristique.Marque = "Hyd Pump3";
objCaracteristique.Puissance = 500;
objCaracteristique.Tension = 1000;
objPompe.lstCaracteristiques.Add(objCaracteristique);
//Ajoute à la liste Pompes
listePompes.Add(objPompe);
//Rebind
this.myDataGrid.ItemsSource = listePompes;
}
}
} |
code xaml du winform utilisant un un listview incorpore dans expander::
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
<Window x:Class="WpfDataGridViewExpanderCSharp.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfDataGridViewExpanderCSharp"
xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit"
Title="Pompes...Expander sur un ListView"
Height="300" Width="300">
<Window.Resources>
<!--Style en-tete colonnes datagrid-->
<Style
x:Key="MyColHeaderStyle">
<Setter
Property="my:DataGrid.Foreground"
Value="Blue"/>
<Setter
Property="my:DataGrid.BorderBrush"
Value="Black"/>
<Setter
Property="my:DataGrid.BorderThickness"
Value="2"/>
<Setter
Property="my:DataGrid.Background"
Value="White"/>
<Setter
Property="my:DataGrid.FontSize"
Value="14"/>
<Setter
Property="my:DataGrid.FontWeight"
Value="Bold"/>
</Style>
<!--Style lignes datagrid-->
<Style x:Key="MyRowStyle" >
<Setter
Property="my:DataGrid.Foreground"
Value="White"></Setter>
<Setter
Property="my:DataGrid.Background"
Value="Red"/>
<Setter
Property="my:DataGrid.FontFamily"
Value="Arial Bold"/>
<Setter
Property="my:DataGrid.FontSize"
Value="12"/>
<Setter
Property="my:DataGrid.FontWeight"
Value="Bold"/>
</Style>
<!--Style colonns en-tete du GridView dans ListView-->
<Style
x:Key="grdColHeaderStyle"
TargetType="{x:Type GridViewColumnHeader}">
<Setter
Property="Background"
Value="Yellow"/>
</Style>
<DataTemplate
x:Key="TemplatePompe"
DataType="{x:Type local:Pompe}">
<Expander
x:Name="ExpTrend"
IsExpanded="True"
Background="White"
Foreground="Black">
<Expander.Header>
<TextBlock
Text="{Binding Path=CodePompe}"/>
</Expander.Header>
<ScrollViewer Height="50">
<ListView
x:Name="myListeView"
ItemsSource="{Binding Path=lstCaracteristiques}">
<ListView.View>
<GridView
x:Name="grdv"
ColumnHeaderContainerStyle="{StaticResource grdColHeaderStyle}">
<GridViewColumn
Header="Marque"
DisplayMemberBinding="{Binding Path=Marque}">
</GridViewColumn>
<GridViewColumn
Header="Puissance"
DisplayMemberBinding="{Binding Path=Puissance}">
</GridViewColumn>
<GridViewColumn
Header="Tension"
DisplayMemberBinding="{Binding Path=Tension}">
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</ScrollViewer>
</Expander>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" ></RowDefinition>
<RowDefinition Height="Auto" ></RowDefinition>
<RowDefinition Height="30" ></RowDefinition>
</Grid.RowDefinitions>
<Label
Grid.Row="0"
x:Name="Titre"
VerticalAlignment="Top"
HorizontalContentAlignment="Center"
FontSize="14"
FontFamily="times new roman"
FontStyle="Italic"
Background="LavenderBlush"
BorderThickness="3"
BorderBrush="BlueViolet"
Content="Expander avec un ListView">
</Label>
<my:DataGrid
Grid.Row="1"
x:Name="myDataGrid"
CanUserAddRows="True"
AutoGenerateColumns="True"
ColumnHeaderHeight="30" RowStyle="{StaticResource MyRowStyle}"
ColumnHeaderStyle="{StaticResource MyColHeaderStyle}"
ItemsSource="{Binding}"
RowDetailsTemplate="{StaticResource TemplatePompe}">
</my:DataGrid>
<Button
Grid.Row="2"
Name="btnAddPompe"
Click="btnAddPompe_Click"
Width="100"
FontFamily="Arial Bold"
FontSize="12">Ajouter Pompe</Button>
</Grid>
</Window> |
NB: la reference my:DataGrid vient de ce que je suis sous VS 2008 qui ne possede pas le controle DataGrid et j'utilise donc le controle DataGrid provenant du ToolKit WPF d'espace de nom : xmlns:my=" ...
Si tu est sous VS 2010 qui possede le DataGrid supprime la reference d'espace de nom xmlns:my="... et les reference my precedent le nom du controle DataGrid........
bon code..............
cacher les Rows,montrer Details
Rebonjour etiennegaloup
Absolument.
Voyons,tu veux d'une part cacher les rows et d'autre part voir les details plus l'expander.Ils y ont pense.
L'astuce: RowHeight=0 et CanUserResizeRows="False" sinon l'user peut voir les "rows" en manipulant la souris.
Pour voir les details:RowDetailsVisibilityMode="Visible" et qui reste "collapsable" bien entendu....
Il suffit de modifier le code du datagrid principal que je reposte:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
<!--Rajouter RowHeight="0"
CanUserResizeRows="False"
RowDetailsVisibilityMode="Visible"-->
<my:DataGrid
Grid.Row="1"
x:Name="myDataGrid"
CanUserAddRows="True"
AutoGenerateColumns="True"
ColumnHeaderHeight="30"
RowHeight="0"
CanUserResizeRows="False"
RowDetailsVisibilityMode="Visible"
RowStyle="{StaticResource MyRowStyle}"
ColumnHeaderStyle="{StaticResource MyColHeaderStyle}"
ItemsSource="{Binding}"
RowDetailsTemplate="{StaticResource TemplatePompe}">
</my:DataGrid>
<Button
Grid.Row="2"
Name="btnAddPompe"
Click="btnAddPompe_Click"
Width="100"
FontFamily="Arial Bold"
FontSize="12">Ajouter Pompe</Button> |
"La raison du plus fort est toujours la meilleure :
Nous l'allons montrer tout à l'heure."
Etiennegaloup dixit Jean de La Fontaine,si je peux me permettre.....
bon code.........
lier largeur colonne du datagrid detail au datagrid maitre
Bonjour etiennegaloup
Je n'ai pas bien compris.
Etant donne que les colonnes Detail appartiennent à la classe Caracteristique et les colonnes Maitre appartiennent à la classe Pompe ,je ne vois pas comment lier des largeurs de colonnes isssues de classes differentes,les index de colonnes n'etant pas simplement en correlation(nbre de colonne affichees differe d'une classe à l'autre).
la meme remarque s'impose quant au deplacement de colonne ou ReorderingColumn.
bon code....