Categoría: mis cosas

Posts de tipo personal o al menos que no son técnicos

  • hay que ver… como es el Format con las llaves…

     

    Pues eso… que si usas Format, en cualquiera de sus encarnaciones: String.Format, StringBuilder.AppendFormat, Console.WriteLine, (incluso la función Format de Visual Basic) etc. y estas usando llaves para indicar parámetros (marcadores de posición que dicen en la documentación), mucho cuidado con que la cadena que estás formateando no tenga también llaves, porque entonces la hemos "pifiao".

     

    El problema

     

    Por ejemplo, si tienes esta cadena (o este código XAML):

     

    Dim xaml = <StackPanel Style="{StaticResource spImagen}">
                   <Image Source="ms-appx:///contenido/img/{0}"
                       Style="{StaticResource Imagen}"/>
               </StackPanel>
    
    

     

    Y pretendes usarlo con algo como esto:

    VB:

     

    sb.AppendFormat(xaml.ToString & "{1}",
                    sText.Replace(".tif", ".jpg"), vbCrLf)
    

     

    C#:

    Nota:

    En C# no se puede usar el contenido XML directamente, pero no es complicado adaptarlo, eso sí, es algo más laborioso que en Visual Basic, todo hay que decirlo. Pero para este caso que es poco código lo pasaremos por alto 😉

     

    string xaml = @"<StackPanel Style=""{StaticResource spImagen}"">
                        <Image Source=""ms-appx:///contenido/img/{0}""
                            Style=""{StaticResource Imagen}""/>
                    </StackPanel>";
    
    sb.AppendFormat(xaml + "\n",
                    sText.Replace(".tif", ".jpg"));
    

     

    Si usamos este código (ya sea con VB o con C#) el compilador producirá una excepción de formato no válido (FormatException) y es porque el "formateador" se encuentra con llaves (de inicio y/o de cierre) que no tienen un valor numérico asignado.

     

    FormatException

    Figura 1. El error en la aplicación de C# (es el mismo que en VB)

     

     

    La solución

     

    Pues… quitar las cadenas con las llaves que no sean "marcadores" y agregarlas en el propio AppendFormat:

     

    VB:

     

    Dim xaml = <Paragraph TextAlignment="Center">
                   <InlineUIContainer>
                       <StackPanel Style="{0}">
                           <Image Source="ms-appx:///contenido/img/{1}"
                               Style="{2}"/>
                       </StackPanel>
                   </InlineUIContainer>
               </Paragraph>
    
    sb.AppendFormat(xaml.ToString & "{3}",
                    "{StaticResource spImagen}",
                    sText.Replace(".tif", ".jpg"),
                    "{StaticResource Imagen}", vbCrLf)
    

     

    C#:

     

    string xaml = @"<StackPanel Style=""{0}"">
                        <Image Source=""ms-appx:///contenido/img/{1}""
                            Style=""{2}""/>
                    </StackPanel>";
    
    sb.AppendFormat(xaml + "\n","{StaticResource spImagen}",
                    sText.Replace(".tif", ".jpg"), "{StaticResource Imagen}");
    

     

    Es decir, ponemos para cada una de las "llaves fatídicas" una cadena con un marcador (de posición) y ponemos esas cadena (con sus llaves) en los parámetros de la función Format y asunto solucionado.

     

    Nota del Guille:

    Mira que esto mismo ya me pasó ayer (o hace un puñao de horas) y después me volvió a pasar, pero he estado un buen rato dándole vueltas al tema (se me olvidó que volví a cambiar el código XAML) y no daba con el dichoso error… eso me pasa por dos razones:

    1.- no tener buena memoria, no dormir lo suficiente, ser más cabezón que el Visual Studio

    2.- no usar suficientes Try/catch para "acorralar" el error…

    En fin… lo importante es que he dado con el error y que te lo cuento por si te pasa a ti.

     

    Si todo va bien, ya mismo te explicaré para qué estoy usando ese código (el de Visual Basic, ya que el de C# sólo lo he escrito para aquellos que les gustan los puntos y comas)…

     

    Lo dicho, espero que te pueda ser de ayuda… esa siempre es la intención 😉

     

    Nos vemos.

    Guillermo

    …

  • Presuntamente algunas funciones de Microsoft.VisualBasic no son compatibles con las aplicaciones para Windows Store

     

    Pues eso… que en un proyecto DLL (biblioteca de clases) para Windows Store no me ha reconocido ciertas funciones de manipulación de cadenas que están definidas en el módulo Strings del espacio de nombres Microsoft.VisualBasic (que es como si dijéramos el "runtime" de Visual Basic para .NET).

    Lo de presuntamente es por si he hecho algo mal y por eso no me reconocía algunas funciones… al menos en un proyecto del tipo biblioteca de clases (class library), en la figura 1 tienes las cosas que se pueden usar de ese módulo con las funciones de cadena.

     

    Microsoft.VisualBasic.Strings en app store class library
    Figura 1. Las funciones que muestra Strings en un proyecto del tipo Class library para Windows store

     

    Nota:
    En una aplicación para Windows Store (no una librería de clases) también muestra los mismos métodos. En una aplicación/librería para el escritorio (incluso de Windows 8) muestra las que estamos habituados a usar.

     

    Así que… me las he tenido que fabricar, al menos las que me han hecho falta para este caso concreto, que no es otro que una actualización de mi librería (perdón, biblioteca) para colorear código: gsColorearCodigo.

    Aquí te dejo un módulo de Visual Basic para hacer las conversiones… lo mismo ya tenía algo publicado sobre algo parecido, pero…

     

    '------------------------------------------------------------------------------
    ' VBStrings                                                         (01/Ene/13)
    '
    ' Para simular las funciones de cadena de Visual Basic
    ' ya que parece que el runtime para Windows Store no incluye algunas funciones
    '
    ' ©Guillermo 'guille' Som, 2013
    '------------------------------------------------------------------------------
    Option Strict On
    Option Infer On
    
    
    Public Module VBStrings
        ''' <summary>
        ''' Devuelve la posición (en base 1) de cadena1 en cadena2
        ''' </summary>
        ''' <remarks></remarks>
        Public Function InStr(cadena1 As String, cadena2 As String) As Integer
            Try
                Dim i = cadena1.IndexOf(cadena2)
                Return i + 1
            Catch ex As Exception
                Return 0
            End Try
        End Function
    
    
        ''' <summary>
        ''' Devuelve la posición en base 1 de cadena1 en cadena2
        ''' se comprueba a partir de la posición desde
        ''' </summary>
        ''' <remarks></remarks>
        Public Function InStr(desde As Integer, cadena1 As String, cadena2 As String) As Integer
            Try
                Dim i = cadena1.IndexOf(cadena2, desde - 1)
                Return i + 1
            Catch ex As Exception
                Return 0
            End Try
        End Function
    
        ''' <summary>
        ''' Devuelve una cadena con los cuantos primeros caracteres de cadena1
        ''' El primer caracter es el 1 y se devuelve en base 1
        ''' </summary>
        ''' <remarks></remarks>
        Public Function Left(cadena1 As String, cuantos As Integer) As String
            If String.IsNullOrWhiteSpace(cadena1) OrElse cuantos < 1 Then
                Return ""
            End If
    
            Dim s = cadena1.Substring(0, cuantos - 1)
            Return s
        End Function
    
        ''' <summary>
        ''' Devuelve la cantidad de caracteres que tiene cadena1
        ''' </summary>
        ''' <remarks></remarks>
        Public Function Len(cadena1 As String) As Integer
            If String.IsNullOrWhiteSpace(cadena1) Then
                Return 0
            End If
    
            Return cadena1.Length
        End Function
    
        ''' <summary>
        ''' Devuelve una cadena nueva después de quitarle
        ''' los espacios del principio y del final
        ''' </summary>
        ''' <remarks></remarks>
        Public Function Trim(cadena1 As String) As String
            If String.IsNullOrWhiteSpace(cadena1) Then
                Return ""
            End If
    
            Return cadena1.Trim()
        End Function
    
        ''' <summary>
        ''' Devuelve una cadena a partir de la posición desde
        ''' La pirmera posición es la 1
        ''' </summary>
        ''' <remarks></remarks>
        Public Function Mid(cadena1 As String, desde As Integer) As String
            If String.IsNullOrWhiteSpace(cadena1) OrElse desde < 1 Then
                Return ""
            End If
    
            Return cadena1.Substring(desde - 1)
        End Function
    
        ''' <summary>
        ''' Devuelve una cadena con cuantos caracteres de cadena1 
        '''  a partir de desde
        ''' La primera posición es la 1
        ''' </summary>
        ''' <remarks></remarks>
        Public Function Mid(cadena1 As String, desde As Integer, 
                                                cuantos As Integer) As String
            If String.IsNullOrWhiteSpace(cadena1) OrElse desde < 1 Then
                Return ""
            End If
    
            Return cadena1.Substring(desde - 1, cuantos)
        End Function
    
        ''' <summary>
        ''' Trocea una cadena usando los caracteres indicados
        ''' </summary>
        ''' <remarks></remarks>
        Public Function Split(cadena1 As String, caracteres As String) As String()
            Return cadena1.Split(caracteres.ToCharArray, 
                                  StringSplitOptions.RemoveEmptyEntries)
        End Function
    End Module
    
    
    

     

    Espero que te sea de utilidad.

     

    Nos vemos.

    Guillermo

    …

  • que dice el Guille que…

     

    Pues eso… en este día 31 de diciembre de 2012… ¿qué quieres que te diga?…

    ¡¡¡ Feliz 2013 !!!

     

     

     

    Nos vemos… el año que viene…
    Guillermo

    …