April 2011 - Posts
Esta es una copia cruzada del artículo escrito en el blog original:
C# – WPF – Escalar el tamaño de la fuente al cambiar el tamaño de la ventana o control
---------------------------------------------------------
Cambiar el tamaño de la fuente a medida que el control cambia de tamaño es una tarea frecuente, pero esta pobremente documentada, en este articulo esta la respuesta.
Este es uno de esos temas…
Puedes pasar horas buscando diferentes alternativas alrededor de la web, encontraras cosas como
- ViewBox
- FontSizeConverter
- IValueConverter
- etc.
Nada de eso funciona al menos no como se espera, aunque según el caso pueden dar una buena aproximación a la solución.
He escrito este artículo para ayudar a muchos desarrolladores (y diseñadores) a resolver este problema de manera definitiva.
Cómo realizar el cálculo de tamaño de fuente?
Dado que las fuentes, en su mayoría, son más altas que anchas es importante entonces que usemos como referencia la propiedad Height del control contenedor para definir el tamaño de la fuente con respecto a su dimensión más grande.
El alto de la fuente esta dictado por la medición de tres partes básicas:
- Ascendente
- Descendente
- Inicial
Observando esta gráfica es fácil hacerse una mejor idea:

La clase FontFamily en WPF posee la propiedad LineSpacing, la cual es ni más ni menos que el alto total de la fuente de acuerdo a los parámetros anteriormente citados.
Sin embargo esto no es todo, la propiedad LineSpacing es un valor genérico para la FontFamily sin importar el tamaño actual de la fuente utilizada, es decir este atributo nos da una relación proporcional respecto al tamaño de la fuente en unidades em.
Por ende podemos decir que el alto de una fuente en unidades em es
Alto = tamaño fuente * FontFamily.LineSpacing
Eso es correcto, pero nosotros no necesitamos calcular el alto de la fuente, sino calcular el tamaño de la fuente con respecto al Height del contenedor ( Button, Window etc), en ese caso la formula a utilizar sería:
tamaño fuente = Alto / FontFamily.LineSpacing
Implementación
Creamos una ventana de WPF con el siguiente código
1 2 3 4 5 6 7 8 9 10 | <Window x:Class="AutoScaleFont.MainWindow"
Title="MainWindow" Height="350" Width="525">
<DockPanel>
<Label HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
SizeChanged="Control_SizeChanged">
Test</Label>
</DockPanel>
</Window>
|
En el archivo de código creamos el controlador para el evento SizeChanged
1 2 3 4 5 | private void Control_SizeChanged(object sender, SizeChangedEventArgs e)
{
Control tmp = sender as Control;
tmp.FontSize = e.NewSize.Height / tmp.FontFamily.LineSpacing;
}
|
El código se explica a si mismo, sin embargo haré una explicación breve. Establecemos la propiedad FontSize de acuerdo a la formula explicada más arriba tomamos el nuevo Alto del control y lo dividimos en la propiedad LineSpacing del FontFamily utilizado por el control.
Una optimización adicional es hacer que el alto de la fuente sea calculado con un valor levemente menor al del control contenedor para dejar un espacio de margen, con el ánimo de hacerlo proporcional le restamos solo un porcentaje respecto al alto total, en este caso el 5%, quedando así:
1 2 3 4 5 | private void Control_SizeChanged(object sender, SizeChangedEventArgs e)
{
Control tmp = sender as Control;
tmp.FontSize = (e.NewSize.Height - e.NewSize.Height * .05d) / tmp.FontFamily.LineSpacing;
}
|
Iniciemos la ejecución y revisemos el resultado:



Eso es justo lo que deseamos!
Si lo deseas puedes hacerlo respecto al ancho del control en lugar de respecto al alto, según sea tu necesidad, en ese caso debes ayudarte con la clase FormattedText y su propiedad Width para hallar el largo total en pixeles de la cadena.
Una semana agitada sin duda, negocios, aprendizaje, cambios en el trabajo, nuevas propuestas, mucho trasnocho… y enfermo.
Ha sido difícil. Sin embargo tengo una hermosa familia y muchas cosas positivas que lo compensan todo.
Así que las cosas son buenas, pero serían mejor.
Viernes 1 Abril 2011 09:12:17
Salía para una reunión, pero decidí ver el correo justo antes de salir, me lleve una agradable sorpresa

Inmerecido?
No lo se, de verdad no se que pensar, cada día que paso metido en temas tecnológicos me encuentro con gente grande, verdaderamente GRANDE, no solo en el sentido técnico sino también en su espíritu profesional, en su pasión y en su vida. No me puedo igualar con ninguno.
Han sido duras lecciones, seguramente muchos pasan eso en algún momento y supongo que, tristemente, no todos se logran dar cuenta de lo equivocados que estaban.
En el año 2003, o por esa época, solía creerme el super programador, el mejor en todo, sin duda era muy bueno en muchas cosas, era ‘un enorme genio’ frente a mi computador donde solo contaba Yo.
Así es fácil creerse un genio.
Con el tiempo la vida, como de costumbre, me ha dado duras lecciones, que considero me han hecho un mejor hombre y un mejor profesional.
Mis diferentes trabajos me fueron aterrizando, luego en 2007 me comencé a vincular con las comunidades y allí comenzaron a cambiar, de raíz, dos cosas:
- Ya no estaba frente al computador de mi casa, ahora estaba en una comunidad de muchas personas genio
- Ya no era un genio, me di cuenta que nunca lo fui.
Con el paso de los años he continuado aprendiendo cosas, técnicas y humanas, y también he conocido mucha gente, diferentes personas distribuidas geográficamente en lo que en otro momento llamábamos el enorme planeta tierra, hoy todos estamos a un clic de distancia.
Esta corta distancia me permitió descubrir a todos los verdaderos genios y talentos que hay allí justo a un clic de distancia de mí, cada semana o incluso cada día logro descubrir personas que son mucho mejores que yo, y que de una u otra forma, son mis maestros.
En mi opinión muchos o tal vez todos ellos merecen ser reconocidos como MVP, muchos ya lo son, pero he aprendido y tengo que aprender tantas cosas de ellos que bueno, a veces me pregunto si verdaderamente lo merezco.
Para ser reconocido como MVP he necesitado de muchas personas
Creo que no soy Juan Carlos Ruiz Microsoft MVP a secas.
Para lograr este reconocimiento he necesitado del apoyo de muchas personas, de mi equipo de amigos colaboradores de BogotaDotNet, de mi familia, de mis compañeros de trabajo, de mis followers en las redes sociales, de mis inspiradores y…
de mis detractores.
Mi nombramiento no es solo un reconocimiento para mí, sino es un reconocimiento para todos ustedes.
Soy Juan Carlos Ruiz Microsoft MVP porque cuento con personas como ustedes, alguien que "se cree un genio detrás del computador de su casa" no puede ser un MVP por si solo, mucho menos tres veces seguidas. He necesitado de su apoyo incondicional, de sus críticas, de sus ideas, de los espacios que me han brindado, de sus ganas de aprender, de sus ganas de enseñar, de su ejemplo y de su reconocimiento.
Gracias a todos por esta tercera vez y por todas las anteriores.
Esta es una copia cruzada del artículo escrito en el blog original:
MVP por tercer año consecutivo – no se como me aguantan
---------------------------------------------------------
Esta es una copia cruzada del artículo escrito en el blog original:
Porqué mis soluciones de SharePoint instaladas por PowerShell no se ven en la galería de soluciones?
---------------------------------------------------------
Interesante pregunta.
SharePoint 2010 posee una característica llamada Sandboxed Solution, estas soluciones son las instaladas por ‘el usuario final’ y estas quedan en una ‘capsula’ de seguridad que evita la ejecución de código malintencionado o dañino dentro de SharePoint. Solo las soluciones instaladas y creadas como Sandboxed Solution aparecen en la galería de soluciones del sitio, así mismo las características de estas soluciones solo son visibles si la solución es de tipo SandBoxed.
Por el contrario las soluciones ‘normales’ o avanzadas de SharePoint solo pueden ser instaladas a través de un Project setup o de comandos vía PowerShell, al ser soluciones no ‘de usuario’ estas son visibles únicamente desde el sitio de administración central de SharePoint 2010 y no es posible que un usuario las instale agregándolas a la galería de soluciones de su sitio, ya que sería alertado con que la solución no contiene un XML esperado… el XML de las Sanboxed Solutions.
Así las cosas si deseas que tu solución de SharePoint 2010 permita ser instalada tan solo agregándola a la galería de soluciones y que sus características sean habilitadas o deshabilitadas desde las pantallas del usuario, tendrás que crearlas como Sandboxed Solution, de lo contrario crea y desplega una solución normal.
Incluso si tu solución solo consta de WebParts la única forma de que SharePoint desempaquete todo el .wsp desde la UI de aplicación es que tu solución sea de tipo sandbox, de lo contrario debes hacer la instalación asistida por comandos de PowerShell.
Saludos,
Esta es una copia cruzada del artículo escrito en el blog original:
Como eliminar un .webpart de SharePoint 2010 que no se borra despues de desinstalar la solución via PowerShell
---------------------------------------------------------
Como lo comenté en un artículo anterior una vez se desinstala una solución que contiene un .webpart por alguna razón este .webpart persiste en la Galería de elementos web de SharePoint 2010, para borrarlo hay que utilizar un poco de ‘astucia’ de desarrollador utilizando PowerShell.
He creado este sencillo script de PowerShell el cual con solo indicar el url del sitio y el nombre del .webpart es capaz de encontrarlo y borrarlo.
Para mayor funcionalidad el nombre del .webpart lo he dejado como una cadena de expresiones regulares de tal forma que podamos hacer una selección más fléxible delos .webpart que deseamos remover.
Como todo, no es perfecto, es susceptible de mejora, una primera mejora sería hacerlo independiente del idioma ya que el nombre de la galería esta establecido por defecto en español pero cambia si utilizas la versión en inglés o en otro idioma.
Acá les dejo el script que sin lugar a dudas sacara de apuros a más de uno al rededor de la web.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.WebPartPages")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Publishing")
$url = Read-Host "Ingrese el nombre del servidor"
$wps = Read-Host "Escriba el patrón del webpart"
$SPSite = New-Object Microsoft.SharePoint.SPSite($url)
$SPWeb = $SPSite.OpenWeb()
$WebPartGallery = $SPWeb.Lists["Galería de elementos web"]
$gall = $WebPartGallery.Items | select Name
$count = $gall.Count
$count
for ( $i =0; $i -lt $count;$i++)
{
Write-Host "Actual:" $gall[$i].Name
if ($gall[$i].Name -match $wps)
{
Write-Host "found"
$WebPartGallery.Items.Delete($i)
$SPWeb.Update()
Write-Host "$wp borrado"
}
}
$SPWeb.Dispose()
|
Un ejemplo de uso para eliminar el .webpart del que hablamos en este artículo “Como instalar una solución (.wsp) de SharePoint 2010 via PowerShell” es
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | .\borrarWebpart.ps1
GAC Version Location
--- ------- --------
True v2.0.50727 C:\Windows\assembly\GAC_MSIL\Microsoft.SharePoint\14.0.0.0__71e9bce111e9429c\Microsoft.SharePo...
Escriba el patrón del webpart: ^TestWeb.*$
11
Actual: MSContentEditor.dwp
Actual: MSPageViewer.dwp
Actual: MSImage.dwp
Actual: MSMembers.dwp
Actual: MSSimpleForm.dwp
Actual: MSUserDocs.dwp
Actual: MSUserTasks.dwp
Actual: MSXml.dwp
Actual: MSPictureLibrarySlideshow.webpart
Actual: Silverlight.webpart
Actual: TestWebPart_VisualWebPart1.webpart
found
borrado
|
Estoy imaginando muchas sonrrisas en este momento ! XD
Esta es una copia cruzada del artículo escrito en el blog original:
Como instalar una solución (.wsp) de SharePoint 2010 via PowerShell
---------------------------------------------------------
Hola, dado la poca documentación que existe en la web al respecto de este tema he decidido escribir este artículo que estoy seguro le será de mucha utilidad a todos ustedes.
Una vez generado el paquete desde Visual Studio 2010, abrimos una consola de administración de SharePoint, sobra decir que la debemos abrir con privilegios de administrador ( clic derecho, ejecutar como administrator ).
Inicia el trabajo, revisaremos primero la forma de realizar la instalación, seguidamente como hacer la desinstalación y finalmente un tip que les será útil a todos.
Instalación de la solución
La instalación se divide en 3 partes
- Subir la solución
- Instalarla
- Activar las características
Procedemos a ejecutar los siguientes pasos en la consola de administración de SharePoint 2010, como la instalación puede ser un proceso ‘incomodo’ entonces lo primero que realizaremos será crear tres variables, una de ellas para la ubicación del sitio, otra para el nombre de la solución y una última para el nombre de la característica.
En este ejemplo los valores para esas variables son:
- url del sitio esta en http://localhost
- nombre de la solución TestWebPart.wsp
- nombre de la única característica de la solución “TestWebPart Feature1″ o su id = “64C2C32C-064D-4216-BB63-6A67EFE828D1″
Así que los primeros comandos a ejecutar son para inicializar las variables
1 2 3 | $SolName="TestWebPart.wsp"
$FeaName="TestWebPart_Feature1"
|
1. Subir la solución
Cambiamos al directorio donde esta el archivo .wsp
seguidamente ejecutamos el siguiente comando, -LiteralPath nos pide el path completo del archivo .wsp, no importa si ya estamos en el directorio en todo caso debemos poner la ruta completa.
1 | Add-SPSolution -LiteralPath "C:\TestWebPart.wsp"
|
Esto nos debe generar la siguiente salida
1 2 3 | Name SolutionId Deployed
---- ---------- --------
testwebpart.wsp 2361bfd2-d113-4f4d-8941-cfdb66edb891 False
|
2. Instalar la solución
Una vez hemos subido la solución al servidor procedemos a instalarla así
1 | Install-SPSolution -Identity $SolName -WebApplication $SiteUrl -GACDeployment
|
Si el comando fue exitoso no hay ningún feedback por consola.
3. Activación de las características de la solución
La solución ya está instalada así que ahora debemos activar las características que hemos incluido. Si hemos desarrollado un Webpart desde Visual Studio 2010 este crea automáticamente una característica, podemos instalarla haciendo uso de su nombre o de is en caso de que lo hayas generado
Tip: si el nombre de la característica tiene espacios, deberás reemplazarlos por el carácter ‘_’ (línea al piso)
1 | Install-SPSolution -Identity $SolName -WebApplication $SiteUrl -GACDeployment
|
Si el comando fue exitoso no hay ningún feedback por consola.
Con eso finalizamos la parte de la instalación, así que vamos a SharePoint y verificamos.
En este caso estamos instalando un webpart así que vamos a Acciones del sitio, Configuración, Elementos web y allí debes encontrar el webpart que acabamos de instalar.

Desinstalación de la solución
Esta parte es básicamente lo mismo pero al revez, si, así de fácil.
- Desactivar las características
- Desinstalar la solución
- Remover la solución
1. Desactivar las características
1 | Disable-SPFeature -Identity $FeaName -Url $SiteURL -Confirm:$false
|
Si es exitoso no hay respuesta
3. Remover la solución
Este comando no sirve pada nada. Así es lo tenemos que ejecutar pero no hace lo que se supone que debe hacer, o mejor, lo hace a medias…
1 | Remove-SPSolution -Identity $SolName -Confirm:$false
|
Si es exitoso no hay respuesta.
Sin embargo si revisamos nuestro webpart aún aparece solo que no se puede usar para nada. Se supone que precisamente este comando lo remueve, pero realmente remueve la solución pero no todos sus componentes, de seguro un bug.
En un próximo artículo les mostraré como eliminar por completo el rastro del webpart que no desapareció.