none
Valores por defecto en un DataGrid RRS feed

  • Pregunta

  • Buenos días:

    Tengo un DataGrid en el que el usuario puede agregar nuevas filas. El problema es que lógicamente esas filas inicialmente llevan todas valor NULL, el usuario rellena los campos (columnas) que le muestra el grid y el propio control añade las filas cuando se pulsa intro en la última columna o flecha abajo. Hasta ahí todo correcto.

    El problema viene cuando llamo al .SaveChanges del contexto (está con EF), ya que las columnas que no muestro en el grid tienen valor NULL y algunas de ellas son foreign key de la tabla.

    Seguro que es muy sencillo, pero no doy con la manera de dar valores por defecto a esas columnas. Antes había un evento llamado OnAddNew, en el que resultaba muy sencillo poner esos valores al registro que se acababa de crear, pero ahora al no trabajar directamente con las filas del grid, sino que debemos hacer todo con la colección que va por debajo, no sé muy bien cuál es la forma correcta de dar esos valores por defecto para que se pueda hacer el insert (vamos, para que lo pueda hacer el EF).

     

    Muchas gracias a todos de antemano.


    Carlos Adrián Martínez
    viernes, 15 de julio de 2011 6:39

Respuestas

  • Otra cosa que podrias hacer es controlar el evento RowEditEnding:

      Private Sub DataGrid1_RowEditEnding(sender As System.Object, e As System.Windows.Controls.DataGridRowEditEndingEventArgs)
      End Sub
    

    Y en "e" tienes un Row, dentro del cual puedes obtener el item (nuevo elemento) que está asociado, tambien tienes un EditAction que te dice si el edit se ha cancelado o se ha hecho en firme (commit).

    Un saludo!

     


    MCTS .NET Framework 3.5 Windows Forms Application Development
    MCTS .NET Framework 3.5 Windows Presentation Foundation
    Visita mi Blog en Geeks.ms
    Sigueme en Twitter
    viernes, 15 de julio de 2011 12:32
    Moderador
  • Si, supongamos que tu tienes una entidad cobros y tu al datagrid le has pasado una List(Of Cobros) por ejemplo

    En e.Row.Item tienes una instancia de esa entidad cobros, la que corresponde a la linea, debería funcionarte esto:

      Private Sub DataGrid1_RowEditEnding(sender As System.Object, e As System.Windows.Controls.DataGridRowEditEndingEventArgs)
        Dim lineaCobro As Cobros = e.Row.Item
        lineaCobro.FormaPago = "Efectivo"
      End Sub
    

    Lo que haces es coger el contenido de e.Row.Item y meterlo en una variable de tipo Cobros (tu entidad) y de esa forma podras tocar los valores y se asignarán de forma automática a la coleccion.

    Un saludo!

     


    MCTS .NET Framework 3.5 Windows Forms Application Development
    MCTS .NET Framework 3.5 Windows Presentation Foundation
    Visita mi Blog en Geeks.ms
    Sigueme en Twitter
    • Marcado como respuesta Carlos Adrián viernes, 15 de julio de 2011 13:00
    viernes, 15 de julio de 2011 12:55
    Moderador

Todas las respuestas

  • Hola!

    Has probado a establecer el valor por defecto de esas columnas en el edmx de entity framework?? estableciendo el valor en el modelo, al crear un nuevo elemento en cliente debería usar los valores por defecto que tenga la entidad.

    Un saludo!


    MCTS .NET Framework 3.5 Windows Forms Application Development
    MCTS .NET Framework 3.5 Windows Presentation Foundation
    Visita mi Blog en Geeks.ms
    Sigueme en Twitter
    viernes, 15 de julio de 2011 9:11
    Moderador
  • No me vale, porque tengo dos grid en el mismo formulario, y cada uno debe llevar valores por defecto diferentes.

     

    Muchas gracias de todos modos.


    Carlos Adrián Martínez
    viernes, 15 de julio de 2011 9:13
  • Pero entonces no son valores por defecto, si varían en cada caso, no debería indicarlos el usuario?? si no, la solución sería antes de llamar a EF, asignar el valor correcto a cada columna.
    MCTS .NET Framework 3.5 Windows Forms Application Development
    MCTS .NET Framework 3.5 Windows Presentation Foundation
    Visita mi Blog en Geeks.ms
    Sigueme en Twitter
    viernes, 15 de julio de 2011 9:15
    Moderador
  • Son por defecto para cada grid. Imagina, en uno se meten los cobros con tarjeta de crédito y en el otro los cobros por efectivos. Ambos entran en la tabla "Cobros", pero en uno el campo FormaPago = Efectivo y en el otro FormaPago = Tarjeta. Todas las filas que se agreguen al primer grid tendrán por defecto FormaPago = Efectivo y todos los que se agreguen al segundo tendrán por defecto FormaPago = Tarjeta.

    Dices "si no, la solución sería antes de llamar a EF, asignar el valor correcto a cada columna". Justo a eso me refiero, ¿cómo asigno el valor correcto a esa columna antes de que EF haga el insert?

    Gracias


    Carlos Adrián Martínez
    viernes, 15 de julio de 2011 9:18
  • Buenas a ver se me ocurre una cosa, por lo que veo, tienes una tabla cobros, y dos tipos de cobros tarjeta y efectivo.

    Creo que la solución perfecta seria que en entity framework hicieses una Herencia por tipo (tabla por tipo) de las entidades, yo crearia dos entidades cobro_tarjeta y cobro_efectivo, las dos mapeadas a la tabla cobros y le pondria una condición de mapeo de forma que, en la entidad cobro_tarjeta el campo formaPago sea tarjeta y en la entidad cobro_efectivo el campo formaPago sea efectivo. de esta forma tendras dos entidades distintas, solo tendras que asignar a la datagrid la entidad que le corresponda y al insertar él automaticamente establecerá el valor del campo formaPago dependiendo de porque entidad llegue el registro, puedes verlo más a fondo aquí:

    http://blogs.microsoft.co.il/blogs/gilf/archive/2010/01/22/table-per-type-inheritance-in-entity-framework.aspx

     

    Si esto no te vale, se me ocurre que antes de llamar al servicio que guarda los cambios, simplemente recorras la coleccion que tengas enlazada al datagrid con un foreach comprobando el valor de la propiedad formaPago


    MCTS .NET Framework 3.5 Windows Forms Application Development
    MCTS .NET Framework 3.5 Windows Presentation Foundation
    Visita mi Blog en Geeks.ms
    Sigueme en Twitter
    viernes, 15 de julio de 2011 9:24
    Moderador
  • Suena bien :) lo pruebo, te digo algo y si funciona marco ya la respuesta.

     

    Muchas gracias!!!


    Carlos Adrián Martínez
    viernes, 15 de julio de 2011 9:52
  • Lo he estado mirando, pero no me convence. Si lo hago así realmente lo que estoy haciendo es condicionar mis entidades a los datos del programa, es decir, hago cobros por tarjeta y por efectivo creo dos entidades. Pero si mañana entrase un cobro por talón tendría que crear una entidad nueva... creo que no es bueno condicionar el esquema de las entidades a los datos, sino a las estructuras. Y el campo que voy a rellenar con "Tarjeta" o con "Efectivo", no deja de ser un simple dato de la base de datos.

    Lo que yo pretendo es algo mucho más sencillo: detectar que se está añadiendo un registro al grid y darle valor a algunos de sus campos.

    Además, podría valer para "Tarjeta" o "Efectivo", pero otro campo que lleva el cobro es la fecha, que está puesta en un textbox en el formulario, y también tengo que darle al campo Fecha el valor que tenga ese textbox.

     

    Antes era así de fácil:

    Public Sub grdCobros_OnAddNew(...)

       grdCobros.Columns("FormaPago") = "Tarjeta"

       grdCobros.Columns("Fecha") = txtFecha.Text

    end Sub

     

    Pero ahora de verdad que no sé cómo hacerlo, ya que el grid no es más que una representación de la colección que lleva debajo, por lo que no puedo dar valores a sus columnas, directamente, sino que (creo) debo cambiar los valores en el elemento insertado en la propia colección. Pero... ¿cómo?

     

    Muchas gracias de todos modos por tu ayuda.

     

     


    Carlos Adrián Martínez
    viernes, 15 de julio de 2011 12:20
  • Hola,

    Vamos a ver, tu tendrás una colección que obtienes de entity framework con tus datos no???? y estableces por binding el itemssource del datagrid, o directamente Datagrid.ItemsSource = Coleccion , algo así verdad?

    Bueno, una vez que el usuario le de al botón guardar para enviar los datos a la base de datos, podrás recorrer la colección original con todos los datos que tiene el datagrid y podrás establecer el valor de las propiedades que quieras.

    Estas usando WPF o Silverlight??


    MCTS .NET Framework 3.5 Windows Forms Application Development
    MCTS .NET Framework 3.5 Windows Presentation Foundation
    Visita mi Blog en Geeks.ms
    Sigueme en Twitter
    viernes, 15 de julio de 2011 12:25
    Moderador
  • Estoy usando WPF. Sí, eso sería una solución, recorrer los datos antes de guardar.
    Carlos Adrián Martínez
    viernes, 15 de julio de 2011 12:27
  • Mejor dicho, no, no sería una solución. Porque en el momento de dar a Guardar datos, el txtFecha puede tener un valor, y no es el que tenía en el momento de insertar la línea.

    Se trata de dar valores en el momento en que el grid inserta la línea. Ese es el momento en que tiene que ver el valor de txtFecha.Text y ponerlo en la columna Fecha del grid.

     


    Carlos Adrián Martínez
    viernes, 15 de julio de 2011 12:31
  • Otra cosa que podrias hacer es controlar el evento RowEditEnding:

      Private Sub DataGrid1_RowEditEnding(sender As System.Object, e As System.Windows.Controls.DataGridRowEditEndingEventArgs)
      End Sub
    

    Y en "e" tienes un Row, dentro del cual puedes obtener el item (nuevo elemento) que está asociado, tambien tienes un EditAction que te dice si el edit se ha cancelado o se ha hecho en firme (commit).

    Un saludo!

     


    MCTS .NET Framework 3.5 Windows Forms Application Development
    MCTS .NET Framework 3.5 Windows Presentation Foundation
    Visita mi Blog en Geeks.ms
    Sigueme en Twitter
    viernes, 15 de julio de 2011 12:32
    Moderador
  • ¡Eso sí que es justo lo que quiero! Pero me vas a perdonar que abuse un poco más de tu amabilidad. No tengo claro cómo debería ser el código que referencie a la columna Fecha o a la columna FormaPago.

    Estoy probando (por probar, no porque tenga nada claro que debe ser así) con e.row.item("Fecha") = txtFecha.text, pero me da error. ¿Me podrías echar una última mano con el código, por favor?

     

    Muchas gracias


    Carlos Adrián Martínez
    viernes, 15 de julio de 2011 12:45
  • Si, supongamos que tu tienes una entidad cobros y tu al datagrid le has pasado una List(Of Cobros) por ejemplo

    En e.Row.Item tienes una instancia de esa entidad cobros, la que corresponde a la linea, debería funcionarte esto:

      Private Sub DataGrid1_RowEditEnding(sender As System.Object, e As System.Windows.Controls.DataGridRowEditEndingEventArgs)
        Dim lineaCobro As Cobros = e.Row.Item
        lineaCobro.FormaPago = "Efectivo"
      End Sub
    

    Lo que haces es coger el contenido de e.Row.Item y meterlo en una variable de tipo Cobros (tu entidad) y de esa forma podras tocar los valores y se asignarán de forma automática a la coleccion.

    Un saludo!

     


    MCTS .NET Framework 3.5 Windows Forms Application Development
    MCTS .NET Framework 3.5 Windows Presentation Foundation
    Visita mi Blog en Geeks.ms
    Sigueme en Twitter
    • Marcado como respuesta Carlos Adrián viernes, 15 de julio de 2011 13:00
    viernes, 15 de julio de 2011 12:55
    Moderador
  • Mira que me explico mal, pero al final me has entendido ¡y me has solucionado mi problema!

     

    Mil gracias, eres un crack!!!!

     


    Carlos Adrián Martínez
    viernes, 15 de julio de 2011 13:00
  • De nada!! jeje, si yo ando hoy algo espeso tambien :P!!
    MCTS .NET Framework 3.5 Windows Forms Application Development
    MCTS .NET Framework 3.5 Windows Presentation Foundation
    Visita mi Blog en Geeks.ms
    Sigueme en Twitter
    viernes, 15 de julio de 2011 13:02
    Moderador