Не удается добавить системный цвет в стили в Silverlight? - PullRequest
3 голосов
/ 28 апреля 2011

Я определил ресурс в XAML для SystemColors. Это прекрасно работает, если я установил свойство Foregroung непосредственно в TextBlock. Тем не менее, я получаю ошибку, показанную ниже, если я назначаю свойство переднего плана в стиле. Я не уверен, в чем проблема и как ее решить. Любые идеи высоко ценятся!

Код, когда я устанавливаю передний план прямо в текстовый блок. Работает отлично

<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 (объектный компонент, Uri resourceLocator) в SilverlightSysColors.MainPage.InitializeComponent () в SilverlightSysColors.MainPage..ctor () InnerException: System.NotSupportedException Сообщение = Невозможно установить свойство только для чтения ''. Трассировки стека: в MS.Internal.XamlMemberInfo.SetValue (цель объекта, значение объекта) в MS.Internal.XamlManagedRuntimeRPInvokes.SetValue (XamlTypeToken inType, XamlQualifiedObject & inObj, XamlPropertyToken inProperty, XamlQualifiedObject & inValue) InnerException:

1 Ответ

3 голосов
/ 28 апреля 2011

Вы не можете включить привязку в Setter.Привязка применяется к свойству ValueProperty зависимости Setter, которое на самом деле не является вашим намерением.Происходит то, что стиль применяется во время синтаксического анализа 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>

Теперь вы можете использовать имена свойств системного цвета с их вариантами «Кисть» в качестве простых статических ресурсов: -

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