En savoir plus sur Xceed DataGrid pour WPF
Cette semaine, nous allons jeter un coup d'œil rapide au regroupement et au tri dans la grille de données pour WPF.
Regroupement au moment de l'exécution
Par défaut, lorsqu'un Contrôle DataGrid est créé, il contient un HierarhicalGroupByControl dans sa section d'en-têtes fixes. Le contrôle group-by offre une vue condensée des niveaux de groupe et permet aux utilisateurs finaux de modifier les descriptions de groupe appliquées à une grille.
Chaque niveau de groupe est représenté par un HierarchicalGroupByItem (groupe hiérarchique par élément) qui peut être utilisée pour modifier l'ordre des groupes, trier les éléments de données ou supprimer complètement les groupes. Si un groupe ColumnManagerRow est présent dans une grille (quel que soit son emplacement), ses cellules (Gestionnaire de colonnesCell) peut être glissé sur le contrôle group-by pour créer un niveau de groupe supplémentaire.
Définition des descriptions de groupes dans le CollectionView
Les éléments de données peuvent être regroupés en ajoutant des PropertyGroupDescription objets ou DataGridGroupDescription (recommandé) à l'objet Description des groupes de la propriété DataGridCollectionViewSource ou DataGridCollectionView à laquelle une grille est liée.
Dans l'exemple suivant, nous regroupons les commandes par pays et ville d'expédition :
<Grid xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid">
<Grid.Resources>
<xcdg:DataGridCollectionViewSource x:Key="cvs_orders"
Source="{Binding Source={x:Static Application.Current},Path=Orders}">
<xcdg:DataGridCollectionViewSource.GroupDescriptions>
<xcdg:DataGridGroupDescription PropertyName="ShipCountry"/>
<xcdg:DataGridGroupDescription PropertyName="ShipCity"/>
</xcdg:DataGridCollectionViewSource.GroupDescriptions>
</xcdg:DataGridCollectionViewSource>
</Grid.Resources>
<xcdg:DataGridControl x:Name="OrdersGrid"
ItemsSource="{Binding Source={StaticResource cvs_orders}}">
</xcdg:DataGridControl>
</Grid>
Note : Il est également possible de faire la même chose avec un DataGridDetailDescription, et/ou directement par la propriété Items en spécifiant le nom du champ de la colonne dont les valeurs doivent être regroupées. Chaque DataGridGroupDescription qui est ajouté à cette collection représente les caractéristiques d'un niveau de groupe dans une grille.
Groupement personnalisé
Il est également possible de créer une description de groupe personnalisée en dérivant de l'élément DataGridGroupDescription et en surchargeant la classe Nom du groupe à partir de l'élément méthode. Une fois mis en œuvre, un Comparateur de tri peuvent lui être attribuées.
Tout d'abord, nous devons créer notre description de groupe personnalisée :
public class AlphabeticalGroupDescription : DataGridGroupDescription
{
public AlphabeticalGroupDescription()
: base()
{
}
public AlphabeticalGroupDescription( string propertyName )
: base( propertyName )
{
}
public override object GroupNameFromItem( object item, int level, System.Globalization.CultureInfo culture )
{
object value = base.GroupNameFromItem( item, level, culture );
try
{
string content = Convert.ToString( value );
value = content.ToUpper().Substring( 0, 1 );
}
catch( InvalidCastException )
{
}
return value;
}
}
Ensuite, nous l'ajoutons à notre DataGridCollectionViewSource :
<Grid.Resources>
<local:ConsonantVowelComparer x:Key="consonantVowelComparer"/>
<xcdg:DataGridCollectionViewSource x:Key="cvs_orders"
Source="{Binding Source={x:Static Application.Current}, Path=Orders}">
<xcdg:DataGridCollectionViewSource.GroupDescriptions>
<local:AlphabeticalGroupDescription PropertyName="ShipCountry"
SortComparer="{StaticResource consonantVowelComparer}"/>
</xcdg:DataGridCollectionViewSource.GroupDescriptions>
</xcdg:DataGridCollectionViewSource>
</Grid.Resources>
Prévenir les regroupements
Il est possible d'empêcher l'utilisateur de modifier les groupes, de sorte que les groupes que vous appliquez ne puissent pas être supprimés ou ajoutés. Pour ce faire, il convient d'utiliser l'option AllowGroupingModification sur la propriété GroupByControl.
Étant donné que nous redéfinissons les en-têtes fixes, nous devons définir UseDefaultHeadersFooters à false et ajouter manuellement les en-têtes que nous voulons.
Par exemple :
<xcdg:DataGridControl x:Name="OrdersGrid"
ItemsSource="{Binding Source={StaticResource cvs_orders}}">
<xcdg:DataGridControl.View>
<xcdg:TableView UseDefaultHeadersFooters="False">
<xcdg:TableView.FixedHeaders>
<DataTemplate>
<xcdg:GroupByControl AllowGroupingModification="False" />
</DataTemplate>
<DataTemplate>
<xcdg:ColumnManagerRow />
</DataTemplate>
</xcdg:TableView.FixedHeaders>
</xcdg:TableView>
</xcdg:DataGridControl.View>
</xcdg:DataGridControl>
Tri au moment de l'exécution
Lorsqu'un Contrôle DataGrid est créé, il contient par défaut un ColumnManagerRow dans sa section d'en-têtes fixes qui contient un ColumnManagerCell pour chaque colonne d'une grille. Le contenu d'une ou de plusieurs colonnes peut être trié en cliquant sur le bouton correspondant. ColumnManagerCell.
Par défaut, un premier clic permet de trier les valeurs de la colonne dans le sens croissant, un deuxième clic permet de les trier dans le sens décroissant, tandis qu'un troisième clic permet de supprimer tout tri appliqué aux valeurs de la colonne. Pour trier les valeurs de plusieurs colonnes, maintenez la touche MAJ enfoncée tout en cliquant sur une colonne. ColumnManagerCell. Le cycle de tri-direction peut être modifié en attribuant à une colonne une nouvelle valeur de SortDirectionCycle ou en gérant la collection Changement de direction du tri événement.
Définition des descriptions de tri dans le CollectionView
Les données peuvent être triées en ajoutant SortDescription aux objets de la SortDescriptions de la propriété DataGridCollectionViewSource ou DataGridCollectionView à laquelle une grille est liée.
Dans l'exemple suivant, nous regroupons les commandes par pays et ville d'expédition :
<Grid xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid">
<Grid.Resources>
<xcdg:DataGridCollectionViewSource x:Key="cvs_orders"
Source="{Binding Source={x:Static Application.Current}, Path=Orders}">
<xcdg:DataGridCollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="ShipCountry"
Direction="Ascending"/>
</xcdg:DataGridCollectionViewSource.SortDescriptions>
</xcdg:DataGridCollectionViewSource>
</Grid.Resources>
<xcdg:DataGridControl x:Name="OrdersGrid"
ItemsSource="{Binding Source={StaticResource cvs_orders}}">
<xcdg:DataGridControl.Columns>
<xcdg:Column FieldName="ShipCountry" VisiblePosition="0"/>
</xcdg:DataGridControl.Columns>
</xcdg:DataGridControl>
</Grid>
Il est également possible de le faire directement via la propriété Items, en spécifiant le nom du champ de la colonne dont les valeurs doivent être triées, ainsi que le sens dans lequel ces valeurs doivent être triées.
Tri personnalisé
En plus du tri par défaut basé sur le type, il est également possible d'appliquer un tri personnalisé en fournissant un paramètre IComparateur à la Comparateur de tri d'une ou plusieurs propriétés de l'élément définies dans le fichier DataGridCollectionView ou DataGridCollectionViewSource auquel une grille est liée Le comparateur sera utilisé chaque fois que les valeurs de la colonne correspondante de la propriété de l'élément seront triées, par exemple lorsque l'on clique sur l'en-tête de la colonne.
Tout d'abord, nous devons créer notre IComparer :
public class AddressComparer: IComparer
{
public AddressComparer()
{
}
int IComparer.Compare( object x, object y )
{
string stringX = ( string )x;
string stringY = ( string )y;
const string digits = "0123456789";
if( ( digits.IndexOf( stringX[ 0 ] ) >= 0 ) && ( digits.IndexOf( stringY[ 0 ] ) >= 0 ) )
{
int index = 0;
System.Text.StringBuilder xNumber = new System.Text.StringBuilder();
while( ( index < stringX.Length ) && ( digits.IndexOf( stringX[ index ] ) >= 0 ) )
{
xNumber.Append( stringX[ index ] );
index++;
}
index = 0;
System.Text.StringBuilder yNumber = new System.Text.StringBuilder();
while( ( index < stringY.Length ) && ( digits.IndexOf( stringY[ index ] ) >= 0 ) )
{
yNumber.Append( stringY[ index ] );
index++;
}
long xValue = long.Parse( xNumber.ToString() );
long yValue = long.Parse( yNumber.ToString() );
if( xValue > yValue )
return 1;
if( xValue < yValue )
return -1;
return stringX.CompareTo( stringY );
}
else
{
return stringX.CompareTo( stringY );
}
}
}
Ensuite, nous l'ajoutons à notre DataGridCollectionViewSource :
<Grid.Resources>
<local:AddressComparer x:Key="addressComparer"/>
<xcdg:DataGridCollectionViewSource x:Key="cvs_orders"
Source="{Binding Source={x:Static Application.Current}, Path=Orders}"
AutoCreateItemProperties="False">
<xcdg:DataGridCollectionViewSource.ItemProperties>
<xcdg:DataGridItemProperty Name="ShipCountry" />
<xcdg:DataGridItemProperty Name="ShipCity" />
<xcdg:DataGridItemProperty Name="ShipAddress"
SortComparer="{StaticResource addressComparer}"/>
<xcdg:DataGridItemProperty Name="ShipVia" />
</xcdg:DataGridCollectionViewSource.ItemProperties>
</xcdg:DataGridCollectionViewSource>
</Grid.Resources>
Empêcher le tri
Il est possible d'empêcher l'utilisateur de trier les colonnes, de sorte que tout tri appliqué ne puisse être supprimé ou modifié. Pour ce faire, il suffit d'utiliser l'option AllowSort disponible sur le site Contrôle de groupe et ColumnManagerRow.
Étant donné que nous redéfinissons les en-têtes fixes, nous devons définir UseDefaultHeadersFooters à false et ajouter manuellement les en-têtes que nous voulons.
Par exemple :
<xcdg:DataGridControl x:Name="OrdersGrid"
ItemsSource="{Binding Source={StaticResource cvs_orders}}">
<xcdg:DataGridControl.View>
<xcdg:TableView UseDefaultHeadersFooters="False">
<xcdg:TableView.FixedHeaders>
<DataTemplate>
<xcdg:GroupByControl AllowSort="False" />
</DataTemplate>
<DataTemplate>
<xcdg:ColumnManagerRow AllowSort="False" />
</DataTemplate>
</xcdg:TableView.FixedHeaders>
</xcdg:TableView>
</xcdg:DataGridControl.View>
</xcdg:DataGridControl>
Pour plus d'informations, veuillez vous référer à la la documentation.