Apuntes de ADO.NET

Llop Site Home > Visual Studio .NET > Apuntes > ADO.NET 14-Feb-2005

14 Febrero 2005

NewDataSet : Jugar con 'DataGrid' y 'DataView'

Imports System.Data

Public Class Form1 : Iherits System.Windows.Forms.Form

#Region " Código generado por el Diseñador "
    Public Sub New()
        MyBase.New()
        'Se inicializan los componentes creados con el 'Diseñador'.
        InitializeComponent()
    End Sub

    ''Dispose' se sobrecarga para eliminar los componentes en la lista. 
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Contenedor para los componentes.
    Private components As System.ComponentModel.IContainer
    'Código del 'Diseñador'; no tocar con el 'Editor de código'.
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
    Friend WithEvents TextBox2 As System.Windows.Forms.TextBox
    Friend WithEvents Button2 As System.Windows.Forms.Button
    Friend WithEvents Button3 As System.Windows.Forms.Button
	
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.Button1 = New System.Windows.Forms.Button
        Me.TextBox1 = New System.Windows.Forms.TextBox
        Me.TextBox2 = New System.Windows.Forms.TextBox
        Me.Button2 = New System.Windows.Forms.Button
        Me.Button3 = New System.Windows.Forms.Button
        Me.SuspendLayout()
        'Button1
        Me.Button1.Location = New System.Drawing.Point(552, 8)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(96, 23)
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Filtro"
        'TextBox1
        Me.TextBox1.Location = New System.Drawing.Point(552, 32)
        Me.TextBox1.Name = "TextBox1"
        Me.TextBox1.TabIndex = 1
        Me.TextBox1.Text = "Sueldo"
        'TextBox2
        Me.TextBox2.Location = New System.Drawing.Point(552, 96)
        Me.TextBox2.Name = "TextBox2"
        Me.TextBox2.TabIndex = 3
        Me.TextBox2.Text = "Sueldo"
        'Button2
        Me.Button2.Location = New System.Drawing.Point(552, 72)
        Me.Button2.Name = "Button2"
        Me.Button2.Size = New System.Drawing.Size(96, 23)
        Me.Button2.TabIndex = 2
        Me.Button2.Text = "Order"
        'Button3
        Me.Button3.Location = New System.Drawing.Point(568, 128)
        Me.Button3.Name = "Button3"
        Me.Button3.TabIndex = 4
        Me.Button3.Text = "relaciones"
        'Form1
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(672, 365)
        Me.Controls.Add(Me.Button3)
        Me.Controls.Add(Me.TextBox2)
        Me.Controls.Add(Me.Button2)
        Me.Controls.Add(Me.TextBox1)
        Me.Controls.Add(Me.Button1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(Me)
    End Sub
#End Region
    'Atributos de la clase. 
    'Un 'DataSet', que almacena la/s tabla/s obtenida/s de la base de datos. 
    Private ds As New DataSet
    'Dos 'DataGrid's, que mostrarán datos (obtenidos de un 'DataSet', un 'DataView', o un 
    ''DataTable') organizados en filas y columnas . Nótese que pueden capturar eventos. 
    Private WithEvents dg2 As New DataGrid
    Private WithEvents dg1 As New DataGrid
    'El 'DataView' mostrará una de las siguientes 'DataTables', que a su vez se llenarán con
    'datos obtenidos del 'DataSet'.
    Private vi As DataView, tablaEmpleados, tablaDepartamentos As DataTable

    'Método que carga el formulario.
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Se inicializan las 'DataTables' con su nombre correspondiente.
	      tablaEmpleados = New DataTable("Empleados")
        tablaDepartamentos = New DataTable("Departamentos")
        'El 'DataView' se inicializa y muestra la tabla de empleados.
		  vi = New DataView(tablaEmpleados)
        'Se ubican los controles, y se crean las tablas de empleados y departamentos.
        UbicarControles()
        CrearDSDepartamentos()
        CrearDSEmpleados()
        'Este 'DataGrid' mostrará los datos del 'DataSet'.
        dg1.DataSource = ds
    End Sub
  
    'Crea la tabla de empleados, y la añade al 'DataSet'.
    Private Sub CrearDSEmpleados()
        'Se inicializan las columnas.
        Dim col1 As New DataColumn("Nombre", GetType(String))
        Dim col2 As New DataColumn("ID", GetType(Integer))
        Dim col3 As New DataColumn("DepartamentoID", GetType(Integer))
        'La columna 2 tiene algunas puntualidades: es para un campo autonumérico.
        With col2
            .AllowDBNull = False
            .AutoIncrement = True
            .AutoIncrementSeed = 1
            .AutoIncrementStep = 1
        End With
        'Se añaden las columnas a la tabla.
        tablaEmpleados.Columns.Add(col1)
        tablaEmpleados.Columns.Add(col2)
        tablaEmpleados.Columns.Add(col3)

        'Se inicializan 1500 filas, y se añaden a la tabla.
        For i As Integer = 1 To 1500
            Dim fila As DataRow = tablaEmpleados.NewRow
            fila.Item("Nombre") = "Tomás #" & i.ToString
            'Los empleados serán alternativamente de un departamento y del otro.
            fila.Item("DepartamentoID") = IIf(i Mod 2 = 0, 1, 2)
            tablaEmpleados.Rows.Add(fila)
        Next

        'La tabla de empleados se añade al 'DataSet'.
        ds.Tables.Add(tablaEmpleados)
    End Sub
	
    'Siguiendo la mecánica del anterior método, se crea una tabla de departamentos, y se añade
    'al 'DataSet'.
    Private Sub CrearDSDepartamentos()
        'Columnas.
        Dim col1 As New DataColumn("Nombre", GetType(String))
        Dim col2 As New DataColumn("ID", GetType(Integer))
        With col2
            .AllowDBNull = False
            .AutoIncrement = True
            .AutoIncrementSeed = 1
            .AutoIncrementStep = 1
        End With

        tablaDepartamentos.Columns.Add(col1)
        tablaDepartamentos.Columns.Add(col2)

        'Filas.
        Dim fila As DataRow = tablaDepartamentos.NewRow
        fila.Item("Nombre") = "Contabilidad"
        tablaDepartamentos.Rows.Add(fila)
        Dim fila2 As DataRow = tablaDepartamentos.NewRow
        fila.Item("Nombre") = "Personal"
        tablaDepartamentos.Rows.Add(fila2)

        'Todo al 'DataSet'.
        ds.Tables.Add(tablaDepartamentos)
    End Sub

    'Subrutina que ubica los componentes creados con el 'Editor de código': los 'DataGrid's.
    Sub UbicarControles()
        'Se determinan las coordenadas y los tamaños de las cuadrículas.
        dg1.Location = New Point(1, 1)
        dg1.Size = New Size(Me.Width \ 2, Me.Height \ 2)
        dg2.Location = New Point(1, dg1.Height + dg1.Location.Y)
        dg2.Size = New Size(Me.Width \ 2, Me.Height \ 2)
        'Se añaden a la lista de controles.
        Me.Controls.Add(dg1)
        Me.Controls.Add(dg2)
    End Sub

    'Método que trata el click en el botón 'Filtro'. Aplica un filtro a las filas del 'DataView'
    'para que sólo se muestren aquellas con una 'ID' superior al valor en el 'TextBox1'.
    Private Sub BTVista(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        vi.RowFilter = "ID > " & Me.TextBox1.Text
        'Los efectos del filtrado se muestran en el primer 'DataGrid'.
        dg1.DataSource = vi
    End Sub

    'Método que responde al click sobre el segundo botón. Ordena las filas del 'DataView' según
    'el nombre, y en orden descendente. 'dg1' muestra los cambios.
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        vi.Sort = "Nombre DESC"
        dg1.DataSource = vi
    End Sub

    'Método que responde al pulsar el botón del ratón sobre una de las filas del 1er 'DataGrid'.
    Private Sub dg1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles dg1.MouseDown
        'Objeto que informa sobre el elemento del 'DataGrid' en el que se ha pinchado.
        Dim myHitTest As DataGrid.HitTestInfo
        'Se inicializa el 'HitTestInfo' con las coordenadas del ratón.
        myHitTest = dg1.HitTest(e.X, e.Y)

        '¿Sobre que elemento se ha pinchado?:
        Select Case myHitTest.Type
            '¿El título?
            Case DataGrid.HitTestType.Caption
            '¿Una celda? Se ejecuta la función que mostrará en 'dg2' los empleados del mismo 
            'departamento que el de la fila.
            Case DataGrid.HitTestType.Cell
                EmpleadosDelDepartamento(myHitTest.Row)
            '¿Una cabecera de columna?
            Case DataGrid.HitTestType.ColumnHeader
            '¿Un modificador de tamaño de columna?
            Case DataGrid.HitTestType.ColumnResize
            '¿Se ha pinchado sobre un área vacía?
            Case DataGrid.HitTestType.None
        End Select
    End Sub

    'Subrutina que muestra todos los empleados de un mismo departamento. El argumento indica qué
    'departamento es el de los empleados que se van a mostrar.
    Sub EmpleadosDelDepartamento(ByVal filaRelacion As Integer)
        'Aquí se crea un array de filas a partir de las filas en la tabla de empleados cuyo 
        ''departamento' -el campo relacionado de las 2 tablas- es igual que 'filaRelacion' (éste 
        'representa el 'ID' de un registro de la tabla de departamentos).
        'Hay que tener presente que la tabla de departamentos es la 'master', y la de empleados
        'es la 'slave'.
        Dim FilasEmpleados() As DataRow = tablaDepartamentos.Rows(filaRelacion).GetChildRows("DepartamentoEmpleado")
        'Creamos una fila e inicializamos una tabla llamada 'Relacion'.
        Dim fila As DataRow, tabla As New DataTable("Relacion")
        'Creamos una columna, que se utiliza en un bucle para rellenar la 'tabla' con las columnas
        'de la tabla de empleados.
        Dim col As DataColumn
        With tabla
            For Each col In tablaEmpleados.Columns
                tabla.Columns.Add(col.ColumnName, col.DataType)
            Next
        End With
        'Se añaden todas las filas del array 'FilasEmpleados' a la 'tabla'.
        For Each fila In FilasEmpleados
            tabla.ImportRow(fila)
        Next

        'Finalmente, se llena el segundo 'DataGrid' con los datos de 'tabla'.
        dg2.DataSource = tabla
    End Sub

    'Subrutina para relacionar el campo 'departamento' de la tabla de empleados con el 'ID' de la 
    'tabla de empleados.
    Private Sub Relaciones()
        'Se borran las anteriores relaciones.
        ds.Relations.Clear()
        'Se crea una 'DataRelation' llamada 'DepartamentoEmpleado' que relaciona los campos citados.
        Dim relacion As New DataRelation("DepartamentoEmpleado", tablaDepartamentos.Columns("ID"), tablaEmpleados.Columns("DepartamentoId"))
        'Hay que añadir la relación al 'DataSet'.
        ds.Relations.Add(relacion)
    End Sub

    'Método que salta al pinchar sobre el tercer botón, el de 'relaciones'. Llama a un método
    'que relacionará un campo de la tabla de empleados con uno de la de departamentos.
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Relaciones()
    End Sub
End Class


IIf:

    'IIf' podría considerarse un operador ternario. En realidad es como una función que devuelve uno 
de dos objetos. Ésta es la sintaxis:

    IIf (boolean 'condición a evaluar', 
         Object 'es develto si la condición evalúa a true', 
         Object 'el retorno si la condición da false')


Remoting:

'Remoting' es la tecnología que permite cruzar 'procesos' y 'appdomains'.
    Proceso: Programa en ejecución. En Windows, éste lo administra el sistema operativo.
    AppDomain: 'Proceso' administrado por el CLR (Common Library Runtime).

Tipos de transmisión de procesos y appdomains por la red:
    MBV (Marshall By Value):     El equipo 'cliente' se descarga a la RAM los datos del proceso remoto 
                                 (en el servidor), hace los cambios pertinentes a los datos, y luego los 
                                 actualiza en el servidor. 
    MBR (Marshall By Reference): El cliente conecta con el servidor, y trata los datos directamente ahí 
                                 (aunque esté en las antípodas). 

    Un objeto .NET debe heredar de MarshallByRefObject para ser accesible a través de la red.
    Los objetos remotos deben ser administrados por un proceso que los muestre al 'mundo exterior';
así estarán accesibles en una URL concreta. El proceso administrador puede ser una 'aplicación de 
Consola' (para 'debugar'), un Servicio Windows, o IIS.

    Los objetos remotos pueden exponerse como:
        * SAO (Server Activated Objects): Objetos activados por el servidor.
        * CAO (Client Activated Objects): Objetos activados por el cliente.

    Un 'SAO' puede publicarse como un objeto 'SingleTon', o 'SingleCall'.
        * SingleTon: Todos los mensajes entrantes son atendidos por la misma instancia del objeto.
        * SingleCall: Todos los mensajes entrantes son atendidos por una nueva instancia del objeto
                      (hay que vigilar la sincronización del acceso).
    Obviamente, el tiempo de vida de estos objetos lo controla el servidor.

    Los 'CAO's son como 'objetos estándar' -cada cliente recive una instancia distinta del objeto, 
que se utiliza en cuantas llamadas a métodos queramos. Un 'CAO' se comporta como un objeto COM al que
se accede remotamente via 'DCOM'.

    El tiempo de vida de los objetos .NET Remoting se basa en su 'tiempo de Lease' (que viene a ser
su 'tiempo de arrendamiento'). Cuando un objeto se publica para acceso remoto, se le da un 'tiempo de 
vida', que se renueva a cada llamada a un método. Cuando expira el 'Lease', el objeto se vuelve inaccesible.


'Advanced DataSet' - Programa que construye un 'DataSet' a partir de un documento '.XML', y que permite grabar un 'DataSet' al disco como un '.XML':

    Especial mención merecen los métodos 'DataSet.ReadXML()' y 'DataSet.WriteXML()', que permiten 
inicializar o guardar el objeto en un documento '.XML'. 

¿Para qué es útil esto de guardar 'DataSets' como '.XML's y lo de inicializarlos?
    * Para crear archivos temporales (los daños se minimizan en caso de desastre).
    * Para PDAs (Portable Digital Agenda): con este sencillo método podemos pasarle 
      tablas creadas en SQL, Oracle, ...

Primary Key: Clave primaria de una tabla; hace referencia a los campos de una columna determinada,
             que serán accesibles a otras tablas. Una clave primaria debe ser distinta en todas
             sus filas.
Foreign Key: Se refiere a una columna de la tabla que referencia a la 'Primary Key' de otra tabla.


Imports System.Data

Public Class Form1 : Iherits System.Windows.Forms.Form

#Region " Código generado por el Diseñador "
    Public Sub New()
        MyBase.New()
        'Se inicializan los componentes creados con el 'Diseñador'.
        InitializeComponent()
    End Sub

    ''Dispose' se sobrecarga para eliminar los componentes en la lista. 
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Contenedor para los componentes.
    Private components As System.ComponentModel.IContainer
    'Código del 'Diseñador'; no tocar con el 'Editor de código'.
    Friend WithEvents DataGrid1 As System.Windows.Forms.DataGrid
    Friend WithEvents DataGrid2 As System.Windows.Forms.DataGrid
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents Button2 As System.Windows.Forms.Button
    Friend WithEvents Button3 As System.Windows.Forms.Button
    Friend WithEvents Button4 As System.Windows.Forms.Button
	
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.DataGrid1 = New System.Windows.Forms.DataGrid
        Me.DataGrid2 = New System.Windows.Forms.DataGrid
        Me.Button1 = New System.Windows.Forms.Button
        Me.Button2 = New System.Windows.Forms.Button
        Me.Button3 = New System.Windows.Forms.Button
        Me.Button4 = New System.Windows.Forms.Button
        CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.DataGrid2, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        'DataGrid1
        Me.DataGrid1.DataMember = ""
        Me.DataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText
        Me.DataGrid1.Location = New System.Drawing.Point(16, 56)
        Me.DataGrid1.Name = "DataGrid1"
        Me.DataGrid1.Size = New System.Drawing.Size(592, 328)
        Me.DataGrid1.TabIndex = 0
        'DataGrid2
        Me.DataGrid2.DataMember = ""
        Me.DataGrid2.HeaderForeColor = System.Drawing.SystemColors.ControlText
        Me.DataGrid2.Location = New System.Drawing.Point(8, 400)
        Me.DataGrid2.Name = "DataGrid2"
        Me.DataGrid2.Size = New System.Drawing.Size(600, 200)
        Me.DataGrid2.TabIndex = 1
        'Button1
        Me.Button1.Location = New System.Drawing.Point(16, 16)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(72, 32)
        Me.Button1.TabIndex = 2
        Me.Button1.Text = "Ordenar"
        'Button2
        Me.Button2.Location = New System.Drawing.Point(120, 16)
        Me.Button2.Name = "Button2"
        Me.Button2.Size = New System.Drawing.Size(72, 32)
        Me.Button2.TabIndex = 3
        Me.Button2.Text = "filtrar"
        'Button3
        Me.Button3.Location = New System.Drawing.Point(208, 16)
        Me.Button3.Name = "Button3"
        Me.Button3.Size = New System.Drawing.Size(72, 32)
        Me.Button3.TabIndex = 4
        Me.Button3.Text = "Salvar"
        'Button4
        Me.Button4.Location = New System.Drawing.Point(304, 16)
        Me.Button4.Name = "Button4"
        Me.Button4.Size = New System.Drawing.Size(72, 32)
        Me.Button4.TabIndex = 5
        Me.Button4.Text = "recuperar"
        'Form1
        Me.AutoScaleBaseSize = New System.Drawing.Size(6, 15)
        Me.ClientSize = New System.Drawing.Size(688, 640)
        Me.Controls.Add(Me.Button4)
        Me.Controls.Add(Me.Button3)
        Me.Controls.Add(Me.Button2)
        Me.Controls.Add(Me.Button1)
        Me.Controls.Add(Me.DataGrid2)
        Me.Controls.Add(Me.DataGrid1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        CType(Me.DataGrid1, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.DataGrid2, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)
    End Sub
#End Region

    'Tenemos un 'DataSet', un par de 'DataTable's -que tendrán campos relacionados- para meter en el 'DS',
    'y un 'DataView' -que es capaz de aplicar filtros a las tablas- para mostrar esas tablas en un
    ''DataGrid'.
    Private ds As DataSet, tablaEmpleados, tablaDepartamentos As DataTable, vi As DataView

    'Al cargarse el formulario, se crean e inicializan dos tablas: una de 'empleados', y otra de 
    'departamentos', con sus relaciones y demás. Para terminar, la tabla de 'departamentos' se
    'muestra en el 'DataGrid1'.
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ds = New DataSet
     
        CrearTablaEmpleados()
        LlenarTablaEmpleados()
        CrearTablaDepartamentos()

        'Mostremos los departamentos en el DataGrid; lo ponemos de tal forma que no se podrá
        'editar el 'DataGrid' ni el 'DataView'.
        DataGrid1.DataSource = ds
        DataGrid1.ReadOnly = True
        vi = New DataView(tablaDepartamentos)
        vi.AllowNew = False
        vi.AllowEdit = False
        vi.AllowDelete = False
        DataGrid1.DataSource = vi
    End Sub
	
#Region "DataTables"
    Sub CrearTablaEmpleados()
        'Se crea la tabla con 4 columnas; automáticamente se ajustan sus propiedades 
        ''MinimumCapacity' y 'CaseSensitive'.
        tablaEmpleados = New DataTable("Empleados")
        With tablaEmpleados
            .Columns.Add("ID", GetType(Integer))
            .Columns.Add("Nombre", GetType(String))
            .Columns.Add("Apellido", GetType(String))
            'Aunque es una foreign key, no hemos creado la otra tabla todavía.
            .Columns.Add("DepartamentoId", GetType(Integer))
        End With

        'Propiedades de columna 'ID'.
        With tablaEmpleados.Columns("ID")
            .AutoIncrement = True        'La hacemos autoincremental.
            .AutoIncrementSeed = 1
            .AllowDBNull = False         'Por defecto es True.
            .Unique = True
        End With

        'Convertimos 'ID' en la clave primaria.
        Dim pkCols() As DataColumn = {tablaEmpleados.Columns("ID")}
        tablaEmpleados.PrimaryKey = pkCols

        'Añadimos la 'DataTable' al 'DataSet'.
        ds.Tables.Add(tablaEmpleados)
    End Sub

    Sub LlenarTablaEmpleados()
        'Llenemos la tabla, fila a fila, con 99 empleados.
        For i As Integer = 1 To 99
            Dim fila As DataRow = tablaEmpleados.NewRow
            With fila
                .Item("Nombre") = "Juan #" & i.ToString
                .Item("Apellido") = "Domínguez #" & i.ToString
                .Item("DepartamentoId") = IIf(i Mod 2 = 0, 1, 2)
                tablaEmpleados.Rows.Add(fila)
            End With
        Next
    End Sub

    Private Sub CrearTablaDepartamentos()
        'Se crea la tabla
        tablaDepartamentos = New DataTable("Departamentos")

        ''ID' y 'Nombre' serán únicos.
        With tablaDepartamentos.Columns.Add("ID", GetType(Integer))
            .Unique = True
        End With

        With tablaDepartamentos.Columns.Add("Nombre", GetType(String))
            .Unique = True
        End With

        'Cómo no, 'ID' será la clave primaria de la tabla.
        tablaDepartamentos.PrimaryKey = New DataColumn() {tablaDepartamentos.Columns("ID")}

        'Añadimos esta tabla al DataSet.
        ds.Tables.Add(tablaDepartamentos)

        'Otra forma de meter filas en el objeto 'DataTable': 'deptValues' no es más que una fila.
        Dim deptValues() As Object = {1, "Ventas"}
        tablaDepartamentos.LoadDataRow(deptValues, True)
    End Sub
#End Region

#Region "Relaciones"
    'Muestra en el 'DataGrid2' todos los empleados cuyo departamento coincide con el 
    'argumento de la subrutina.
    Private Sub Relaciones(ByVal filaRelacion As Integer)
        'Borramos las relaciones que haya.
        ds.Relations.Clear()
        'Creamos la relación -se llamará 'DepartamentoEmpleado', y relacionará la columna 'ID' de la 
        'tabla de departamentos, con la columna 'Departamento' de la tabla de empleados-,
        'y la añadimos al 'DataSet'.
        Dim relacion As New DataRelation("DepartamentoEmpleado", tablaDepartamentos.Columns("ID"), tablaEmpleados.Columns("DepartamentoId"))
        ds.Relations.Add(relacion)

        'Mostremos nombres de empleados del primer departamento indicado con el argumento.
        Dim FilasEmpleados() As DataRow = tablaDepartamentos.Rows(filaRelacion).GetChildRows("DepartamentoEmpleado")
        'Ahora podemos crear una tabla nueva, y rellenarla con todos esos registros en 'FilasEmpleados'.
        Dim fila As DataRow, tabla As New DataTable("Relacion")
        'Añadimos la pauta para las columnas.
        Dim col As DataColumn
        With tabla
            For Each col In tablaEmpleados.Columns
                tabla.Columns.Add(col.ColumnName, col.DataType)
            Next
        End With
        'Y por fin metemos los datos, fila por fila.
        For Each fila In FilasEmpleados
            tabla.ImportRow(fila)
        Next
        'Esta nueva tabla puede verse en el 'DataGrid2'.
        Me.DataGrid2.DataSource = tabla
    End Sub
#End Region

    'La siguiente 'sub' salta cuando se pulsa (no hace falta ni terminar el 'click') el ratón
    'sobre el 'DataGrid1'. Es curiosa la forma de detectar en qué lugar del grid se ha pulsado.
    Private Sub DataGrid1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGrid1.MouseDown
        Dim myHitTest As DataGrid.HitTestInfo
        ''myHitTest' se inicializa con las coordenadas del ratón, para poder localizar dónde
        'del 'DataGrid' se ha pinchado.
        myHitTest = DataGrid1.HitTest(e.X, e.Y)
        'Si se ha pinchado en una celda, en el 'DataGrid2' podremos ver todos los empleados del
        'mismo departamento.
        If myHitTest.Type = DataGrid.HitTestType.Cell Then
            Relaciones(myHitTest.Row)
        End If
    End Sub

    ''DataView' ordena los registros por orden ascendente.
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        vi.Sort = "nombre asc"
    End Sub

    ''DataView' sólo mostrará las filas cuya 'ID' sea menor o igual que 2.
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        vi.RowFilter = "ID <= 2"
    End Sub

    ''DataSet' guarda su contenido en un documento '.xml'.
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        ds.WriteXml("ds.xml")
        'Para guardar sólo el esquema:
        'ds.WriteXml("ds.xml", XmlWriteMode.WriteSchema)
        'Para guardar originales y cambios:
        'ds.ReadXml("ds.xml", XmlReadMode.DiffGram)
    End Sub

    'Sub que salta al picar sobre el 'Button4'; se vacía el 'DataSet', se carga a partir de un 
    'archivo '.xml', y se muestra en el 'DataGrid1'.
    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
        ds.Clear()
        ds.ReadXml("ds.xml")
        Me.DataGrid1.DataSource = ds
    End Sub
End Class

¿Comentarios, sugerencias?: llopsite.at.yahoo.es | © 2005-07 Albert Lobo

Última actualización: 18-Feb-2007

Hosted by www.Geocities.ws

1