无法从静态资源设置 CornerRadius 值

Posted

技术标签:

【中文标题】无法从静态资源设置 CornerRadius 值【英文标题】:Cannot set CornerRadius value from static resource 【发布时间】:2012-02-01 13:01:03 【问题描述】:

我已经定义了一个静态资源:

<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”。

我做错了什么?我如何使它工作?谢谢。

【问题讨论】:

请注意,我确实需要具体说明左上角。其他角应该绑定到其他一些静态资源值... 如果您想在运行时更改它,请将其设为 DynamicResource。 ~10 年后,您的解决方案可以正常工作。也许他们改变了 CornerRadius 的定义方式。 【参考方案1】:
<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" />
...

【讨论】:

谢谢谢谢谢谢,我只是无法解决这个问题,任何遇到这个问题的人都应该记住用于涉及这种性质的 XAML 的任何其他内容 =)【参考方案2】:

MSDN:

您可以在 XAML 中设置此值,但只能作为采用 CornerRadius 的属性的属性语法的一部分,或作为 CornerRadius 对象元素的初始化文本。请参阅CornerRadius 的 XAML 部分和备注部分。

您可以尝试绑定整个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 中确实存在问题)

【讨论】:

【参考方案3】:

我相信CornerRadius 属性不是DependencyProperties,所以它们不能通过绑定来设置。

我能想到的两个替代方案是使用MultiConverter,它接受Border 对象的参数和所需的CornerRadius,或者为CornerRadius 创建一个自定义的DependencyProperty。这两种方法都需要您在代码隐藏中设置值。

【讨论】:

@HB Hrrm 我认为它是一个结构。其实我明白你的意思,Border.CornerRadius 是一个依赖属性,但是CornerRadius 上的属性不是。我已经编辑了我的答案。 CornerRadius 类型当然是结构体,但Border.CornerRadius 是 DP,这也不是绑定,您可以在任何属性上使用其他标记扩展(如 StaticResource)。 @HB Hrrm 我每天都学到新东西。我从来没有真正考虑过,但我认为这是有道理的,因为StaticResource 得到了一次解决,所以不需要DependencyProperty

以上是关于无法从静态资源设置 CornerRadius 值的主要内容,如果未能解决你的问题,请参考以下文章

解决从私库下载下来已经编译好的项目核心部分,改变其编译后的静态资源后无法打包进改变部分的问题

Swift - 同时设置cornerRadius和阴影

CornerRadius 未设置

在按钮模板上设置CornerRadius

使用将 maskToBounds 设置为 true 和cornerRadius 不会更改视图

根据子类中的 UIButton 大小设置cornerRadius 的最佳位置?