这是非常模糊的,我可能只是遗漏了一些非常简单的东西。
情景1
让我说我在我的<Window.Resources>
部分创建了一个渐变画笔:
<LinearGradientBrush x:Key="GridRowSelectedBackBrushGradient" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#404040" Offset="0.0" />
<GradientStop Color="#404040" Offset="0.5" />
<GradientStop Color="#000000" Offset="0.6" />
<GradientStop Color="#000000" Offset="1.0" />
</LinearGradientBrush>
然后很久以后,我想覆盖DataGrid的HighlightBrushKey
。我基本上这样做了(可怕);
<LinearGradientBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
GradientStops="{Binding Source={StaticResource GridRowSelectedBackBrushGradient}, Path=GradientStops}"
StartPoint="{Binding Source={StaticResource GridRowSelectedBackBrushGradient}, Path=StartPoint}"
EndPoint="{Binding Source={StaticResource GridRowSelectedBackBrushGradient}, Path=EndPoint}" />
这显然不是引用资源最灵活的方式。我也想出了以下几乎完全相同的问题。
场景2
假设我在<Window.Resources>
标记中创建了两种颜色,如下所示:
<SolidColorBrush x:Key="DataGridRowBackgroundBrush" Color="#EAF2FB" />
<SolidColorBrush x:Key="DataGridRowBackgroundAltBrush" Color="#FFFFFF" />
然后,我希望在一个数组中提供它们,该数组在Binding上提供ConverterParameter,这样我就可以为我的静态资源实例提供自定义转换器:
<Setter Property="Background">
<Setter.Value>
<Binding RelativeSource="{RelativeSource Mode=Self}"
Converter="{StaticResource BackgroundBrushConverter}">
<Binding.ConverterParameter>
<x:Array Type="{x:Type Brush}">
<SolidColorBrush Color="{Binding Source={StaticResource DataGridRowBackgroundBrush}, Path=Color}" />
<SolidColorBrush Color="{Binding Source={StaticResource DataGridRowBackgroundAltBrush}, Path=Color}" />
</x:Array>
</Binding.ConverterParameter>
</Binding>
</Setter.Value>
</Setter>
我所做的是尝试重新引用现有资源,但在我的努力中,我实际上已经重新创建了资源,并绑定了属性以使它们匹配。再次,这并不理想。
因为我现在至少遇到过这个问题两次,还有更好的方法吗?
谢谢,汤姆
答案 0 :(得分:10)
我想知道有人会问这个问题。
您希望在场景1中做的是有效地为单个资源提供“别名”。这很容易通过标记来实现,只有在看到标记后才会显而易见。假设我们在App.xaml或其他地方有这个:
<ResourceDictionary>
<LinearGradientBrush x:Key="GridRowSelectedBackBrushGradient" ... />
</ResourceDictionary>
要在另一个ResourceDictionary中包含别名,只需:
<ResourceDictionary>
<StaticResourceExtension x:Key="{x:Static SystemColors.HighlightBrushKey}"
ResourceKey="GridRowSelectedBackBrushGradient" />
</ResourceDictionary>
这将在第一个ResourceDictionary中查找画笔对象,并将相同的对象添加到新键下的第二个ResourceDictionary中。这也适用于单个ResourceDictionary。
对于您的场景2,解决方案同样简单:
<Binding.ConverterParameter>
<x:Array Type="{x:Type Brush}">
<StaticResourceExtension ResourceKey="DataGridRowBackgroundBrush" />
<StaticResourceExtension ResourceKey="DataGridRowBackgroundAltBrush" />
</x:Array>
</Binding.ConverterParameter>
同样,通过Brush
找到的实际ResourceKey
对象会直接添加到Brush[]
数组中。没有创建新的Brush
。
我认为我们都习惯使用StaticResourceExtension
标记扩展语法(例如{StaticResource Xyz}
),很容易忘记它也可以与常规元素语法一起使用。
答案 1 :(得分:0)
你正在使用的标记不够远。您没有创建LinearGradientBrush
,这是您的第一个示例:您只需引用该资源。例如:
<DataGrid HighlightBrushKey="{StaticResource GridRowSelectedBackBrushGradient}" ....
在您的第二个示例中,我要说您要将数组声明为资源:
<x:Array Type="{x:Type Brush}" x:Key="MyArray">
<SolidColorBrush Color="#EAF2FB" />
<SolidColorBrush Color="#FFFFFF" />
</x:Array>
然后你可以使用
<Binding RelativeSource="{RelativeSource Mode=Self}"
Converter="{StaticResource BackgroundBrushConverter}"
ConverterParameter="{Staticresource MyArray}" />