2010-06-14 5 views
9

Dies ist ziemlich obskur, ich vermisse nur etwas sehr einfach.Wie WPF-Ressourcen zu anderen Ressourcen-Tags zuweisen

Szenario 1

Lets sagen, dass ich einen Farbverlauf, wie dies in meinem <Window.Resources> Abschnitt erstellen:

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

Dann viel später, möchte ich die HighlightBrushKey für ein Datagrid zu überschreiben. Ich habe es im Grunde so gemacht (schrecklich);

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

Dies ist offensichtlich nicht die glatteste Art der Referenzierung einer Ressource. Ich kam auch auf das folgende Problem, das fast identisch ist.

Szenario 2

sagen, dass ich erstellt zwei Farben in meinem <Window.Resources> Markup, etwa so:

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

Dann später, ich möchte, dass sie in einem Array liefern, die den Converter ernährt sich von eine Bindung, damit ich den benutzerdefinierten Konverter mit meinen statischen Ressourceninstanzen versorgen kann:

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

Was ich habe Es ist der Versuch, eine vorhandene Ressource neu zu referenzieren, aber in meinen Bemühungen habe ich die Ressource tatsächlich neu erstellt und die Eigenschaften so gebunden, dass sie übereinstimmen. Auch dies ist nicht ideal.

Weil ich jetzt dieses Problem mindestens zweimal getroffen habe, gibt es einen besseren Weg?

Danke, Tom

Antwort

10

Ich habe mich gefragt, wann jemand danach fragen würde.

Was Sie in Szenario 1 tun möchten, ist effektiv eine einzige Ressource einen "Alias" zu geben. Dies kann leicht durch Markup erfolgen, das erst dann offensichtlich erscheint, wenn Sie es sehen. Angenommen, wir haben dies in unserer App.xaml oder irgendwo:

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

Um einen Alias ​​in einem anderen Resource zu umfassen, nur:

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

Das sieht das Pinselobjekt in der ersten Resource und fügt die gleichen Objekt zum zweiten ResourceDictionary unter einem neuen Schlüssel. Dies funktioniert auch in einem einzelnen ResourceDictionary.

Für Ihre Szenario 2 der Lösung ist ebenso einfach:

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

Auch hier sind die tatsächlichen Brush Objekte über die ResourceKey hinzugefügt werden direkt an die Brush[] Array gefunden. Es wird keine neue Brush erstellt.

Ich denke, wir sind alle so gewohnt, mit StaticResourceExtension mit Markup-Erweiterung Syntax (zB {StaticResource Xyz}), dass es leicht zu vergessen, dass es auch mit regulären Element Syntax sowie verwendet werden kann.

+0

Ja, Ray, das ist es total! Lass mich ein bisschen mit meinem Xaml herumlaufen und ich werde dich wissen lassen, wie es mir geht. Soweit es mich betrifft, ist dies die Antwort! Vielen Dank! – Tom

+0

Ok, da Window.Resources selbst ein ResourceDictionary ist, habe ich einfach meine verpfuschten Ressourcendubletten durch StaticResourceExtension ersetzt und es funktioniert einfach. Das ist Magie, vielen Dank. – Tom

+1

Während dies funktioniert, verursacht es falsche und vorübergehende Compilerfehler: Ein Objekt vom Typ "System.Windows.StaticResourceExtension" kann nicht auf eine Eigenschaft angewendet werden, die den Typ "System.Windows.Media.Color" erwartet. Diese kommen und gehen - manchmal bestehen sie sogar nach einem Build und verschwinden nach dem anderen. –

0

Das Markup der Sie arbeiten nicht weit genug nach oben. Sie erstellen kein LinearGradientBrush, Ihr erstes Beispiel: Sie verweisen nur auf die Ressource. Zum Beispiel:

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

In Ihrem zweiten Beispiel, würde ich sagen, dass Sie den Array als Ressource erklären wollen:

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

Und dann können Sie verwenden

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

Danke Dan! Es gibt jedoch keine Eigenschaft im DataGrid, die HighlightBrushKey genannt wird. Sie muss im DataGrid.Resources-Abschnitt zugewiesen werden und den x: Static-Systempinsel außer Kraft setzen. Ich überlegte, das Array selbst als Ressource zu definieren, aber dazu müssen die gleichen SolidColorBrush-Ressourcen zweimal definiert werden, anstatt auf meine bereits vorhandenen SolidColorBrushes, die ich zuvor erstellt hatte, Bezug zu nehmen. Was ich suche wahrscheinlich nicht existiert, wäre es fast eine Typ Struktur. Ich könnte nur darüber hinwegkommen und weitermachen! – Tom

Verwandte Themen