Wpf 如何为转换器参数启用动态蒙皮

Wpf 如何为转换器参数启用动态蒙皮,wpf,resources,skinning,staticresource,dynamicresource,Wpf,Resources,Skinning,Staticresource,Dynamicresource,当某些需要修改外观的项目不支持DynamicResourceExtension类型的值时,启用WPF应用程序动态蒙皮的最佳方法是什么?特别是,我们的问题是ConverterParameters需要StaticResourceExtension 下面是使用Visual Studio 2008和WPF 3.5的转换器参数的情况 我们有一个自定义转换器,它接受一个值和一个参数,并简单地返回它们的产品。 非常简单,效果很好,我们将其用于各种任务,包括设置一些窗口元素大小。例如,通过传递一个值“Sourc

当某些需要修改外观的项目不支持DynamicResourceExtension类型的值时,启用WPF应用程序动态蒙皮的最佳方法是什么?特别是,我们的问题是ConverterParameters需要StaticResourceExtension

下面是使用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设置为DynamicSource,但这不受支持,因此我们必须使用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>
0.1
(其中命名空间定义为xmlns:sys=“clr namespace:System;assembly=mscorlib”。)

就提取CustomParameter而言,这很好,但它仍然不能让我们通过动态交换皮肤来更改ConverterParameter

在对此进行了更多的研究之后,特别是下面的文章

我们认为现在需要做的是使用StaticResourceExtension并在幕后使用资源别名动态设置其值

为此,我们用以下两个资源替换了以前的OurElementHeightParameter资源

<sys:Double x:Key="SkinnedHeightRatio">0.1</sys:Double>
<StaticResourceExtension x:Key="OurElementHeightParameter" ResourceKey="SkinnedHeightRatio" />
0.1
这很好,产生了相同的结果

当这一切正常工作时,我们认为将SkindHeightrato资源放在一个单独的ResourceDictionary(称为Skin.xaml)中并将其与原始MainResource.xaml ResourceDictionary合并是一个简单的问题,我们将拥有我们所追求的动态蒙皮

但是,一旦我们将
0.1
提取到另一个ResourceDictionary,我们就会遇到如下生成错误:

<sys:Double x:Key="OurElementHeightParameter">0.1</sys:Double>
未知生成错误,'索引超出范围。必须为非负数且小于集合的大小。”

更奇怪的是,如果我们将上面的两个资源放在同一个ResourceDictionary中,然后通过在它们之间放置另一个随机资源来分隔它们,例如

<sys:Double x:Key="SkinnedHeightRatio">0.1</sys:Double>
<Thickness x:Key="SomeRandomResource" >5</Thickness>
<StaticResourceExtension x:Key="OurElementHeightParameter" ResourceKey="SkinnedHeightRatio" />
0.1
5.
然后,ourElementHeights参数指向它正上方的SomeRandomResource,而不是 在其ResourceKey属性(SkinndHeightratio)中指定的资源,该属性仅在其上方2行。。。 在这种情况下,传递给转换器的参数是资源

这一切都很令人困惑,让我们觉得我们完全找错了方向。那么我们错在哪里呢

如果有人需要一个应用程序的完整代码来重现这个问题,我可以发布它


非常感谢任何指针。

创建多值转换器并为其绑定两个值可能会更简单。

我认为你是对的。感谢您的回复,并对迟来的确认表示歉意(这个问题太长时间没有得到回答,它已经离开了雷达!)