Mostrando entradas con la etiqueta datagridview. Mostrar todas las entradas
Mostrando entradas con la etiqueta datagridview. Mostrar todas las entradas

jueves, 26 de enero de 2012

Seleccionar celda + datagridview + click derecho


Sin duda no es un comportamiento común dentro de un Datagridview, sin embargo, en ocasiones es necesario, principalmente para permitir el que sea lanzado un menú contextual a la vez que se selecciona una fila o celda que se desea.
   Sin embargo, para conseguirlo se requiere mas que solo activar alguna propiedad, es forzoso realizar este proceso mediante código, específicamente, una función que sea lanzada al momento que se presiona el botón del mouse, es decir, usando el evento Mouse down
Private Sub DGEquipos_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DGEquipos.MouseDown
          If e.Button = Windows.Forms.MouseButtons.Right Then
               With Me.DGEquipos
                   Dim Hitest As DataGridView.HitTestInfo = .HitTest(e.X, e.Y)                   If Hitest.Type = DataGridViewHitTestType.Cell Then
                      .CurrentCell = .Rows(Hitest.RowIndex).Cells(Hitest.ColumnIndex)                   End If
               End With
          End If
   End Sub

      En la primera y única condicional, solo hacemos que el sistema se asegure que se ha presionado el botón derecho, comparando el valor del boton que se ha presionado contra el valor de la constante del sistema perteneciente al botón derecho.
      A continuación procedemos a declarar e inicializar una variable de tipo Hitestinfo, a quien se le asigna el resultado de la función hitest, perteneciente al datagridview deseado, dado que es una de las partes mas importantes, se ha remarcado en rojo.
     el método Hitest nos devuelve el control o elemento  que se encuentre en las coordenadas que se le dan  como argumento que, en este caso, corresponden a las que nos indican donde se ha presionado el botón derecho del mouse
     Al final, solo nos resta verificar si el tipo de control capturado en el paso anterior es una de las celdas del datagridview, en este caso, se ha remarcado la línea en azul.
    Para terminar, solo ajustamos la celda usando los datos obtenidos a través de el método Hitest, paso remarcado en color café

miércoles, 25 de enero de 2012

Windows Forms DataGridView Maestro/ Detalle


Introduction

This example demonstrates a Windows Forms equivalent to the Microsoft Access one-to-many form by binding a DataSet containing a DataRelation between 2 DataTables to a DataGridView resulting in Parent/Child views.

Building the Sample

This sample was built using Visual Studio 2010.
Description
In Microsoft Access you can create a form that contains a subform (a one-to-many form) which is useful when working with relational data.  For this sample we'll use the Customer Orders scenario giving the user a way to view both Customer and related Order data at the same time by creating a Parent/Child view on a Windows Form using DataGridViews.  This is accomplished through the use of a DataRelation between two DataTable objects in a DataSet which are bound to DataGridViews.
Below is a code snippet from Form1.cs which creates the DataSet, DataTables, DataRelation, adds test data, and binds the data to DataGridViews.
The purpose of this sample is to fulfill a code sample request.  I hope this helps.
C#
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
 
namespace FormSubformEquivalent 
{ 
    /// <summary> 
    /// This class demonstrates the use of DataTables and DataRelations, 
    /// creating Master/Child views to mimic a one-to-many form  
    /// (form/subform) in Microsoft Access.  This should be considered a  
    /// starting point. 
    /// </summary> 
    public partial class Form1 : Form 
    { 
        private DataTable tblCustomer; 
        private DataTable tblOrder; 
        private DataSet tblDataSet; 
 
        public Form1() 
        { 
            InitializeComponent(); 
 
            // Create Tables 
            tblCustomer = new DataTable("tblCustomer"); 
            tblOrder = new DataTable("tblOrder"); 
 
            // Create DataSet 
            tblDataSet = new DataSet(); 
 
            // Create Columns and Add to Tables 
            tblCustomer.Columns.Add("ID"typeof(int)); 
            tblCustomer.Columns.Add("CustomerName"typeof(string)); 
            tblOrder.Columns.Add("ID"typeof(int)); 
            tblOrder.Columns.Add("Order"typeof(string)); 
            tblOrder.Columns.Add("CustomerID"typeof(int)); 
 
            // Add Test Data 
            tblCustomer.Rows.Add(1"Jane Doe"); 
            tblCustomer.Rows.Add(2"John Smith"); 
            tblCustomer.Rows.Add(3"Richard Roe"); 
            tblOrder.Rows.Add(1"Order1.1"1); 
            tblOrder.Rows.Add(2"Order1.2"1); 
            tblOrder.Rows.Add(3"Order1.3"1); 
            tblOrder.Rows.Add(4"Order2.1"2); 
            tblOrder.Rows.Add(5"Order3.1"3); 
            tblOrder.Rows.Add(6"Order3.2"3); 
             
            // Add Tables to DataSet 
            tblDataSet.Tables.Add(tblCustomer); 
            tblDataSet.Tables.Add(tblOrder); 
 
            // Create Relation 
            tblDataSet.Relations.Add("CustOrderRelation", 
                tblCustomer.Columns["ID"], tblOrder.Columns["CustomerID"]); 
 
            BindingSource bsCustomer = new BindingSource(); 
            bsCustomer.DataSource = tblDataSet; 
            bsCustomer.DataMember = "tblCustomer"; 
 
            BindingSource bsOrder = new BindingSource(); 
            bsOrder.DataSource = bsCustomer; 
            bsOrder.DataMember = "CustOrderRelation"; 
 
            // Bind Data to DataGridViews 
            dgvCustomer.DataSource = bsCustomer; 
            dgvOrder.DataSource = bsOrder; 
        } 
    } 
} 


DataGridViewCheckBoxColumn: Detectar el cambio/check en el evento CellValueChanged


Huston… teniamos un problema! Va yo era el del problema. Con un amigo del trabajo Pedro (flamante programador Clipper!) teniamos que realizar acciones en un winform en un control Datagridview con un Checkbox. Simple no? Pero cuando queriamos acceder por codigo al valor de la columna DataGridViewCheckBoxColumn CellValueChanged no teniamos el cambio actual.

Problema

Tenemos una grilla con una columna DataGridViewCheckBoxColumn
image
Para que cuando tengamos evento click en el check…
image
LO PODAMOS DETECTAR !!! Pense que era mas facil de lo que crei, pero por eso aqui esta este instructivo con las dos opciones:
Antes que nada… explicación de porque no podemos hacer simplemente…con los eventos como las otras celdas:
Pero si lo hacemos en el evento CellContentClick, no tendremos actualizado el valor del check 
Private Sub DataGridView1_CellContentClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick

    MsgBox("Estado: " & Me.DataGridView1.Rows(e.RowIndex).Cells("check").Value)

End Sub
(from MSDN…)CellContentClick: Para los clicks en DataGridViewCheckBoxCell este evento se produce antes de que cambie el valor de la casilla de verificación(…)
Si lo hacemos aqui CellValueChanged (que es donde deberiamos consultar por naturaleza) solo se produce cuando el usuario deja la celda actual. Esto sucede porque los cambios no se plasman hasta luego de ejecutar el evento CellEndEdit.


OPCION 1: La parte “ortodoxa”… cambiar el estado por nosotros mismos. Tenemos el control

Aqui la idea es cambiar la propiedad de esta columna DataGridViewCheckBoxColumn a ReadOnly
image 
image
Y en el evento CellContentClick, tendremos que ”artesanalmente” cambiar de estado… y alli si podremos recuperarlo.
Private Sub DataGridView1_CellContentClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick

   If e.ColumnIndex = Me.DataGridView1.Columns.Item("check").Index Then
       Dim chkCell As DataGridViewCheckBoxCell = Me.DataGridView1.Rows(e.RowIndex).Cells("check")
       chkCell.Value = Not chkCell.Value
   End If

   MsgBox("Estado: " & EstadoCheck(e.RowIndex))

End Sub
(Nota: Aqui la columna checkbox se llama “check”, y el metodo EstadoCheck solo obtiene el estado del la columna con el check – para demo)
Entonces? Aqui es una forma ortodoxa de conseguir nuestro objetivo: “Tener un poco de control en el OnClick del checkbox en una columna DataGridViewCheckBoxColumn del Datagridview”


OPCION 2:  Tener control del cambio en el CheckBoxColumn: Evento CurrentCellDirtyStateChanged (cuando se cambia el estado de alguna celda)

Esta opcion es la recomendacion de MSDN asi que, aqui va…
La columna checkbox (DataGridViewCheckBoxColumn) la dejamos como esta… sin propiedad ReanOnly seteada.
En el evento CurrentCellDirtyStateChanged preguntamos si la celda actual tiene cambios sin confirmar (propiedad IsCurrentCellDirty)
Private Sub DataGridView1_CurrentCellDirtyStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataGridView1.CurrentCellDirtyStateChanged
       If DataGridView1.IsCurrentCellDirty Then
           DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
       End If
   End Sub
         y alli si podremos consultar el valor… en el evento por naturaleza
Private Sub DataGridView1_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged

       MsgBox("Estado: " & EstadoCheck(e.RowIndex))

End Sub


Enlaces:

Fuente : http://geeks.ms

AGREGAR DATOS A UN DATAGRIDVIEW


Public Class Frm04

    Private Sub btnadd_Click(ByVal sender As System.ObjectByVal e AsSystem.EventArgsHandles btnadd.Click
        If TxtCod.Text = "" Then
            MsgBox("Ingrese Codigo")
            Exit Sub
        End If
        If Txtemail.Text = "" Then
            MsgBox("Ingrese Email")
            Exit Sub
        End If
        If TxtNom.Text = "" Then
            MsgBox("Ingrese Nombre")
            Exit Sub
        End If
        If TxtTel.Text = "" Then
            MsgBox("Ingrese Telefono")
            Exit Sub
        End If
        DGVAgenda.Rows.Add(TxtCod.Text.ToUpper, TxtNom.Text.ToUpper, TxtTel.Text.ToUpper, Txtemail.Text)
        Call Nuevo()
    End Sub
    Private Sub Nuevo()
        TxtCod.Clear()
        Txtemail.Clear()
        TxtNom.Clear()
        TxtTel.Clear()
    End Sub

    Private Sub Btndel_Click(ByVal sender As System.ObjectByVal e AsSystem.EventArgsHandles Btndel.Click
        If DGVAgenda.SelectedRows.Count = 0 Then
            MsgBox("Seleccione Item")
            Exit Sub
        End If
        DGVAgenda.Rows.RemoveAt(DGVAgenda.CurrentCell.RowIndex)
    End Sub

End Class