2010-06-14 101 views
9

这很晦涩难懂,我可能会错过一些非常简单的东西。如何将WPF资源分配给其他资源标签

方案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> 

然后很久以后,我想覆盖HighlightBrushKey为DataGrid。我基本上是这样做的(可怕的);

<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" /> 

再后来,我想在一个阵列,可以在喂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> 

我已经e试图重新引用现有的资源,但是在我的努力中,我实际上已经重新创建了资源,并且限制了它们匹配的属性。再次,这并不理想。

因为我现在至少打了两次这个问题,有没有更好的方法?

谢谢,汤姆

回答

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> 

同样,经由ResourceKey找到的实际Brush对象被直接加入到Brush[]阵列。没有新的Brush被创建。

我认为我们都习惯于使用带标记扩展语法的StaticResourceExtension(例如{StaticResource Xyz}),很容易忘记它也可以用于常规元素语法。

+0

是的,雷完全是它!让我淡化我的xaml一下,然后我会让你知道我的表现。就我而言,这是答案!谢谢! – Tom 2010-06-16 11:59:59

+0

好的,因为Window.Resources本身就是一个ResourceDictionary,所以我简单地用StaticResourceExtension替换了我的僵化的资源重复,并且它正常工作。这很神奇,非常感谢。 – Tom 2010-06-16 12:06:02

+1

虽然这确实起作用,但会引发虚假和暂时的编译器错误:“System.Windows.StaticResourceExtension”类型的对象不能应用于需要类型“System.Windows.Media.Color”的属性。这些来来去去 - 有时甚至在一次构建之后仍然存在,并且一次又一次地消失。 – 2012-09-11 18:30:09

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}" /> 
+0

谢谢丹!但是,DataGrid上没有名为HighlightBrushKey的属性,它必须在DataGrid.Resources节中分配,以覆盖x:Static系统刷。 我认为将数组定义为资源本身,但这需要定义两次相同的SolidColorBrush资源,而不是引用先前创建的现有SolidColorBrushes。 我在找的东西可能不存在,它几乎是一个类型的结构。 我可能只需要克服这个并继续前进! – Tom 2010-06-14 11:29:22