2010-06-14 12 views
9

Esto es bastante oscuro, me puede estar perdiendo algo extremadamente simple.Cómo asignar recursos de WPF a otras etiquetas de recursos

Escenario 1

digamos que creo un pincel de degradado, como esto en mi sección <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> 

A continuación, mucho más tarde, quiero anular el HighlightBrushKey de una cuadrícula de datos. Básicamente lo he hecho así (horrible);

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

Evidentemente, esta no es la mejor manera de hacer referencia a un recurso. También se me ocurrió el siguiente problema, que es casi idéntico.

Escenario 2

Di creé dos colores en mi <Window.Resources> marcado, así:

<SolidColorBrush x:Key="DataGridRowBackgroundBrush" Color="#EAF2FB" /> 
<SolidColorBrush x:Key="DataGridRowBackgroundAltBrush" Color="#FFFFFF" /> 

Luego, más tarde, quiero suministrarlos en una matriz, que alimenta el ConverterParameter en una unión para que pueda suministrar el convertidor de medida con mis instancias de recursos estáticos:

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

lo que he Don Es un intento de re-referenciar un recurso existente, pero en mi esfuerzo, he recreado el recurso y atado las propiedades para que coincidan. Nuevamente, esto no es ideal.

Porque ahora he llegado a este problema al menos dos veces, ¿hay una manera mejor?

Gracias, Tom

Respuesta

10

Me preguntaba cuando alguien iba a preguntar sobre esto.

Lo que quiere hacer en el Escenario 1 es darle un "alias" efectivamente a un único recurso. Esto se hace fácilmente mediante un marcado que parece obvio solo después de verlo. Supongamos que tenemos esto en nuestra App.xaml o en alguna parte:

<ResourceDictionary> 
    <LinearGradientBrush x:Key="GridRowSelectedBackBrushGradient" ... /> 
</ResourceDictionary> 

Para incluir un alias en otro ResourceDictionary, simplemente:

<ResourceDictionary> 
    <StaticResourceExtension x:Key="{x:Static SystemColors.HighlightBrushKey}" 
          ResourceKey="GridRowSelectedBackBrushGradient" /> 
</ResourceDictionary> 

Este busca el objeto de pincel en el primer ResourceDictionary y añade la misma objetar al segundo ResourceDictionary bajo una nueva clave. Esto también funciona dentro de un solo ResourceDictionary.

para su escenario 2 la solución es tan simple:

<Binding.ConverterParameter> 
    <x:Array Type="{x:Type Brush}"> 
    <StaticResourceExtension ResourceKey="DataGridRowBackgroundBrush" /> 
    <StaticResourceExtension ResourceKey="DataGridRowBackgroundAltBrush" /> 
    </x:Array> 
</Binding.ConverterParameter> 

Una vez más, los reales Brush objetos encontrados a través de la ResourceKey se añaden directamente a la matriz Brush[]. No se crea un nuevo Brush.

Creo que estamos tan acostumbrados a usar StaticResourceExtension con la sintaxis de extensión de marcado (por ejemplo {StaticResource Xyz}) que es fácil olvidar que también se puede utilizar con la sintaxis de elementos regular también.

+0

Sí, ¡Ray eso es totalmente! Déjame hablar un poco con mi xaml y te contaré cómo me llevo. En lo que a mí respecta, ¡esta es la respuesta! ¡Gracias! – Tom

+0

Ok, como Window.Resources es en sí mismo un ResourceDictionary, simplemente he reemplazado mis duplicados de recursos fallidos con StaticResourceExtension y simplemente funciona. Esto es magia, muchas gracias. – Tom

+1

Mientras esto funciona, provoca errores de compilador espurios y transitorios: un objeto del tipo "System.Windows.StaticResourceExtension" no se puede aplicar a una propiedad que espera el tipo "System.Windows.Media.Color". Estos van y vienen, a veces incluso persisten después de una construcción y desaparecen tras otra. –

0

El marcado se trabaja con no sube lo suficiente. No cree un LinearGradientBrush, su primer ejemplo: simplemente hace referencia al recurso. Por ejemplo:

<DataGrid HighlightBrushKey="{StaticResource GridRowSelectedBackBrushGradient}" .... 

En el segundo ejemplo, diría que desea declarar la matriz como recurso:

<x:Array Type="{x:Type Brush}" x:Key="MyArray"> 
    <SolidColorBrush Color="#EAF2FB" /> 
    <SolidColorBrush Color="#FFFFFF" /> 
</x:Array> 

y luego se puede utilizar

<Binding RelativeSource="{RelativeSource Mode=Self}" 
     Converter="{StaticResource BackgroundBrushConverter}" 
     ConverterParameter="{Staticresource MyArray}" /> 
+0

Gracias Dan! Sin embargo, no hay ninguna propiedad en el DataGrid llamada HighlightBrushKey, debe asignarse en la sección DataGrid.Resources que sobrescribe el pincel del sistema x: Static. Consideré definir la matriz como un recurso en sí, pero eso requiere definir los mismos recursos de SolidColorBrush dos veces, en lugar de hacer referencia a mis SolidColorBrushes existentes que creé anteriormente. Lo que estoy buscando probablemente no exista, casi sería una estructura de tipo . ¡Quizás tenga que superar esto y seguir adelante! – Tom

Cuestiones relacionadas