Невозможно установить значение CornerRadius из статического ресурса

Я определил статический ресурс:

<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>
...

Позже в файле XAML я пытаюсь использовать это значение при установке радиуса верхнего левого угла для границы:

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

Во время разработки все работает нормально и меняя значение для CornerRadiusValue Статический ресурс меняет радиус угла на границе. Однако, когда я хочу запустить это, я получаю XamlParseException исключение с сообщением:

Невозможно установить доступное только для чтения свойство System.Windows.CornerRadius.TopLeft.

Что я делаю неправильно? Как мне заставить это работать? Благодарю.

3 ответа

Решение

MSDN:

Вы можете установить это значение в XAML, но только как часть синтаксиса атрибута для свойств, которые принимают CornerRadius, или как текст инициализации элемента объекта CornerRadius. Смотрите разделы XAML и разделы замечаний CornerRadius.

Вы можете попытаться связать весь CornerRadius свойство и использовать конвертер, чтобы получить все ресурсы и создать CornerRadius Экземпляр из них с помощью конструктора.

например, используя только одно значение:

<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();
    }
}

Вероятно, вы можете сделать это более общим, если искать ресурсы, идущие вверх по дереву, а не напрямую нацеливаясь на объект, для которого определены ресурсы.

(Это проблема только с Silverlight, в WPF ваш код работает нормально, если у вас есть вопрос о Silverlight, избегайте тега WPF, если проблема не существует в WPF)

<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" />
...

Я верю CornerRadius свойства не DependencyPropertiesпоэтому они не могут быть установлены через привязку.

Я могу придумать две альтернативы: MultiConverter который принимает параметры Border объект и желаемый CornerRadiusили создать пользовательский DependencyProperty для CornerRadius, Оба метода потребуют от вас установить значение в коде.

Другие вопросы по тегам