/ / No se puede establecer el valor de CornerRadius a partir del recurso estático: silverlight, xaml, resourcedictionary, cornerradius

No se puede establecer el valor de CornerRadius desde un recurso estático: silverlight, xaml, resourcedictionary, cornerradius

He definido un recurso estático:

<UserControl x:Class="MyProject.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Width="255"
Height="300">

<UserControl.Resources>
<sys:Double x:Key="CornerRadiusValue">5</sys:Double>
</UserControl.Resources>
...

Más adelante en el archivo XAML, estoy tratando de usar ese valor al configurar el radio de la esquina superior izquierda para un borde:

<Border
Width="40"
Height="30"
BorderThickness="1,1,0,0"
BorderBrush="Red">
<Border.CornerRadius>
<CornerRadius TopLeft="{StaticResource CornerRadiusValue}" />
</Border.CornerRadius>
</Border>

En tiempo de diseño, todo funciona bien y cambia el valor de CornerRadiusValue El recurso estático cambia el radio de la esquina en un borde. Sin embargo, cuando quiero ejecutar esto, obtengo un XamlParseException excepción con el mensaje:

No se puede establecer la propiedad de solo lectura `System.Windows.CornerRadius.TopLeft".

¿Qué estoy haciendo mal? ¿Cómo lo hago funcionar? Gracias.

Respuestas

2 para la respuesta № 1

MSDN:

Puede establecer este valor en XAML, pero solo como parte de la sintaxis de atributo para las propiedades que toman un Radio de esquinao como texto de inicialización de un Radio de esquina elemento objeto Consulte las secciones XAML y las secciones Comentarios de Radio de esquina.

Podrías intentar unir todo CornerRadius propiedad y usar un convertidor para obtener todos los recursos y crear un CornerRadius instancia de ellos usando el constructor.

p.ej. utilizando solo un valor:

<Border Name="bd" BorderBrush="Red" BorderThickness="1">
<Border.Resources>
<sys:Double x:Key="CR_TopLeft">5</sys:Double>
</Border.Resources>
<Border.CornerRadius>
<Binding ElementName="bd">
<Binding.Converter>
<vc:CornerRadiusConverter />
</Binding.Converter>
</Binding>
</Border.CornerRadius>
<Button>!</Button>
</Border>
public class CornerRadiusConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var resourceSource = (FrameworkElement)value;
var topLeft = (double)resourceSource.Resources["CR_TopLeft"];
return new CornerRadius(topLeft, 0, 0, 0);
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}

Probablemente podría hacer que esto sea más genérico buscando los recursos que suben por el árbol y no apuntando directamente al objeto en el que se definen los recursos.

(Este es un problema exclusivo de Silverlight, en WPF su código funciona bien, si tiene una pregunta de Silverlight, evite la etiqueta WPF a menos que el problema realmente exista en WPF)


3 para la respuesta № 2
<sys:Double x:Key="ScrollbarHandleCrValue">3</sys:Double>
<CornerRadius x:Key="ScrollbarHandleCornerRadius"
TopLeft="{StaticResource ScrollbarHandleCrValue}"
TopRight="{StaticResource ScrollbarHandleCrValue}"
BottomRight="{StaticResource ScrollbarHandleCrValue}"
BottomLeft="{StaticResource ScrollbarHandleCrValue}" />

...
<Border Name="Border"
CornerRadius="{StaticResource ScrollbarHandleCornerRadius}"
Background="{StaticResource ScrollbarHandleColor}"
BorderBrush="Transparent"
BorderThickness="1" />
...

0 para la respuesta № 3

Creo CornerRadius las propiedades no son DependencyProperties, por lo que no se pueden establecer mediante un enlace.

Las dos alternativas que se me ocurren es usar un MultiConverter que acepta los parámetros de la Border objeto y deseado CornerRadius, o para crear una DependencyProperty personalizada para CornerRadius. Ambos métodos requieren que establezca el valor en código subyacente.