2012-02-02 2 views
1

Каков наилучший способ включения динамического скинирования приложения WPF, когда некоторые элементы, требующие модификации скинов, не поддерживают значения типа DynamicResourceExtention? В частности, наша проблема заключается в том, что ConverterParameters требует StaticResourceExtentions.Как включить динамическое скинирование для ConverterParameters

Вот наша ситуация с 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 - это ссылка на ресурс нашего пользовательского конвертера. Нет проблем.

Теперь мы хотим динамически скрыть приложение, извлекая конвертер и поместив его в отдельный ресурс. Например, мы могли бы потребовать, чтобы высота элемента составляла 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-имен: System; сборка = mscorlib")

Это прекрасно работает, насколько экстрагирование. CustomParameter обеспокоен, но он все еще не позволило нам изменить наш ConverterParameter путем замены скинов на лету.

После изучения этого еще, в частности, следующие статьи

How to assign wpf resources to other resource tags

Skinning using a color as staticresource for another color

Aliasing resources

то, что мы думаем, что нам нужно сделать сейчас, это взять наш StaticResourceExtention и установите его значение динамически за кулисами, используя псевдонимы ресурсов.

Попытка сделать это, мы заменили предыдущий OurElementHeightParameter ресурс со следующими двумя ресурсами

, который работает отлично, производя одинаковый результат.

Когда это сработало, мы подумали, что было бы простым размещением ресурса 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.

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

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

Любые указатели очень ценят.

ответ

0

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

+0

Я думаю, что вы правы. Спасибо за ответ и извините за позднее признание (вопрос остался без ответа так долго, он ушел с радара!) – Nick