Как включить динамический скиннинг для ConverterParameters
Каков наилучший способ включить динамическую обложку приложения WPF, если некоторые элементы, требующие изменения обложки, не поддерживают значения типа DynamicResourceExtention? В частности, наша проблема заключается в том, что ConverterParameters требует StaticResourceExtentions.
Вот наша ситуация с ConverterParameters Используя Visual Studio 2008 и WPF 3.5.
У нас есть специальный конвертер, который принимает значение и параметр и просто возвращает их продукт. Очень просто, отлично работает, и мы используем его для различных задач, включая настройку некоторых размеров элементов окна. Например, передав значение "Source={x:Static SystemParameters.PrimaryScreenHeight}" и параметр "0.1", мы можем установить высоту элемента точно на 1/10 высоты экрана.
Height="{Binding Source={x:Static SystemParameters.PrimaryScreenHeight},
Converter={StaticResource PctConverter},
ConverterParameter=0.1}"
где PctConverter - ссылка на ресурс для нашего пользовательского конвертера. Нет проблем там.
Теперь мы хотим динамически обработать приложение, извлекая ConverterParameter и помещая его в отдельный ресурс. Например, мы можем захотеть, чтобы высота элемента составляла 0,1 от высоты экрана в одних оболочках, а в других - 0,25 высоты экрана. Первоначально мы думали, что просто установим для ConverterParameter значение DynamicResource, но это не поддерживается, поэтому мы должны установить его, используя StaticResourceExtension, например:
Height="{Binding Source={x:Static SystemParameters.PrimaryScreenHeight},
Converter={StaticResource PctConverter},
ConverterParameter={StaticResource OurElementHeightParameter}}"
где OurElementHeightParameter определен в отдельном ResourceDictionary (назовите его MainResource.xaml) следующим образом:
<sys:Double x:Key="OurElementHeightParameter">0.1</sys:Double>
(где пространство имен определено как xmlns:sys="clr-namespace:System;assembly=mscorlib".)
Это работает отлично, что касается извлечения CustomParameter, но это все еще не позволило нам изменить наш ConverterParameter путем замены скинов на лету.
После исследования этого еще, в частности, следующие статьи
Как назначить ресурсы wpf другим тегам ресурсов
Скиннинг с использованием цвета в качестве статического ресурса для другого цвета
то, что мы думаем, что нам нужно сделать сейчас, это взять наше StaticResourceExtention и динамически установить его значение за кулисами, используя псевдонимы ресурсов.
Пытаясь сделать это, мы заменили предыдущий ресурс OurElementHeightParameter следующими двумя ресурсами
<sys:Double x:Key="SkinnedHeightRatio">0.1</sys:Double>
<StaticResourceExtension x:Key="OurElementHeightParameter" ResourceKey="SkinnedHeightRatio" />
который работает нормально, производя идентичный результат.
Когда это работало нормально, мы подумали, что будет просто поместить ресурс SkinnedHeightRatio в отдельный ResourceDictionary (назовите его Skin.xaml) и объединить его с оригинальным MainResource.xaml ResourceDictionary, и мы получим динамический скиннинг, который нам нужен.
Но, как только мы извлекаем <sys:Single x:Key="SkinnedHeightRatio">0.1</sys:Single>
к другому ResourceDictionary мы сталкиваемся с ошибкой сборки следующим образом:
Неизвестная ошибка сборки, 'Индекс был вне диапазона. Должно быть неотрицательным и меньшим, чем размер коллекции.
Еще более странным является то, что если мы оставим два указанных выше ресурса в одном и том же ResourceDictionary и просто разделим их, поместив между ними другой случайный ресурс, например
<sys:Double x:Key="SkinnedHeightRatio">0.1</sys:Double>
<Thickness x:Key="SomeRandomResource" >5</Thickness>
<StaticResourceExtension x:Key="OurElementHeightParameter" ResourceKey="SkinnedHeightRatio" />
затем OurElementHeightParameter указывает на SomeRandomResource непосредственно над ним, а не на ресурс, указанный в его свойстве ResourceKey (SkinnedHeightRatio), которое находится всего в 2 строках над ним... В этом случае параметром, передаваемым в преобразователь, является толщина SomeRandomResource.
Все это очень сбивает с толку и заставляет нас думать, что мы полностью лаем не то дерево. Так куда мы идем не так?
Если кому-то понадобится полный код приложения, воспроизводящего проблему, я могу опубликовать его.
Любые указатели очень ценятся.
1 ответ
Может быть проще создать многозначный преобразователь и привязать к нему два значения.