Как включить динамическое оформление для 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 строки выше него ... В этом случае параметром, переданным конвертеру, является Thickness SomeRandomResource.

Все это очень сбивает с толку и заставляет нас думать, что мы полностью лаем не на то дерево. Так в чем же мы ошибаемся?

Если кому-то понадобится полный код приложения, воспроизводящего проблему, я могу опубликовать его.

Любые указатели приветствуются.


person Nick    schedule 02.02.2012    source источник


Ответы (1)


Может быть проще создать многозначный преобразователь и привязать его к двум значениям.

person MikNik    schedule 12.07.2012
comment
Я думаю ты прав. Спасибо за ответ и извините за позднее подтверждение (вопрос так долго оставался без ответа, он исчез с радаров!) - person Nick; 20.10.2012