2014-03-07 15 views
6

Ich habe seltsames Verhalten beim Referenzieren von StaticResources innerhalb einer DataTemplate in einem ResourceDictionary festgestellt.StaticResource-Referenz in DataTemplate

In diesem Beispiel fülle ich ein Listenfeld mit den Zahlen 1 bis 9 mit einem DataTemplate, das in einem ResourceDictionary definiert ist.

Hier ist der MainWindow.xaml Code:

<Window x:Class="testResources.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" 
    Width="525" 
    Height="350"> 
<Grid> 
    <ListBox Width="100" ItemTemplate="{StaticResource NumberTemplate}"> 
     <ListBox.ItemsSource> 
      <Int32Collection>1,2,3,4,5,6,7,8,9</Int32Collection> 
     </ListBox.ItemsSource> 
    </ListBox> 
</Grid> 

Die NumberTemplate in ResourceDictionary1.xaml definiert:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
<DataTemplate x:Key="NumberTemplate"> 
    <Grid Background="{StaticResource CoolNumbersColor}"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="35" /> 
     </Grid.ColumnDefinitions> 
     <TextBox Grid.Column="0" Background="{StaticResource CoolNumbersColor}" Text="{Binding Mode=OneWay}" /> 
    </Grid> 
</DataTemplate> 

Die Static CoolNumbersColor in App definiert ist. xaml zusammen mit ResourceDictionary1.xaml. Hier ist meine Datei App.xaml:

<Application x:Class="testResources.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"> 
<Application.Resources> 
    <ResourceDictionary> 
     <SolidColorBrush x:Key="CoolNumbersColor">GreenYellow</SolidColorBrush> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="pack://application:,,,/ResourceDictionary1.xaml" /> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

Als erstes habe ich das erwartete Verhalten in Visual Studio 2010 Designer sehen. Tatsächlich erscheint eine farbige Liste von Zahlen. Aber wenn dieses Beispiel auszuführen versucht, erhalte ich die Fehler

„Can not Ressource finden namens‚CoolNumbersColor‘. Ressourcennamen sind Groß- und Kleinschreibung“

Ich kann nicht verstehen, warum dies geschieht. Ist CoolNumbersColor Bewertung irgendwie aufgeschoben? Lexikalisch steht es vor dem fusionierten Ressourcenwörterbuch.

Die einzige Möglichkeit, dies zu erreichen (anders als mit DynamicResources), ist ein zweites ResourceDictionary zu erstellen (z. B. ResourceDictionary2.XAML), definieren CoolNumbersColor dort und verschmelzen sie alle in ResourceDictionary.MergedDictionaries wie folgt aus:

<Application x:Class="testResources.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"> 
<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="pack://application:,,,/ResourceDictionary2.xaml" /> 
      <ResourceDictionary Source="pack://application:,,,/ResourceDictionary1.xaml" /> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

+1

Wo verwenden Sie diese Ressource? Ich habe es in kleinen App versucht und funktioniert gut zu meinem Ende. –

+0

Haben Sie versucht, CoolNumbersColor vor ResourceDictionary.MergedDictionaries in Application.Resources zu definieren? –

+0

Ja, ich habe es benutzt und benutze es innerhalb 'DataTemplate' von' ListBox'. Immer noch keine Probleme. Kannst du es in einer kleinen App versuchen? Ich vermute, das Problem liegt woanders. –

Antwort

6

Ich denke, dies ist auf die Tatsache zurückzuführen ist, dass ein:

StaticResource

  • Vorwärtsreferenzen werden nicht unterstützt
  • Es wird nur einmal festgelegt, wenn das Programm gestartet wird: Ladezeit Nachschlag von Ressourcen

DynamicResource

  • vorwärts Unterstützt verweist
  • für jeden Zugriff Gilt für die Ressource: Run- Zeit Suche

Example of forward reference

Nicht mit StaticResource arbeiten:

<Window x:Class="SeveralResourceDictionariesHelp.MainWindow" 
     Background="{StaticResource testColor}" ... > 

<Window.Resources> 
    <SolidColorBrush x:Key="testColor">Red</SolidColorBrush> 
</Window.Resources> 

Businesses DynamicResource:

<Window x:Class="SeveralResourceDictionariesHelp.MainWindow" 
     Background="{DynamicResource testColor}" ... > 

<Window.Resources> 
    <SolidColorBrush x:Key="testColor">Red</SolidColorBrush> 
</Window.Resources> 

Zum Zeitpunkt der Anwendung gestartet wird, die CoolNumbersColor (Static) nicht innerhalb der " Visibility "von DataTemplate bzw. es wirft eine Ausnahme, er versucht zu finde es in seinem Umfang, kann es aber nicht finden.

Wenn Ressourcenwörterbücher verwendet werden, werden sie jeweils in die erste Warteschlange geladen, in diesem Fall wäre dies ein einzelner Sichtbereich, in dem die Ressource vorhanden ist.

DynamicResource wird nicht geladen, wenn die Anwendung gestartet wird, wird es während seiner ersten Anfrage an ihn geladen und in diesem Stadium DataTemplate "sieht" die Ressource. Die Frage bleibt Why this trick works in the Studio?. Vielleicht gibt es einen Unterschied zwischen dem Laden zur Laufzeit und im Entwurfsmodus, aber ich habe keine offizielle Bestätigung in der Dokumentation oder anderswo gefunden.

+0

@Theodore Zographos: Ja ist es, ich wollte es in meiner Antwort schreiben, aber beschränkte mich auf einen Absatz. –

+0

Nun, lexikalisch zumindest, sehe ich nicht die Vorwärtsreferenz, da 'CoolNumbersColor' vor den MergedDictionaries definiert ist. Wenn der Parser das DataTemplate auswertet, sollte er 'CoolNumbersColor' finden, da er in der Suchkette definiert ist: 1.same xaml 2.Generic.xaml 3. app.resources –

+2

@Theodore Zographos: In WPF sucht Elemente zuerst Ressource aus seinem Ressourcenabschnitt und dann Blasen bis zu dem Stamm des Elementbaums, schließlich erreichen das Systemthema, die folgende Sequenz veranschaulicht die Reihenfolge: 1. Elementhierarchie 2. Application.Resources 3. Type theme 4. Systemthema. –