2011-04-28 19 views
3

我在XAML中为SystemColors定义了资源。如果我将Foregroung属性直接设置到TextBlock,它工作得很好。但是,如果我在样式中分配前景属性,则会出现下面显示的错误。我不确定是什么问题以及如何解决问题。任何想法都非常感谢!无法在Silverlight中的样式中添加系统颜色?

直接在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] LineNumber上= 11 LinePosition = 41 堆栈跟踪: 在System.Windows.Application.LoadComponent(对象部件,乌里resourceLocator) 在SilverlightSysColors.MainPage.InitializeComponent() 在SilverlightSysColors.MainPage。 .ctor() InnerException:System.NotSupportedException Message =无法设置只读属性''。 堆栈跟踪: 在MS.Internal.XamlMemberInfo.SetValue(对象目标,对象的值) 在MS.Internal.XamlManagedRuntimeRPInvokes.SetValue(XamlTypeToken法菜单,XamlQualifiedObject & inObj,XamlPropertyToken inProperty,XamlQualifiedObject & inValue) 的InnerException:

回答

3

您不能在a Setter中包含绑定。该绑定应用于SetterValueProperty依赖属性,这不是您的真正意图。在Xaml解析期间(在绑定可以应用它的值之前)应用样式会发生什么情况,这又会导致样式被封闭。当试图通过绑定来调整Setter的值时,它会失败,因为只有在使用样式后才会读取值。

编辑

一个解决根据我的猜测,动态绑定是不是真的那么必要你只是想访问SystemColors静态类成员的方便手段。我的做法是创建一个ResourceDictionary的衍生产品,以将一组完整的资源带到SystemColors类中,包括每个属性的Color和Brush,并相应地命名。反射的一点点帮助: -

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

有了这个类在你的应用程序在您MergedDictionaries列表中的App.xaml一个它的实例: -

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

现在你可以使用系统颜色属性名称以其“Brush”变体作为简单的静态资源: -

<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> 
+0

是否有任何解决方法? – vladc77 2011-04-28 21:57:34

+0

@ vladc77:看看我的编辑工作 – AnthonyWJones 2011-04-29 19:41:13

+0

这是我能找到的最好的工作。非常感谢你分享他的技术。我高度评价它。 – vladc77 2011-05-01 15:56:14