Я хочу настроить систему тем, и одна из тем должна соответствовать системным цветам окна. Однако, поскольку у нас гораздо больше элементов, чем для системного цвета Windows, нам необходимо настроить затенение некоторых системных цветов. Поскольку цвета являются типами значений, трудно заменить их чем-то, что позволило бы нам использовать конвертер на месте.
Например, у нас это есть в одной из наших тем XAML:
<Color x:Key="ButtonFaceColor">#FFD3D3D3</Color>
Затем на него ссылаются через ключ ресурса в различных частях XAML, в основном с кистями, но также с несколькими другими элементами, которые принимают цвет. Например, у нас может быть bru sh:
<SolidColorBrush x:Key="ButtonFaceBrush" Color="{StaticResource ButtonFaceColor}"/>
Однако, не только кисти используют цвета; у нас есть другие элементы, которые могут принимать цвета напрямую. По этой причине мы хотим настраивать использование цветов, а не кистей.
Теперь нам нужна тема, соответствующая теме Windows '. Если мы просто хотим использовать системный цвет как есть, мы можем изменить его на:
<StaticResource x:Key="ButtonFaceColor" ResourceKey="{x:Static SystemColors.ControlColor}"/>
Однако мы на самом деле хотим использовать конвертер, чтобы мы могли настроить затенение. Таким образом, мы на самом деле хотим что-то более похожее на это:
<Binding x:Key="ButtonFaceColor" Source="{x:Static SystemColors.ControlColor}" Converter="{StaticResource RgbShadeConverter}" ConverterParameter="1"/>
Однако, тестируя даже с использованием только эталона цвета, как показано:
<Binding x:Key="ButtonFaceColor" Source="{x:Static SystemColors.ControlColor}"/>
Мы получаем ошибку, которая довольно непостижима. Судя по ошибкам, XAML пытается разрешить привязку, и, возможно, нам не понравится, что мы в основном заменяем Color
структуру на Binding
объект, который должен возвращать Color
структуру ,
System.Windows.Markup.XamlParseException: 'Set property 'System.Windows.ResourceDictionary.DeferrableContent' threw an exception.' Line number '3' and line position '21'. ---> System.Xaml.XamlObjectWriterException: 'Provide value on 'MS.Internal.Markup.StaticExtension' threw an exception.' Line number '105' and line position '22'. ---> System.IO.FileNotFoundException: Could not load file or assembly 'Infralution.Localization.Wpf, PublicKeyToken=547ccae517a004b5' or one of its dependencies. The system cannot find the file specified.
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.Assembly.Load(AssemblyName assemblyRef)
at System.Windows.Baml2006.Baml2006SchemaContext.ResolveAssembly(BamlAssembly bamlAssembly)
at System.Windows.Baml2006.Baml2006SchemaContext.GetAssembly(Int16 assemblyId)
at System.Windows.Baml2006.Baml2006SchemaContext.EnsureXmlnsAssembliesLoaded(String xamlNamespace)
at System.Windows.Baml2006.Baml2006SchemaContext.GetXamlType(String xamlNamespace, String name, XamlType[] typeArguments)
at MS.Internal.Xaml.XamlContext.GetXamlType(XamlTypeName typeName, Boolean returnUnknownTypesOnFailure, Boolean skipVisibilityCheck)
at MS.Internal.Xaml.XamlContext.ResolveXamlType(String qName, Boolean skipVisibilityCheck)
at MS.Internal.Xaml.Context.ObjectWriterContext.ServiceProvider_Resolve(String qName)
at MS.Internal.Markup.StaticExtension.ProvideValue(IServiceProvider serviceProvider)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CallProvideValue(MarkupExtension me, IServiceProvider serviceProvider)
--- End of inner exception stack trace ---
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CallProvideValue(MarkupExtension me, IServiceProvider serviceProvider)
at System.Xaml.XamlObjectWriter.Logic_ProvideValue(ObjectWriterContext ctx)
at System.Xaml.XamlObjectWriter.Logic_AssignProvidedValue(ObjectWriterContext ctx)
at System.Xaml.XamlObjectWriter.WriteEndObject()
at System.Xaml.XamlServices.Transform(XamlReader xamlReader, XamlWriter xamlWriter, Boolean closeWriter)
at System.Windows.ResourceDictionary.EvaluateMarkupExtensionNodeList(XamlReader reader, IServiceProvider serviceProvider)
at System.Windows.ResourceDictionary.GetKeyValue(KeyRecord key, IServiceProvider serviceProvider)
at System.Windows.ResourceDictionary.SetKeys(IList`1 keyCollection, IServiceProvider serviceProvider)
at System.Windows.Baml2006.WpfSharedBamlSchemaContext.<>c.<Create_BamlProperty_ResourceDictionary_DeferrableContent>b__297_0(Object target, Object value)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(Object inst, XamlMember property, Object value)
--- End of inner exception stack trace ---
at System.Windows.Markup.XamlReader.RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri)
at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
at System.Windows.Application.LoadBamlStreamWithSyncInfo(Stream stream, ParserContext pc)
Что такое магическое заклинание, чтобы заставить XAML принять ссылку с преобразователем на тип значения вместо элемента Color
?
ОБНОВЛЕНИЕ 1
Я также попробовал следующее:
<SolidColorBrush x:Key="ButtonFaceBrush" Color="{DynamicResource ButtonFaceColor}"/>
Это приводит к ошибке времени разработки:
An object of the type "System.Windows.Data.Binding" cannot be applied to a property that expects the type "System.Windows.Media.Color".
Что-то вроде того, почему Binding
не сработал бы, я думаю. Изменение в:
<SolidColorBrush x:Key="ButtonFaceBrush" Color="{Binding ButtonFaceColor}"/>
исключает ошибку времени разработки. Однако при фактическом запуске приложения возникает то же исключение, о котором сообщалось изначально.