Hero

Manejo de celdas del control DataGrid WPF en .NET

Julio 29, 2013

Pablo
Microsoft
.Net
VB

Una de las formas más comunes de mostrar información en las aplicaciones que desarrollamos es por medio de tablas, el Framework .Net haciendo uso de la interfaz WPF nos brinda el tipo de control DataGrid, este permite una forma dual de manejo de celdas, con un modo de presentación de datos y otro de edición de datos.

Sin embargo este objeto es poco intuitivo a la hora de su implementación por lo que explicaré como utilizar este sistema de celdas.

  1. Crear clase que manejara el DataGrid.

Para este ejemplo los datos con que estará vinculado el DataGrid será un List de un objeto Usuario el cual está definido en la siguiente clase la cual contiene los atributos y propiedades correspondientes, así como un método getList que devuelve el listado que mostrará el DataGrid.

<pre title="Clase Usuario">Public Class Usuario
    Private nombre As String
    Private fechaNacimiento As String
    Private tipo As String

    ''' <summary>
    ''' Propiedad que asigna un valor al atributo nombre
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property NombreUsuario As String
        Get
            Return nombre
        End Get
        Set(value As String)
            nombre = value
        End Set
    End Property

    ''' <summary>
    ''' Propiedad que asigna un valor al atributo fechaNacimiento
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property FechaNacimientoUsuario As String
        Get
            Return fechaNacimiento
        End Get
        Set(value As String)
            fechaNacimiento = value
        End Set
    End Property

    ''' <summary>
    ''' Propiedad que asigna un valor al atributo tipo
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property TipoUsuario As String
        Get
            Return tipo
        End Get
        Set(value As String)
            tipo = value
        End Set
    End Property

    ''' <summary>
    ''' Metodo contructor sin parametros
    ''' </summary>
    ''' <remarks></remarks>
    Sub New()
        NombreUsuario = ""
        FechaNacimientoUsuario = ""
        TipoUsuario = ""
    End Sub

    ''' <summary>
    ''' Metodo constructor con parametros
    ''' </summary>
    ''' <param name="nombre">Nobre del usuario</param>
    ''' <param name="fechaNacimiento">Fecha de nacimiento del usuario</param>
    ''' <param name="tipo">Tipo de usuario</param>
    ''' <remarks></remarks>
    Sub New(ByVal nombre As String, ByVal fechaNacimiento As Date, ByVal tipo As String)
        NombreUsuario = nombre
        FechaNacimientoUsuario = fechaNacimiento
        TipoUsuario = tipo
    End Sub

    ''' <summary>
    ''' Metodo que devuelve una lista de usuarios
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function getList() As List(Of Usuario)
        Dim list As New List(Of Usuario)
        list.Add(New Usuario("Pablo", New Date(1992, 4, 24).ToString("yyyy-MM-dd"), "Administrador"))
        list.Add(New Usuario("Roberto", New Date(1990, 5, 20).ToString("yyyy-MM-dd"), "Normal"))
        list.Add(New Usuario("Anibal", New Date(1980, 8, 16).ToString("yyyy-MM-dd"), "Normal"))
        list.Add(New Usuario("Maria", New Date(1993, 5, 19).ToString("yyyy-MM-dd"), "Administrador"))
        Return list
    End Function

End Class
  1. Crear ventana en XAML con el DataGrid.

Se procede a crear la ventana (en mi caso de nombre MainWindow.xaml) con el DataGrid y es aquí es donde se puede observar que este objeto posee un DataGridTemplateColumn en las cuales además del encabezado (DataGridTemplateColumn.Header), podemos agregar objetos CellTemplate (DataGridTemplateColumn.CellTemplate) que es la celda en modo de presentación en otras palabras como el usuario va a observar la información en este ejemplo todas las CellTemplate son TextBlock ya que solamente queremos que se muestre el texto.

Por otra parte vemos que además de tener CellTemplate, las DataGridTemplateColumn también poseen CellEditingTemplate (DataGridTemplateColumn.CellEditingTemplate) en el cual agregamos los controles que se utilizarán en el modo de edición.

En este ejemplo se ve claramente cómo se puede variar de celdas, en el campo Nombre poseemos un TextBox, en el campo Fecha Nacimiento un DatePicker ya que de esta manera facilitamos al usuario a seleccionar una fecha, y en el campo Tipo de Usuario un ComboBox que delimita al usuario a solo dos opciones en este campo, como se puede observar todos los controles de las celdas están vinculados a las propiedades de nuestra clase Usuario, ya que en el code behind vincularemos el grid a la lista que nos retorna el objeto Usuario en su método getList.

También podemos observar que en la etiqueta de apertura del Datagrid se le agregan algunos valores a sus propiedades, como que no puede eliminar filas entre otras, muchas de estas son opcionales para este ejemplo sin embargo no podemos obviar AutoGenerateColumns=“False” ya que si no colocamos esto el DataGrid nos duplicará las columnas por haberlo vinculado a la lista en el código behind.

<pre title="Codigo XAML del Window"><Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <DataGrid x:Name="dataGrid1" HorizontalAlignment="Center" VerticalAlignment="Center"
                  AutoGenerateColumns="False"
                  CanUserAddRows="False"
                  SelectionMode="Single"
                  CanUserDeleteRows="False"
                  CanUserResizeRows="False"
                  CanUserSortColumns="False"
                  HeadersVisibility="Column"
                  GridLinesVisibility="None" SelectionUnit="FullRow">
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.Header>
                        <TextBlock  Text="Nombre" />
                    </DataGridTemplateColumn.Header>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock x:Name="txtNombre" Text="{Binding NombreUsuario}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate >
                        <DataTemplate>
                            <TextBox Text="{Binding NombreUsuario, UpdateSourceTrigger=LostFocus}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>

                <DataGridTemplateColumn >
                    <DataGridTemplateColumn.Header>
                        <TextBlock  Text="Fecha Nacimiento"  />
                    </DataGridTemplateColumn.Header>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock  x:Name="FechaNacimiento" Text="{Binding FechaNacimientoUsuario}"  />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate >
                        <DataTemplate>
                            <DatePicker x:Name="dpFecha" SelectedDate="{Binding FechaNacimientoUsuario}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>

                <DataGridTemplateColumn >
                    <DataGridTemplateColumn.Header>
                        <TextBlock  Text="Tipo de Usuario"  />
                    </DataGridTemplateColumn.Header>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock  x:Name="txtbTipoUsuario" Text="{Binding TipoUsuario}"  />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate >
                        <DataTemplate>
                            <ComboBox x:Name="cmbTipoUsuario" Text="{Binding TipoUsuario, UpdateSourceTrigger=LostFocus}">
                                <ComboBoxItem Content="Normal" />
                                <ComboBoxItem Content="Administrador" />
                            </ComboBox>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>
  1. Vincular el DataGrid con el List de Usuarios.

Luego en el código behind de la ventana (en mi caso de nombre MainWindow.xaml.vb) creamos un método Loaded y en este creamos una instancia del objeto Usuario y obtenemos la lista por medio del método getList, luego vinculamos el DataGrid a la lista.

<pre title="Codigo Behind Window">Class MainWindow

    Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Dim usuario As New Usuario()
        Dim list As List(Of Usuario) = usuario.getList()
        dataGrid1.ItemsSource = list
    End Sub
End Class
  1. Resultado:

DataGrid en modo de edición(nombre)

DataGrid en modo de edición(fecha)

DataGrid en modo de edición(combo)

Podemos observar en las imágenes como cambian nuestros controles cuando editamos las celdas, haciendo más fácil controlar lo que ingresan nuestros usuarios o facilitando el uso de nuestra aplicación.

Espero que entendieran el ejemplo y les sea de ayuda!!! 😊

Recibe consejos y oportunidades de trabajo 100% remotas y en dólares de weKnow Inc.