无法在Silverlight中的样式中添加系统颜色?

无法在Silverlight中的样式中添加系统颜色?,silverlight,coding-style,systemcolors,Silverlight,Coding Style,Systemcolors,我在XAML中为SystemColor定义了资源。如果我直接将Foregroung属性设置为TextBlock,效果会很好。但是,如果我在样式中指定前景属性,则会出现如下所示的错误。我不知道问题是什么,如何解决。任何想法都将受到高度赞赏 直接在texblock中设置前景时的代码。它工作得很好 <TextBlock Text="WindowTextColor" Foreground="{Binding WindowTextColor, Source={StaticResource Syste

我在XAML中为SystemColor定义了资源。如果我直接将Foregroung属性设置为TextBlock,效果会很好。但是,如果我在样式中指定前景属性,则会出现如下所示的错误。我不知道问题是什么,如何解决。任何想法都将受到高度赞赏

直接在texblock中设置前景时的代码。它工作得很好

<TextBlock Text="WindowTextColor" Foreground="{Binding WindowTextColor, Source={StaticResource SystemColors}, Converter={StaticResource colorConverter}}" />

通过样式设置前景属性时的代码。我的应用程序崩溃:

<UserControl.Resources> 
  <local:ColorToBrushConverter x:Key="colorConverter" />
  <local:SystemColorsWrapper x:Key="SystemColors" />
  <Style x:Key="TextBlockStyle1" TargetType="TextBlock">
    <Setter Property="Foreground" Value="{Binding WindowColor, Source={StaticResource SystemColors}, Converter={StaticResource colorConverter}}"/>
  </Style>    
</UserControl.Resources>

<Grid Background="#FFB8B8B8">
    <TextBlock Text="WindowColor" Style="{StaticResource TextBlockStyle1}" />      
</Grid>

我得到的错误是:

发生System.Windows.Markup.XamlParseException异常 消息=设置属性“”引发了异常。[第11行位置:41] 行号=11 LinePosition=41 堆栈跟踪: 位于System.Windows.Application.LoadComponent(对象组件,Uri resourceLocator) 在SilverlightSysColors.MainPage.InitializeComponent()中 在SilverlightSysColors.MainPage..ctor()上 InnerException:System.NotSupportedException Message=无法设置只读属性“”。 堆栈跟踪: 位于MS.Internal.XamlMemberInfo.SetValue(对象目标,对象值) 在MS.Internal.XamlManagedRuntimeRPInvokes.SetValue(XamlTypeToken inType、XamlQualifiedObject和inObj、XamlPropertyToken inProperty、XamlQualifiedObject和inValue)
InnerException:

您不能在a
设置程序中包含绑定。绑定应用于
Setter
ValueProperty
依赖性属性,这实际上不是您的意图。发生的情况是,样式在Xaml解析期间应用(在绑定可以应用其值之前),这反过来导致样式被密封。当绑定试图调整
Setter
的值时,它失败了,因为一旦使用了样式,值就变成只读

编辑

这是一个基于我的猜测的解决方案,动态绑定并没有那么必要,您只需要一种方便的方法来访问
SystemColors
静态类的成员。我的方法是创建
ResourceDictionary
的派生,将一整套资源带到
SystemColors
类中,包括每个属性的颜色和画笔,并相应地命名。稍微思考一下是有帮助的:-

public class SystemColorsResources : ResourceDictionary
{
    public SystemColorsResources()
    {
        foreach (PropertyInfo pi in typeof(SystemColors).GetProperties())
        {
            Color c = (Color)pi.GetValue(null, null);
            Add(pi.Name, c);
            Add(pi.Name.Replace("Color", "Brush"), new SolidColorBrush(c));
        }
    }
}
在应用程序中使用该类时,请在应用程序的
合并词典
列表中包含该类的实例。Xaml:-

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <local:SystemColorsResources />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

现在,您可以将系统颜色属性名称及其“笔刷”变体用作直接的静态资源:-

<UserControl.Resources>
  <Style x:Key="TextBlockStyle1" TargetType="TextBlock">
    <Setter Property="Foreground" Value="{StaticResource WindowBrush}" />
  </Style>
</UserControl.Resources>

<Grid Background="#FFB8B8B8">
    <TextBlock Text="WindowColor" Style="{StaticResource TextBlockStyle1}" />
</Grid>


这是我能找到的最好的工作。非常感谢您分享他的技术。我非常感激。我有个问题。我看到你用画笔代替了颜色。我想知道我是否需要将颜色应用于边界背景,然后它将不起作用。有什么方法可以将其用于背景颜色吗?@vladc77:我不知道有任何控件属性采用
颜色
而不是
画笔
。您应该为
Background
属性使用“xxxxBrush”资源密钥名称,因为它需要
笔刷。注意:对于皮带和支架,
SystemColorResources
包含颜色和笔刷。您可能希望在基于系统颜色创建自己的画笔时使用这些颜色,但我怀疑您是否能找到其他用途。谢谢您回复我。我尝试使用此技术将背景色应用于边界控件,但颜色没有更改。我在setter中将foregroung替换为background属性。你知道为什么它不起作用吗。再次感谢。@vladc:没有看到你在做什么,很难说。让我担心的是,你仍然使用“颜色”这个词而不是“画笔”。知道你了解这种区别会有帮助。