Otro sobre optimización del Visual Studio 2005

Ayer mi amigo Jairo me comento el truco para optimizar nuestro VS2005 y hoy leo en el blog de ScottGu ese truco y alguno más para optmizarlo.


Podéis leer el post en el siguiente link:


http://weblogs.asp.net/scottgu/archive/2006/09/22/Tip_2F00_Trick_3A00_-Optimizing-ASP.NET-2.0-Web-Project-Build-Performance-with-VS-2005.aspx


Saludos

Mejorar el rendimiento en los proyectos de Visual Basic 2005

Si desarrollamos una solución grande con Visual Basic 2005 podemos sufrir diferentes problemas de rendimiento. Entre estos problemas nos encontramos retardo al generar o volver a generar, demasiado uso de la CPU (por encima del 50%), respuesta del editor o del intellisense, entre otros.


Para optimizar el rendimiento de nuestro editor simplemente debemos crear un valor en el registro.


Es recomendable que haga una copia de seguridad antes de modificar el registro.


Para poder corregir esto simplemente debemos ir al nodo:


HKEY_CURRENT_USERSoftwareMicrosoftVisualStudio8.0VB Editor

 

Y una vez ahí crear un DWord llamado OptimizePDB con el valor 1.

 

Podéis leer la noticia en español en el siguiente link para quien tenga problemas con el inglés:

 


 

Y la noticia completa en inglés:

 


 

Saludos y espero que os sea útil [:)]

 

Tengo que agradecer a Jairo por darme a conocer esta noticia [;)]

Usando el ProgressBar con un BackGroundWorker

Este ejemplo esta especialmente publicado para Emilio Velardiez que me pregunto como usar una barra de progreso con una BackgroundWorker.

Este ejemplo lo haré en una aplicación Windows Form.

A nuestra aplicación Windows Forms vamos a agregar un BackgroundWorker, llamado BackgroundWorker1, y un ProgressBar, llamado ProgressBar1.

Las únicas propiedades que cambiaremos son las del BackgroundWorker1, para que pueda reportar el proceso:

Y este es el código de nuestra aplicación:

Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load BackgroundWorker1.RunWorkerAsync() End Sub Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork Dim i As Integer For i = 1 To 1000 BackgroundWorker1.ReportProgress(i / 10) Threading.Thread.Sleep(500) Next End Sub Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged ProgressBar1.Value = e.ProgressPercentage End Sub Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted MsgBox("listo") End Sub End Class

Espero, como siempre, que os sea útil.

Textbox WaterMark (antes con efecto sombra) Beta 2

Esta es la nueva versión del Textbox con marca de agua, el proceso de creación es igual que el anterior, esta vez el código es el siguiente:


 


 


Public Class TextBoxWaterMark
Private _active As Boolean
Private _defaultFont As Font = Me.Font
Private _defaultColor As Color = Me.ForeColor
Private _defaultBackColor As Color = Me.BackColor

Private _watermarkText As String
Private _watermarkFont As Font = New Font(_defaultFont, FontStyle.Italic)
Private _watermarkColor As Color = Color.Gray
Private _watermarkBackColor As Color = Color.White
Private _password As Boolean

Property WaterMarkText() As String
Get
Return _watermarkText
End Get
Set(ByVal value As String)
_watermarkText
= value
If _active = True Or Me.Text = “” Then
ActiveWaterMark()
End If
End Set
End Property

Property WaterMarkColor() As Color
Get
Return _watermarkColor
End Get
Set(ByVal value As Color)
_watermarkColor
= value
End Set
End Property

Property WaterMarkBackColor() As Color
Get
Return _watermarkBackColor
End Get
Set(ByVal value As Color)
_watermarkBackColor
= value
End Set
End Property

Property WaterMarkFont() As Font
Get
Return _watermarkFont
End Get
Set(ByVal value As Font)
_watermarkFont
= value
End Set
End Property

Private Sub TextBoxWaterMark_Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Enter
If _active = True Then
QuitWaterMark()
End If
End Sub

Private Sub TextBoxWaterMark_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LostFocus
If Me.Text = “” Then
ActiveWaterMark()
End If
End Sub

Public Overrides Property Text() As String
Get
If _active = True Then
Return “”
Else
Return MyBase.Text
End If
End Get
Set(ByVal value As String)
MyBase.Text = value
End Set
End Property

Public Sub ActiveWaterMark()
_active
= True
Me.Text = _watermarkText
Me.Font = _watermarkFont
Me.BackColor = _watermarkBackColor
Me.ForeColor = _watermarkColor
End Sub

Public Sub QuitWaterMark()
_active
= False
Me.Text = “”
Me.Font = _defaultFont
Me.BackColor = _defaultBackColor
Me.ForeColor = _defaultColor
End Sub

Private Sub TextBoxWaterMark_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.TextChanged
If Me.Text = “” And Not Me.Focused Then
ActiveWaterMark()
End If
End Sub
End Class


 


Se han corregido en esta versión los siguientes errores:



  • Si se está mostrando la marca de agua la propiedad Text de vuelve una cadena vacía

  • Se pueden cambiar los colores del texto normal

  • Si el texto se cambia sin estar en el foco se activa la marca de agua

  • En caso de que el usuario escriba el mismo texto de la marca de agua no se active los colores de la marca de agua

Además he añadido las sigiuentes características:



  • Se puede cambiar el color de fondo de la marca de agua.

  • Se pueden cambiar los colores de la marca de agua

Pronto publicaré la siguiente versión.

Textbox con efecto sombra

En este post os voy a explicar como crear un textbox con efecto sombra.

El efecto sombra es un texto que explica para que sirve el textbox o que debe incluir en él, en la siguiente figura podéis ver un textbox con efecto sombra y otro que no lo tiene.

Si nuestro segundo textbox se convierte en el foco de la aplicación, la fuente y el color se convertirán a la del primero y el texto estará en blanco. Si una vez perdido el foco el cuadro de texto está vacío este se volverá a convertir en la sombra. En caso de no estar vacio se mantiene con lo que el usuario a escrito.

Lo primero que debemos hacer es crear un control de usuario que llamaremos AdvancedTextbox.

Una vez que este creado vamos al código del diseñador, AdvancedTextbox.Designer.vb (debemos activar la opción Mostrar todos los archivos del explorador de soluciones para poder verlo).

En la línea 2 eliminamos esto:

Inherits System.Windows.Forms.UserControl

Y lo cambiamos por esto:

Inherits System.Windows.Forms.TextBox

Con eso nuestro control de usuario pasa de ser heredado de System.Windows.Forms.UserControl, por System.Windows.Forms.Textbox.

Ahora ya tenemos nuestro control de usuario exactamente igual que el Textbox de .NET, ahora tendremos que darle personalidad a nuestro textbox “avanzado”.

Para ello vamos al código de nuestro textbox y añadimos el siguiente código (he comentado todo el código para su fácil lectura):

1 Public Class AdvancedTextbox 2 3 'Variable que guardará la fuente para el texto normal 4 Private _defaultFont As Font = Me.Font 5 'Al igual que la anterior esta guarda el color 6 Private _defaultColor As Color = Me.ForeColor 7 'Y este es el texto que tendrá la sombra 8 Private _defaulttext As String 9 10 'Con esta propiedad vamos a cambiar el texto de la sombra 11 Property DefaultText() As String 12 Get 13 'Retornamos el texto que tenemos guardado 14 Return _defaulttext 15 End Get 16 Set(ByVal value As String) 17 'Comprobamos si ya se está mostrando la sombra 18 If Me.Text = "" Or Me.Text = _defaulttext Then 19 'De ser así le cambiamos al nuevo texto 20 Me.Text = value 21 'Ponemos la fuente de la sombra 22 Me.Font = New Font(_defaultFont, FontStyle.Italic) 23 'Y también ponemos el color de la sombra 24 Me.ForeColor = Color.Gray 25 End If 26 'Por último guardamos el nuevo valor 27 _defaulttext = value 28 End Set 29 End Property 30 31 'Ahora se debe poner automáticamente la sombra 32 33 'Para ello, cuando AdvancedTextbox obtenga el foco quitamos la sombra 34 Private Sub AdvancedTextbox_Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Enter 35 'Comprobamos si tiene la sombra 36 If Me.Text = DefaultText Then 37 'De ser así, vaciamos el textbox 38 Me.Text = "" 39 'Establecemos la fuente predeterminada 40 Me.Font = _defaultFont 41 'Y el color predeterminado 42 Me.ForeColor = _defaultColor 43 End If 44 End Sub 45 46 'En caso de perder el foco 47 Private Sub AdvancedTextbox_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LostFocus 48 'Si está vacio el textbox 49 If Me.Text = "" Then 50 'Establecemos el texto de la sombra 51 Me.Text = _defaulttext 52 'Establecemos la fuente de la sombra 53 Me.Font = New Font(_defaultFont, FontStyle.Italic) 54 'Y su respectivo color 55 Me.ForeColor = Color.Gray 56 End If 57 End Sub 58 59 'Al cambiar el texto debemos asegurarnos de que se muestre o no la sombra 60 Private Sub AdvancedTextbox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.TextChanged 61 'Por eso cuando el texto cambie validaremos su contenido 62 If Me.Text = _defaulttext Then 63 'Si es igual al texto de la sombra 64 'cambiamos su fuente y su color al de la sombra 65 Me.Font = New Font(_defaultFont, FontStyle.Italic) 66 Me.ForeColor = Color.Gray 67 'En caso de estar vacio cambiamos su texto le damos el foco 68 'Asi conseguimos que solo este vacio cuando tenga el foco 69 ElseIf Me.Text = "" Then 70 Me.Focus() 71 Else 72 'Por último al no estar vacío ni contener el texto de la sombra 73 'Establecemos la fuente y el color predeterminados 74 Me.Font = _defaultFont 75 Me.ForeColor = _defaultColor 76 End If 77 End Sub 78 End Class 79

Debido a que es la primera versión de este código ciertas propiedades, como por ejemplo Font y ForeColor no se pueden cambiar, siendo necesario su cambio en las variables privadas de la clase.

Las pruebas que he hecho has sido satisfactorias, pero, como ya sabréis, si es el programador el propio tester no suele tener problemas, ya que lo usa para lo que lo ha hecho, deberia testearlo otra persona.

Si os animáis a probarlo no dudeis en comentar vuestras opiniones y si no, siempre podéis comentar lo que queráis[:P]

Como validar si un objeto implementa una interfaz (sin usar Reflection)

Bruno nos contaba hoy como validar si un objeto implementa una intefaz.


De paso que pruebo el Plugin de WLW os doy otra opción sin usar Reflection.


Ya comenta Rodrígo de hacerlo de esta forma y yo os enseño el código. Parece que es mucho más código, pero en realidad la comprobación es la función Comprobar().

‘Esta es la intefaz que vamos a utilizar.
Public Interface IClase
Property name() As String
End Interface

‘Esta es la clase que la implmenta
Public Class Clase_1
Implements IClase

Private _name As String

Public Property name() As String Implements IClase.name
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
End Class

‘Esta es una clase que no la implementa
Public Class Clase_2
Private _name As String

Public Property name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
End Class

‘Y aquí tenemos el ejemplo
Public Class Form1

‘Esta es la función para comprobar
Public Function Comprobar(ByVal Obj As Object) As Boolean
Try
Dim NewObj As Object
NewObj = CType(Obj, IClase)
Catch ex As Exception
Return False
Exit Function
End Try
Return True
End Function

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim Clase1 As New Clase_1()
Dim Clase2 As New Clase_2()

Dim _msg As String

If Comprobar(Clase1) Then
_msg = “Clase1 SI implmenta la intefaz” & Chr(13)
Else
_msg = “Clase1 NO implmenta la intefaz” & Chr(13)
End If

If Comprobar(Clase2) Then
_msg += “Clase2 SI implmenta la intefaz
Else
_msg += “Clase2 NO implmenta la intefaz
End If

MsgBox(_msg)
End Sub
End Class

Eso es todo [:D], espero que os sea útil.

Trabajando con direcciones…

A veces en nuestros proyectos, los usuarios deben ingresar un dirección URL, para ello sería conveniente comprobar si es correcta, y de ser así, de que tipo es (HTTP, FTP, etc.), por eso os dejo aquí unos pequeños trucos para trabajar con ellas.

¿Qué clase es la indicada para este trabajo?

Se trata de la clase System.Uri. Esta clase contiene una serie de métodos compartidos para trabajar con direcciones y además si creamos una instancia de ella, podemos saber más cosas de la dirección.

¿Cómo podemos comprobar si una dirección es correcta?

Para ello, tenemos que usar el método compartido System.Uri.IsWellFormedUriString. Este método compartido tiene dos parámetros: uriString y uriKind. Al primero le debemos dar la cadena de la dirección, y al segundo le tenemos que señalar lo "permisivo" que será con esa dirección, explico esto con un ejemplo. Lo correcto sería poner: http://www.microsoft.es, aunque www.microsoft.es también sería válido (a la hora de navegar con nuestro explorador), por ello si queremos que la segunda opción sea válida le debemos poner UriKind.Relative y si queremos que no sea válido le debemos poner UriKind.Absolute.

¿Y si ahora queremos saber que tipo de dirección es?

Para ello debemos crear una instancia de la clase System.Uri.

Dim ObjUri As New System.Uri(URL)

Una vez que lo tengamos creado, tenemos que obtener el scheme, para ello recomiendo usar un Select Case ya que así podemos comparar con todos los esquemas:

Select Case ObjUri.Scheme
   Case Uri.UriSchemeHttp

   Case Uri.UriSchemeHttps

   Case Uri.UriSchemeFtp

   Case Uri.UriSchemeFile

   Case
Uri.UriSchemeMailto
End Select


Puse los mas conocidos pero podéis encontrar más dentro de System.Uri.

Último ejemplo…

Como último ejemplo voy a hacer una función de tipo System.Boolean que lo que hará es válidar si una URL es de tipo HTTP o HTTPs:

Public Function Validar(ByVal URL As String) As Boolean

    'Comprobamos si la dirección es correcta, en caso de no ser así devolvemos False y salimos de la función.

    If Not System.Uri.IsWellFormedUriString(URL, UriKind.Absolute) Then

        Return False

        Exit Function

    End If

    'Instanciamos la clase Uri para poder comprobar el scheme.

    Dim objUri As Uri = New Uri(URL)

    'Y ahora comprobamos si es de tipo HTTP o HTTPs

    If objUri.Scheme = Uri.UriSchemeHttp Or objUri.Scheme = Uri.UriSchemeHttps Then

        Return True

        Exit Function

    Else

        Return False

    End If

End Function

Espero que os sea útil 😉

VB y C#, una equivalencia que ha pasado desapercibida

Leyendo las Equivalencias entre Visual Basic .NET y C# de elGuille me encontré con que faltaba una, se trata de una comparativa, el select case en VB y el switch en C#.


Esto es lo que debería de añadir elGuille 😉


Visual Basic .NET

Select Case x

   Case 10

      ‘…

   Case 20

      ‘…

   Case Else

      ‘…

End Select

 

C#

 

switch (x)

{

   case 10:

      //…

      break;

   case 20:

      //…

      break;

   default:

      //…

      break;

}


Esperemos que sea la única 😛

 

Una costumbre en VB que C# no nos permite

Esta tarde, un amigo, me comentaba que, que estaba empezando con C#, y se encontraba con que le generaba errores en el designer.cs, sabiendo que viene de VB, me imaginé al momento cuál era su error. Os lo voy a razonar como intenté razonarselo a él.


¿Cómo manejamos un evento en VB?


Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load


End Sub


Y… ¿en C#?


private void Form1_Load(object sender, EventArgs e)


{


}


¿Cuál es la diferencia?


Espero que hayáis notado que lo que falta es el handles, lo que “une” el método con el evento del control.


Entonces… ¿Dónde se “une” el método con el evento en C#?


En el designer.cs con el que teníamos problemas, esta es la línea que lo demuestra


this.Load += new System.EventHandler(this.Form1_Load);


¿Dónde estan los errores?


Pues que si eliminamos el evento como en VB, en el designer se seguirá apuntando hacia un evento que no existe y eso genera los errores.


¿Cuál es la solución a este problema?


Pues tenemos dos opciones:



  • Elinamos esa línea de código
  • O como deberíamos hacer… eliminamos los eventos desde la ventana de propiedades del diseñador.

Espero que os sea útil 😉

Encriptación: Una clase que te puede simplificar las cosas

‘Este código que hoy os mando es fue desarrollado por mí y el amigo Elliott (dev4u.net@gmail.com) he dividido el trabajo de los 2 en Regiones, mi parte del trabajo es la región Contraseñas Hash y la de Elliott Encriptar/Desencriptar, yo comentaré mi parte, si tenéis alguna duda con su código contactad con él, o contactad conmigo para que os ponga en contacto con él.


 


‘Antes de que me olvide otra cosa, fue desarrollado con Visual Studio 2005, pero no tiene ningún problema en ser usado con Visual Studio .NET 2003 (a mi no me dio ningún conflicto).


 


Imports System


Imports System.IO


Imports System.Security


Imports System.Security.Cryptography


Imports System.Text


 


Public Class Criptologia



#Region “Contraseñas Hash”



    ‘Con esta función que tenemos aquí abajo, lo que haces es transformar la cadena en Bytes.


    Shared Function ConvertirCadenaEnMatrizDeTipoByte(ByVal Cadena As [String]) As [Byte]()


        Return (New UnicodeEncoding).GetBytes(Cadena)


        ‘Retornamos la cadena convertida.


    End Function



    ‘En esta función la cadena la convertiremos en Bytes con la función anterior, lo transformaremos en un valor Hash, encriptado con el algoritmo SHA512 y más tarde lo convertiremos en una cadena.



    Public Function EncriptarHash(ByVal ValorAEncriptar As String) As String


        Dim ValorToHash As [Byte]() = ConvertirCadenaEnMatrizDeTipoByte(ValorAEncriptar)


        ‘Declaramos la variable de tipo Byte y llamamos a ConvertirCadenaEnMatrizDeTipoByte y convertimos la cadena a encriptar en typo Byte


        Dim ValorHash As Byte() = CType(CryptoConfig.CreateFromName(“SHA512”), HashAlgorithm).ComputeHash(ValorToHash)


        ‘Encriptamos variable Byte en una cadena de tipo Byte, también.


        Return Convert.ToBase64String(ValorHash)


        ‘BitConverter.ToString(ValorHash)


        ‘Retornamos la variable de tipo Byte en String.


    End Function



    ‘Para comparar dos valores lo primero es enviar como parametros una cadena sin encriptar y otra cadena encriptada, con el mismo tipo de encriptación, y haciendo uso del mismo algoritmo, en nuestro caso usaremos Hash con el algoritmo SHA512. Luego encriptamos el valor si encriptar y comparamos los dos valores, retornando True si son iguales y False si son diferentes, esto lo podemos hacer con una simple sentencia IF.


    Public Function Comparar(ByVal ValorSinEncriptar As String, ByVal ValorEncriptado As String) As Boolean


        If EncriptarHash(ValorSinEncriptar) = ValorEncriptado Then


            Return True


        Else


            Return False


        End If


    End Function


#End Region


 


#Region “Encriptar/Desencriptar”


    Const StrClave As String = “EjemploDeCodigo”


    Public Function EncriptarTexto(ByVal CadenaAEncriptar As String, Optional ByVal Clave As String = StrClave, Optional ByVal MantenerMayusculas As Boolean = True)


        Dim i As Integer, C As Integer


        Dim CadenaEncriptada As String


        If MantenerMayusculas = False Then


            Clave = Clave.ToUpper()


            CadenaAEncriptar = CadenaAEncriptar.ToUpper()


        End If


        If Len(Clave) Then


            For i = 1 To Len(CadenaAEncriptar)


                C = Asc(Mid$(CadenaAEncriptar, i, 1))


                C = C + Asc(Mid$(Clave, (i Mod Len(Clave)) + 1, 1))


                CadenaEncriptada = CadenaEncriptada & Chr(C And &HFF)


            Next i


        Else


            CadenaEncriptada = CadenaAEncriptar


        End If


        Return CadenaEncriptada


    End Function


 


    Public Function DesencriptarTexto(ByVal CadenaADesencriptar As String, Optional ByVal Clave As String = StrClave, Optional ByVal MantenerMayusculas As Boolean = True)


        Dim i As Integer, C As Integer


        Dim CadenaDesencriptada As String


        If MantenerMayusculas = False Then


            Clave = Clave.ToUpper


        End If


        If Len(Clave) Then


            For i = 1 To Len(CadenaADesencriptar)


                C = Asc(Mid$(CadenaADesencriptar, i, 1))


                C = C – Asc(Mid$(Clave, (i Mod Len(Clave)) + 1, 1))


                CadenaDesencriptada += Chr(C And &HFF)


            Next i


        Else


            CadenaDesencriptada = CadenaADesencriptar


        End If


        Return CadenaDesencriptada


    End Function


#End Region


End Class