Как включить динамический скиннинг для ConverterParameters - PullRequest
1 голос
/ 02 февраля 2012

Каков наилучший способ включить динамическое создание обложки для приложения 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 Ответ

0 голосов
/ 12 июля 2012

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

...