Pregunta

Recientemente descubrí que WPF admite diferentes unidades de medida en XAML.Además de los DIP predeterminados, también hay soporte para píxeles, pulgadas y centímetros (hasta donde yo sé).Esto permite al diseñador escribir XAML como este:

<Canvas>
    <Line X1="0cm" X2="3cm" Y1="1cm" Y2="3cm" Stroke="Black"/>
</Canvas>

Sin embargo, no puede vincular estos valores.Imaginemos que tenemos un ViewModel con la propiedad Dimension que es una Cadena, por ejemplo "7cm".Lo siguiente no funcionará:

<Button Width="{Binding Dimension}">Test</Button>

Se lanza FormatException.De manera similar, al crear un FrameworkElement en código subyacente, así:

Canvas1.Children.Add(new Button() { Width = "3cm", Content = "Test"});

La compilación falla porque se lanza una excepción en el constructor/dondequiera que intente crear el control.

Me pregunto:

  • ¿Es posible utilizar unidades naturales (en mi caso, métricas, centímetros) en el código subyacente?
  • ¿Cómo?
  • ¿Existe una lista completa de unidades compatibles con WPF/XAML?

EDITAR:

Aquí hay un enlace del comentario a continuación, que resuelve esta pregunta:

http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.width.aspx

¿Fue útil?

Solución

Puede hacer esto en el código subyacente aplicando la misma conversión que usa el analizador XAML; no necesita volver a implementar esta lógica si no le importa pasar cadenas:

button.Width = (double)new LengthConverter().ConvertFrom("2cm");

El analizador XAML utiliza Convertidores de tipo para convertir cadenas a los valores necesarios, en el página de documentación del Width propiedad puedes ver que tiene un TypeConverterAttribute especificando que un LengthConverter debería ser usado.Este atributo se puede utilizar para anular localmente cómo se debe manejar una propiedad, pero también se puede aplicar a nivel de clase, por lo que si un Employee La clase tiene este atributo que especifica que un EmployeeConverter debe usarse dicho convertidor será el predeterminado para propiedades de tipo Employee.

Estoy un poco sorprendido de que el enlace no aplique este tipo de convertidor, pero usarlo dentro de un IValueConverter Sería bastante simple; de ​​hecho, podrías crear un extensión de marcado que construye un IValueConverter desde un convertidor de tipos para hacerlo bien genérico.

Otros consejos

Para 1) y 2) Debido a que los DIP son independientes del dispositivo, puede calcular cualquier "unidad natural" desde y hacia sin problemas.La excepción son los píxeles (antinaturales :) que dependen del dispositivo.

Crear un Convertidor de valores que convierte valores de cadena en dobles donde se pueden especificar las unidades deseadas en la cadena.Luego puede usar ValueConverter en su Binding y calcular en su ViewModel en "unidades naturales".

Para 3) y la implementación:Busqué rápidamente en Google y no encontré nada, pero tal vez una búsqueda más profunda muestre algo.De lo contrario, crear tu propio convertidor no debería ser muy difícil.Aquí algunas informaciones de conversión:

96DIP == 1inch == 2.54cm;
1cm == 37.8DIP;
1zoll == 1inch == 2.54cm;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top