Introduzione

In questo articolo il controllo Extended DataGrid per applicazioni WPF.

È un controllo DataGrid non incluso nei controlli ufficiali, sviluppato dalla Xceed.

La pagina di riferimento è http://wpfextendeddatagrid.codeplex.com/

Costruiamo una applicazione WPF con Visual Studio 2015 e vediamo le caratteristiche e le funzionalità di questa Datagrid.

Prima di tutto dobbiamo scaricare la libreria, che sarà poi referenziata nel progetto che andremo a creare.

La libreria, con anche una demo e altre librerie, è scaricabile da qua: http://wpfextendeddatagrid.codeplex.com/releases/view/612262

Integrazione

Creiamo quindi una nuova applicazione WPF e la chiameremo WpfExtendedDataGrid.

Salviamo poi la solution e ora aggiungiamo la libreria.

Ed ecco come diventa “Esplora soluzione” dopo l’aggiunta della dll.

Siamo pronti a questo punto a scrivere l’interfaccia e il codice.

Nello Xaml dobbiamo aggiungere le seguenti righe nella Window:

             xmlns:ExtendedGridControl="clr-namespace:ExtendedGrid.ExtendedGridControl;assembly=ExtendedGrid"

             xmlns:ExtendedColumn="clr-namespace:ExtendedGrid.ExtendedColumn;assembly=ExtendedGrid"

xmlns:Controls="clr-namespace:ExtendedGrid.Microsoft.Windows.Controls;assembly=ExtendedGrid"

All’interno del tag Grid della Window mettete il seguente codice:

        <ExtendedGridControl:ExtendedDataGrid x:Name="grid" ItemsSource="{Binding SourceTable}" RowHeaderWidth="17" GroupByControlVisibility="Collapsed" AutoGenerateColumns="False" HideColumnChooser="False"

                                              IsSynchronizedWithCurrentItem="True"  SelectionMode="Extended" SelectionUnit="CellOrRowHeader" >

            <Controls:DataGrid.Columns>

                <ExtendedColumn:ExtendedDataGridTextColumn Header="Game Name" AllowAutoFilter="False"

                                           Binding="{Binding GameName}" />

                <ExtendedColumn:ExtendedDataGridTextColumn Header="Creator" AllowAutoFilter="False"

                                           Binding="{Binding Creator}" />

                <ExtendedColumn:ExtendedDataGridTextColumn Header="Owner"

                                           Binding="{Binding Owner}" AllowAutoFilter="False"/>

                <ExtendedColumn:ExtendedDataGridTextColumn Header="Publisher"

                                           Binding="{Binding Publisher}" AllowAutoFilter="False"

                                           CanUserSort="False" Width="*"/>

            </Controls:DataGrid.Columns>

            <ExtendedGridControl:ExtendedDataGrid.FooterDataTemplate>

                <DataTemplate>

                    <StackPanel Orientation="Horizontal">

                        <TextBlock Text="RowsCount:" FontWeight="Bold"/>

                        <TextBlock Margin="3,0,0,0" Foreground="DarkGreen"  Text="{Binding ElementName=grid,Path=Items.Count}"></TextBlock>

                    </StackPanel>

                </DataTemplate>

            </ExtendedGridControl:ExtendedDataGrid.FooterDataTemplate>

        </ExtendedGridControl:ExtendedDataGrid>

Possiamo già lanciare l’applicazione per vedere se funziona. Otterremmo questo:

L’intestazione delle colonne è configurata nello Xaml.

Ovviamente la DataGrid è vuota perché non abbiamo associato alcun dato:

Adesso nel Code behind mettiamo il codice seguente:

Imports System.ComponentModel

Imports System.Data

Class MainWindow

    Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded

        DataContext = Me

        InitializeComponent()

        SourceTable = New DataTable()

        SourceTable.Columns.Add(New DataColumn("GameName", GetType(String)))

        SourceTable.Columns.Add(New DataColumn("Creator", GetType(String)))

        SourceTable.Columns.Add(New DataColumn("Publisher", GetType(String)))

        SourceTable.Columns.Add(New DataColumn("Owner", GetType(String)))

        Dim row = SourceTable.NewRow()

        SourceTable.Rows.Add(row)

        row("GameName") = "World Of Warcraft"

        row("Creator") = "Blizzard"

        row("Publisher") = "Blizzard"

        row("Owner") = "Mark"

        row = SourceTable.NewRow()

        SourceTable.Rows.Add(row)

        row("GameName") = "Halo"

        row("Creator") = "Bungie"

        row("Publisher") = "Microsoft"

        row("Owner") = "Bill"

        row = SourceTable.NewRow()

        SourceTable.Rows.Add(row)

        row("GameName") = "Gears Of War"

        row("Creator") = "Epic"

        row("Publisher") = "Microsoft"

        row("Owner") = "Steve"

    End Sub

    Private _sourceTable As DataTable

    Public Property SourceTable() As DataTable

        Get

            Return _sourceTable

        End Get

        Set

            _sourceTable = Value

        End Set

    End Property

End Class

Adesso la tabella sarà così:

Ovviamente possiamo collegare la DataGrid a una fonte dati, come una lista o a una tabella, facendo come di seguito.

<Window x:Class="MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:ExtendedGridControl="clr-namespace:ExtendedGrid.ExtendedGridControl;assembly=ExtendedGrid"

        xmlns:ExtendedColumn="clr-namespace:ExtendedGrid.ExtendedColumn;assembly=ExtendedGrid"

        xmlns:Controls="clr-namespace:ExtendedGrid.Microsoft.Windows.Controls;assembly=ExtendedGrid"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        xmlns:local="clr-namespace:WpfExtendedDataGrid"

        mc:Ignorable="d"

        Title="MainWindow" Height="350" Width="525">

    <Grid>

        <ExtendedGridControl:ExtendedDataGrid x:Name="grid"  RowHeaderWidth="17"  AutoGenerateColumns="False"

                                              GroupByControlVisibility="Collapsed"           IsSynchronizedWithCurrentItem="True"  SelectionMode="Extended" SelectionUnit="CellOrRowHeader" >

            <Controls:DataGrid.Columns>

                <ExtendedColumn:ExtendedDataGridTextColumn Header="Name" AllowAutoFilter="True"

                                           Binding="{Binding Nome}" />

                <ExtendedColumn:ExtendedDataGridTextColumn Header="Cognome" AllowAutoFilter="True"

                                           Binding="{Binding Cognome}" />

                <ExtendedColumn:ExtendedDataGridTextColumn Header="Email"

                                           Binding="{Binding Email}" AllowAutoFilter="True"/>

            </Controls:DataGrid.Columns>

            <ExtendedGridControl:ExtendedDataGrid.FooterDataTemplate>

                <DataTemplate>

                    <StackPanel Orientation="Horizontal">

                        <TextBlock Text="RowsCount:" FontWeight="Bold"/>

                        <TextBlock Margin="3,0,0,0" Foreground="DarkGreen"  Text="{Binding ElementName=grid,Path=Items.Count}"></TextBlock>

                    </StackPanel>

                </DataTemplate>

            </ExtendedGridControl:ExtendedDataGrid.FooterDataTemplate>

        </ExtendedGridControl:ExtendedDataGrid>

    </Grid>

</Window>

Imports System.ComponentModel

Imports System.Data

Class MainWindow

    Private lst As New List(Of Anagrafica)

    Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded

        lst.Add(New Anagrafica("Sbressa", "Piero", "pierosbressa@crystalweb.it"))

        lst.Add(New Anagrafica("Rossi", "Mario", "pieer11@hotmail.it"))

        lst.Add(New Anagrafica("Verdi", "Giuseppe", "crystalweb_beta@outlook.it"))

        lst.Add(New Anagrafica("Rossi", "Piero", "pierosbressa@crystalweb.onmicrosoft.com"))

        grid.ItemsSource = lst

    End Sub

End Class

Class Anagrafica

    Private _Cognome As String

    Private _Nome As String

    Private _Email As String

    Public Sub New(ByVal Cognom As String, ByVal Nom As String, ByVal Emai As String)

        _Cognome = Cognom

        _Nome = Nom

        _Email = Emai

    End Sub

    Public Property Cognome() As String

        Get

            Return _Cognome

        End Get

        Set(ByVal value As String)

            _Cognome = value

        End Set

    End Property

    Public Property Nome() As String

        Get

            Return _Nome

        End Get

        Set(ByVal value As String)

            _Nome = value

        End Set

    End Property

    Public Property Email() As String

        Get

            Return _Email

        End Get

        Set(ByVal value As String)

            _Email = value

        End Set

    End Property

End Class

Ed ecco il risultato:

Notiamo che cliccando sull’intestazione della colonna, viene ordinato in base a quella colonna.

Possiamo anche spostare le colonne in base alle nostre esigenze semplicemente trascinando l’intestazione della colonna da spostare.

Possiamo fare anche un doppio click alla fine della colonna per avere automaticamente la larghezza della colonna in base agli elementi.

Funzionalità aggiuntive

Notiamo che è possibile avere un filtro in base a un dato di una certa colonna, come nella figura seguente:

Adesso vediamo come personalizzare la Datagrid e aggiungere le funzionalità mancanti nella Datagrid ufficiale.

Trascinando una colonna nella parte in alto automaticamente saranno raggruppate le righe in base a quella colonna. Ad esempio trasciniamo la colonna Nome.

Questo è quello che otterremmo:

Possiamo trascinare anche la colonna Cognome, ad esempio:

Questo è possibile grazie alla proprietà GroupByControlVisibility="Visible" da mettere all’interno del tag ExtendedGridControl:ExtendedDataGrid.

 

Vediamo ora come esportare la tabella in Excel. Oltre a mettere un pulsante nello Xaml, mettiamo il seguente codice nel code-behind:

    Private Sub EsportaToExcel_Click(sender As Object, e As RoutedEventArgs) Handles EsportaToExcel.Click

        grid.ExportToExcel("WorkSheetName", "C:\PROVA\PROVA1.xls", ExcelTableStyle.Light1, True)

    End Sub

Poi possiamo mettere un pulsante con un FileDialog per la scelta del file sfogliamo le risorse ok, ma l’importante è capire i metodi per ottenere direttamente il risultato. Con una semplice riga abbiamo il contenuto della Datagrid su Excel. Addio “Copia e Incolla”.

Allo stesso modo possiamo anche esportare in PDF, con questa riga di codice:

        grid.ExportToPdf("WorksheetName", “C:\PROVA\PROVA1.PDF”, ExcelTableStyle.Light1, True)

Possiamo anche esportare in un semplice file CSV, per essere importato in qualche altro software.

        grid.ExportToCsv("worksheet", "C:\PROVA\PROVA.CSV", True)

In un file Excel possiamo fissare un numero di colonne che vogliamo. Anche con questa Datagrid, possiamo fare altrettanto. Basta aggiungere queste due proprietà all’interno di ExtendedGridControl:ExtendedDataGrid:

ShowColumnSplitter="True" FrozenColumnCount="1"

Dove 1 è il numero di colonne che vogliamo rendere fisse.

Possiamo anche spostare a runtime questo valore, semplicemente spostando la barra grigia.

Possiamo anche personalizzare l’ultima riga mettendo il numero delle righe oppure altre scritte personalizzate.

Possiamo anche bloccare delle righe in alto. Per bloccare le prime 2 righe ad esempio, procediamo a mettere nello Xaml, sempre all’interno di ExtendedGridControl:ExtendedDataGrid il seguente codice:

EnableColumnVirtualization="False"     EnableRowVirtualization="False"  

Mentre nel caricamento della pagina mettere il seguente codice:

        grid.FrozenRowCount = 2

Lanciamo l’applicazione e otteniamo questo:

Possiamo aggiungere inoltre i numeri sulle righe, come quelle che ci sono in Excel.

Per fare questo dobbiamo aggiungere sempre nello Xaml la seguente proprietà:

ShowRowNumber="True"

Ed ecco il risultato:

Possiamo inoltre cambiare il tema, andando a mettere la seguente riga nel code-behind, nel caricamento della finestra:

grid.Theme=ExtendedDataGrid.Themes.Media

I valori sono:

  Default 

  Office2007Silver 

  Office2007Black 

  Office2007Blue 

  Windows7 

  LiveExplorer 

  System 

  Media 

Questo è LiveExplorer:

Mentre questo Windows 7:

Conclusioni

Abbiamo visto in questo articolo un’altra libreria che non può mancare nella cassetta degli attrezzi dello sviluppatore WPF. In questo articolo il prescelto è stato una DataGrid con funzioni aggiuntive rispetto alla standard rilasciata tra i controlli WPF