Archive for Enero, 2009

Me.DesignMode o ¿podrías por favor no interpretar el código mientras sólo estoy diseñando? (Gracias)

Sábado, Enero 31st, 2009

VisualBasic.NET (supongo que todo el VisualStudio.NET) tiene un comportamiento que me desquicia. Bueno, tiene unos cuantos, pero hoy hablo de uno en particular. Imaginemos un caso muy habitual en el que tengo un control de usuario y un formulario. Primero diseño el control de usuario y luego en el formulario lo insertaré.

El control de usuario (ctrlDGV.vb) lo creo simplemente añadiéndole un objeto de tipo DataGridView (dgvMain) y el siguiente código:

Public Class ctrlDGV

    '----------------------------------------------------------------
    ' Private attribute.
    '----------------------------------------------------------------
    Private DBC As DatabaseConnection

    '----------------------------------------------------------------
    ' Setter for DBC.
    '----------------------------------------------------------------
    Public Sub LoadDBC(ByVal DBC As DatabaseConnection)
        Me.DBC = DBC
    End Sub

    '----------------------------------------------------------------
    ' Event Me.Load.
    '----------------------------------------------------------------
    Private Sub ctrlDGV_Load(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles Me.Load
        Dim DT As DataTable
        DT = Me.DBC.GetDataTable("SELECT field FROM table")
        Me.dgvMain.DataSource = DT
    End Sub

End Class

El objeto Me.DBC es un objeto de conexión a datos cuyo método GetDataTable me devolverá un DataTable a partir de una cadena SQL (es todo lo que necesitamos saber aceca de él en lo que a este post se refiere). La manera de crear ese objeto Me.DBC no atañe a este control, porque asumimos que siempre nos preocuparemos de llamar al método LoadDBC (y por tanto asegurarnos que Me.DBC ha dejado de ser Nothing) antes de que se dispare el evento Me.Load, así que no habrá problemas.

¿No habrá problemas? Sí, sí que los habrá... Los habrá simplemente cuando intentemos insertar este control en un formulario en vista diseño. En ese momento obtendremos el siguiente error...

...y no nos dejará insertarlo. ¿Por qué? Pues porque el código en el evento Me.Load se está interpretando y descubre que Me.DBC es todavía Nothing... No entiendo por qué narices tiene que interpretar código en tiempo de diseño, la verdad. Y lo curioso del caso es que si comentamos el código del evento Me.Load entonces nos deja insertar dicho control en un formulario sin problemas. Y si después volvemos a descomentar el código, aunque no podremos ver el formulario en modo diseño porque nos volverá a dar el error, sí que podremos ejecutar la aplicación y funcionará correctamente (si llamamos al método LoadDBC antes de que se lance el evento Me.Load, insisto). Y es normal que funcione porque el flujo es correcto en tiempo de ejecución...

El caso es que para solucionar este problema tenemos dos posibilidades. La primera es actuar a lo bestia y meterlo todo dentro de un Try-Catch y muerto el perro se acabó la rabia:

'----------------------------------------------------------------
' Event Me.Load.
'----------------------------------------------------------------
Private Sub ctrlDGV_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load
    Try
        Dim DT As DataTable
        DT = Me.DBC.GetDataTable("SELECT field FROM table")
        Me.dgvMain.DataSource = DT
    Catch ex As Exception
        'On error no nothing, it's just for design time.
    End Try
End Sub

El segundo es ser un poco más sutil y hacer uso de la propiedad DesignMode del propio control para decirle algo así:

'----------------------------------------------------------------
' Event Me.Load.
'----------------------------------------------------------------
Private Sub ctrlDGV_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load
    If Not Me.DesignMode Then
        Dim DT As DataTable
        DT = Me.DBC.GetDataTable("SELECT field FROM table")
        Me.dgvMain.DataSource = DT
    End If
End Sub

Es decir, si no estás en modo diseño ejecútame este código (si estás en modo diseño no hagas nada). Me parece algo surrealista, sinceramente. Para mí lo normal sería... si estás en modo diseño, no hagas nada, ni te mires el código, ni olerlo, dejámelo a mí... Y como mucho que la propiedad Me.DesignMode sirviera para lo contrario: para explícitamente solicitarle que hiciera una determinada cosa incluso en tiempo de diseño.

Pues hasta que descubrí esto... ufffff...

Quitar la selección de un ComboBox en un DataGridView en .NET.

Jueves, Enero 22nd, 2009

Minipost recordatorio para mí mismo... Hace un rato he descubierto con gran sorpresa y desencanto que si en un objeto de tipo DataGridView tengo puestas algunas columnas como tipo ComboBox a través del objeto propio del .NET Framework DataGridViewComboBoxColumn (toma nombre cortito), y el campo en cuestión es de algún tipo que admite nulos -por ejemplo un Nullable(Of UInt16) o un simple String-... hasta que en el ComboBox no seleccionamos ningún valor, en la tabla relacionada de la base de datos se almacenará un valor NULL sin problemas, pero en el momento en que en el ComboBox seleccionamos un valor, no tenemos manera fácil de quitar esa selección. Dicho en plan fácil, un ComboBox dentro de un DataGridView nos permite seleccionar fácilmente un valor pero difícilmente quitar esa selección (aunque parezca mentira).

No obstante, si el campo es de tipo String no hay demasiado problema: nos podemos situar encima y con la combinación CTRL+0 (control cero) quitamos la selección. Ahora bien, el problema viene cuando el campo es numérico -como Nullable (Of UInt16)-. Aquí no podemos hacer un CTRL+0 sin más o nos lanzará un error.

Buscando buscando he encontrado un par de páginas (ésta y esta otra) que me han ayudado a resolver el problema y de paso a conocer que se trata de un bug reportado a Microsoft (sin que se hayan esmerado gran cosa en corregirlo, dicho sea de paso). En cualquier caso, la solución pasa por incorporar el siguiente código:

'----------------------------------------------------------------
' Event DGV.KeyDown.
'----------------------------------------------------------------
Private Sub DGV_KeyDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) _
Handles DGV.KeyDown
    If TypeOf Me.DGV.Columns(Me.DGV.CurrentCell.ColumnIndex) _
    Is System.Windows.Forms.DataGridViewComboBoxColumn Then
        If e.KeyCode = Keys.D0 Or e.KeyCode = Keys.NumPad0 _
        Or e.KeyCode = Keys.Delete Then
            Me.DGV.CurrentCell.Value = System.DBNull.Value
            e.Handled = True
        End If
    End If
End Sub

De paso he incorporado la misma funcionalidad para la tecla Suprimir, que siempre es bastante más intuitivo para quitar la selección de un ComboBox que la combinación CTRL+0.

Todo lo que quisiste hacer con un PDF pero no supiste cómo.

Domingo, Enero 11th, 2009

A través de Menéame descubro este genial artículo de Blogoff en el que explican cómo trastear y manipular a nuestro antojo documentos PDF sin necesidad de tener el programa Adobe Acrobat versión completa (es decir, no el Reader que es gratuíto sino el completo, el de pago). Decido incorporarlo a mi propio blog para tenerlo más mano cuando lo necesite y para de paso hacerlo llegar a más gente. El artículo de Blogoff se puede encontrar aquí y a su vez está basado en el artículo en inglés original que se puede leer aquí.

Todo lo que sigue a continuación no está escrito por mí sino que es el contenido íntegro de la entrada en el blog Blogoff...

1. ¿Cómo creo documentos PDF en mi ordenador sin necesidad de Adobe Acrobat?

Hazte con una copia del programa gratuito DoPDF [Ver tutorial]

2. Pero no quiero instalar un programa cuando lo único que voy a convertir son unos pocos documentos.

Sube tus documentos a Google Docs a través del explorador y luego expórtalos como PDF. Así de simple

3. Un cliente me ha mandado una presentación PowerPoint por e-mail y aquí no tengo nada para abrirlo ¿qué puedo hacer?

Reenvía el correo (con el powerpoint adjunto) a pdf@koolwire.com. Ellos convertirán la presentación a PDF y te la mandarán de vuelta para que la puedas ver en la mayoría de los dispositivos portátiles.

4. ¿Cómo guardo una página web como PDF sin guardarla como HTML primero?

Sólo tienes que ir a PrimoPDF, escribir la dirección de la página y recibirás una copia de la misma en PDF en el correo que les hayas proporcionado.

5. ¿Cómo puedo transformar un PDF a otros formatos como documento de Word, imagen, HTML, etc…?

A través de una web como Zamzar [ver tutorial]

6. ¿Cómo puedo juntar dos archivos PDF en uno? ¿Y cambiar el orden de las páginas?

PDFill es una utilidad muy versátil que te permitirá combinar varios documentos PDF en uno, reordenar las páginas e incluso rotarlas desde dentro del PDF.

7. Quiero extraer el texto de un PDF para usarlo en mi documento de Word ¿cuál es la mejor opción?

Abre PDF Text Extraction y sube tu PDF. Extraerá las 10 primeras páginas de tu documento en formato texto.

8. No puedo usar el truco de arriba porque el documento PDF no se hizo desde Word sino que fue escaneado.

Hay un modo de extraer el texto de estos documentos a través del OCR de Google. Quizás no la forma más rápida pero posiblemente la mejor solución gratuita.

9. Tengo documentos PDF en mi ordenador en el sentido de que no se pueden imprimir o seleccionar texto en ellos con el ratón.

PDF Unlocker es una utilidad gratuita que borra las restricciones más habituales sobre un PDF sin pedir ningún tipo de password.

10. Algunos PDF de mi empresa están protegidos con contraseñas que nadie recuerda después de la cena de empresa de ayer ¿qué puedo hacer?

Échale un vistazo a How to Open Password Protected PDF

11. Busco un servicio que permita a mis visitantes bajarse los artículos como PDF.

Añade el botón Web2PDF en algún sitio de tu página web. Convertirá la página a PDF de forma instantánea y además te permitirá mantener un registro de las conversiones.

12. Alguien me ha enviado un documento PDF en un idioma que no entiendo.

Puedes traducirlo con Google Translate y Zoho Viewer.

13. ¿Cómo puedo añadir anotaciones o notas de texto a mis documentos PDF?

Descarga PDF-X Viewer que es como Adobe Reader pero con algunas funciones adicionales. Puedes añadir las anotaciones que quieras e incluso pegar imágenes. Otra opción parecida es PDF Escape.

14. ¿Cómo puedo abrir un documento PDF online sin tener el software de Adobe?

Una alternativa fácil para abrir PDF en el navegador es el Free Online PDF Viewer, aunque hay otras muchas.

15. ¿Puedo rellenar formularios PDF online sin Acrobat Reader?

Sólo tienes que ir a PDF Filler, subir el archivo y empezar a escribir.

16. ¿Cómo puedo añadir una marca de agua o mi propia firma a un PDF?

Lo primero que tienes que hacer es crear tu marca de agua o firma con Paint o cualquier otro programa de dibujo y luego guardarla como imagen. Asegúrate de haber recortado bien la firma y abre el documento PDF en el PDF-X Viewer que ya hemos mencionado. Una vez allí sólo tienes que pegarla dentro del documento.

17. Tengo un libro en PDF que llega a las 200 páginas ¿hay algún modo de extraer algunas páginas en concreto y salvarlas como otro PDF?

Puedes usar tanto PDF Merge como PDF SAM para hacer esta operación.

18. ¿Cómo puedo proteger mi documento PDF con una contraseña?

En PDF Hammer subes tu documento y le asignas la contraseña que quieras.

19. Un PDF tiene muchos enlaces pero no puedo hacer click en ellos porque están en texto plano. ¿Cómo puedo convertilos en enlaces estándar?

Una vez más, acude a PDF Escape, sube el PDF y coloca los hipervínculos donde consideres oportuno.

20. ¿Qué servicios me rec0mendarías para subir archivos PDF a internet?

En el artículo original recomiendan Issuu que aún no he probado. De los que he visto me quedo con Scribd.

21 [Blogoff Bonus Track]. ¿Cómo puedo abrir un PDF más rápido con Adobe Reader?

Desactivando los plugins o usando Foxit PDF como lector de escritorio.

21 [Blogoff Bonus Track]. ¿Cómo crear un PDF de un documento de Word?

Con Express PDF (mi herramienta favorita)

22. [Blogoff Bonus Track]. ¿Cómo puedo manejar archivos PDF en OpenOffice?

Plugin para editar archivos PDF en Open Office sin Adobe Reader