当某些需要修改皮肤的项目不支持DynamicResourceExtention类型的值时,为WPF应用程序启用动态蒙皮的最佳方法是什么?特别是,我们的问题是ConverterParameters需要StaticResourceExtentions。
以下是使用Visual Studio 2008和WPF 3.5的ConverterParameters的情况。
我们有一个自定义转换器,它接受一个值和一个参数,然后简单地返回它们的产品。 非常简单,工作正常,我们将它用于各种任务,包括设置一些窗口元素大小。例如,传递值“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。
在对此进行了一些研究后,特别是以下文章
How to assign wpf resources to other resource tags
Skinning using a color as staticresource for another color
我们认为我们现在需要做的是使用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。
所有这些都令人困惑,让我们觉得我们正在彻底咆哮错误的树。那么我们哪里出错了?
如果有人需要完整代码来复制问题的应用程序,我可以将其发布。
任何指针都非常感激。
答案 0 :(得分:0)
创建一个多值转换器并将其绑定到两个值可能更简单。