2010-06-14 11 views
9

Questo è piuttosto oscuro, potrei semplicemente mancare qualcosa di estremamente semplice.Come assegnare risorse WPF ad altri tag risorsa

Scenario 1

Diciamo creo un pennello sfumato, come questo nella mia sezione <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> 

Poi molto più tardi, voglio ignorare il HighlightBrushKey per un DataGrid. In pratica l'ho fatto in questo modo (orribile);

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

Questo ovviamente non è il modo più semplice di fare riferimento a una risorsa. Ho anche trovato il seguente problema, che è quasi identico.

Scenario 2

dire che ho creato due colori nella mia <Window.Resources> markup, in questo modo:

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

Poi più tardi, voglio fornire loro in un array, che alimenta il ConverterParameter su un binding quindi posso fornire il convertitore personalizzato con le mie istanze di risorse statiche:

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

Quello che ho don È un tentativo di rereferenziare una risorsa esistente, ma nei miei sforzi ho effettivamente ricreato la risorsa e legato le proprietà in modo che corrispondano. Di nuovo, questo non è l'ideale.

Perché ora ho riscontrato questo problema almeno due volte, c'è un modo migliore?

Grazie, Tom

risposta

10

Mi stavo chiedendo quando qualcuno avrebbe chiesto questo.

Quello che si vuole fare nello Scenario 1 è di dare effettivamente una singola risorsa e un "alias". Questo è fatto facilmente dal markup che sembra ovvio solo dopo averlo visto. Supponiamo di avere questo nella nostra App.xaml o da qualche parte:

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

Per inserire un alias in un altro ResourceDictionary, basta:

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

Questo sembra l'oggetto pennello in primo ResourceDictionary e aggiunge la stessa oggetto al secondo ResourceDictionary sotto una nuova chiave. Questo funziona anche all'interno di un singolo ResourceDictionary.

per lo scenario 2 la soluzione è altrettanto semplice:

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

Nuovamente, l'attuale Brush oggetti trovati tramite il ResourceKey vengono aggiunti direttamente alla matrice Brush[]. Non è stato creato alcun nuovo Brush.

Penso che siamo tutti così abituati a utilizzare StaticResourceExtension con la sintassi di estensione markup (ad esempio {StaticResource Xyz}) che è facile dimenticare che può essere utilizzato anche con la sintassi di elementi regolari pure.

+0

Sì, Ray è totalmente! Lasciami parlare del mio xaml per un po 'e ti farò sapere come andrò avanti. Per quanto mi riguarda, questa è la risposta! Grazie! – Tom

+0

Ok, dato che Window.Resources è esso stesso un ResourceDictionary, ho semplicemente sostituito i miei duplicati di risorse pasticciati con StaticResourceExtension e funziona. Questa è magia, grazie mille. – Tom

+1

Sebbene funzioni, genera errori di compilazione spuri e transitori: un oggetto del tipo "System.Windows.StaticResourceExtension" non può essere applicato a una proprietà che prevede il tipo "System.Windows.Media.Color". Questi vanno e vengono - a volte persistono anche dopo una costruzione e scompaiono dopo l'altro. –

0

Il markup si sta lavorando con non va abbastanza lontano. Non si crea un LinearGradientBrush, il primo esempio: si fa semplicemente riferimento alla risorsa. Per esempio:

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

Nel vostro secondo esempio, direi che si desidera dichiarare la matrice come una risorsa:

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

E quindi è possibile utilizzare

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

Grazie Dan! Tuttavia, non esiste alcuna proprietà su DataGrid chiamata HighlightBrushKey, deve essere allocata nella sezione DataGrid.Resources che sostituisce il pennello di sistema x: Static. Ho considerato la definizione della matrice come una risorsa stessa, ma ciò richiede la definizione delle stesse risorse di SolidColorBrush due volte, anziché fare riferimento ai miei SolidColorBrushes esistenti creati in precedenza. Quello che sto cercando probabilmente non esiste, sarebbe quasi una struttura di tipo . Potrei semplicemente dover superare questo e andare avanti! – Tom

Problemi correlati