2010-03-19 6 views
25

J'essaie d'apprendre quelque chose sur WPF et je suis assez surpris par sa flexibilité.WPF Certains styles ne sont pas appliqués aux contrôles DataTemplate

Cependant, j'ai rencontré un problème avec Style s et DataTemplate s, ce qui est un peu déroutant. J'ai défini ci-dessous page de test pour jouer un peu avec des styles, etc et a constaté que les Style s définis dans <Page.Resources> pour Border et TextBlock ne sont pas appliqués dans le DataTemplate, mais Style pour ProgressBar défini exactement de la même manière est appliquée.

code source (je viens d'utiliser Kaxaml et XamlPadX pour voir le résultat)

<Page 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

    <Page.Resources> 

    <Style TargetType="{x:Type Border}"> 
     <Setter Property="Background" Value="SkyBlue"/> 
     <Setter Property="BorderBrush" Value="Black"/> 
     <Setter Property="BorderThickness" Value="2"/> 
     <Setter Property="CornerRadius" Value="5"/> 
    </Style> 

    <Style TargetType="{x:Type TextBlock}"> 
     <Setter Property="FontWeight" Value="Bold"/> 
    </Style> 

    <Style TargetType="{x:Type ProgressBar}"> 
     <Setter Property="Height" Value="10"/> 
     <Setter Property="Width" Value="100"/> 
     <Setter Property="Foreground" Value="Red"/> 
    </Style> 

    <XmlDataProvider x:Key="TestData" XPath="/TestData"> 
     <x:XData> 
     <TestData xmlns=""> 
      <TestElement> 
      <Name>Item 1</Name> 
      <Value>25</Value> 
      </TestElement> 
      <TestElement> 
      <Name>Item 2</Name> 
      <Value>50</Value> 
      </TestElement> 
     </TestData> 
     </x:XData> 
    </XmlDataProvider> 

    <HierarchicalDataTemplate DataType="TestElement"> 
     <Border Height="45" Width="120" Margin="5,5"> 
     <StackPanel Orientation="Vertical" Margin="5,5" VerticalAlignment="Center" HorizontalAlignment="Center"> 
      <TextBlock HorizontalAlignment="Center" Text="{Binding XPath=Name}"/> 
      <ProgressBar Value="{Binding XPath=Value}"/> 
     </StackPanel> 
     </Border> 
    </HierarchicalDataTemplate> 

    </Page.Resources> 

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> 
    <StackPanel Orientation="Vertical" VerticalAlignment="Center"> 
     <Border Height="45" Width="120" Margin="5,5"> 
     <StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center"> 
      <TextBlock HorizontalAlignment="Center" Text="Item 1"/> 
      <ProgressBar Value="25"/> 
     </StackPanel> 
     </Border> 
     <Border Height="45" Width="120" Margin="5,5"> 
     <StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center"> 
      <TextBlock HorizontalAlignment="Center" Text="Item 2"/> 
      <ProgressBar Value="50"/> 
     </StackPanel> 
     </Border> 
    </StackPanel> 
    <ListBox Margin="10,10" Width="140" ItemsSource="{Binding Source={StaticResource TestData}, XPath=TestElement}"/> 
    </StackPanel> 
</Page> 

Je soupçonne qu'il a quelque chose à voir avec les styles par défaut etc, mais plus déconcertant est la raison pour laquelle certains Style s sont appliqués et d'autres non . Je ne peux pas trouver une explication facile pour ci-dessus n'importe où et je voudrais donc demander si quelqu'un aurait la gentillesse d'expliquer ce comportement en termes de lamens avec des liens possibles vers la description technique, c'est-à-dire vers MSDN.

Merci d'avance pour votre soutien!

Répondre

27

Ceci est en fait une conception. Les éléments qui ne dérivent pas de Control ne capturent pas les styles implicites, sauf s'ils se trouvent dans les ressources de l'application.

Cette link explique cela plus en détail, ou vous pouvez voir le Connent bug report.

+0

Merci pour le lien! Il explique ce qui se passe, mais toujours un lien vers la documentation officielle serait bien juste que je sais où chercher de telles choses. – Martin

+0

Ajout d'un lien vers un rapport de bogue sur le site Connect de Microsoft, pas sûr qu'il existe des documents officiels décrivant ce comportement. – CodeNaked

+0

les deux liens sont morts maintenant. trouvé [lien de retour pour le premier] (https://web.archive.org/web/20170201072114/http://www.11011.net/archives/000692.html). Veuillez l'ajouter à votre réponse si vous le souhaitez. – itsho

3

J'ai aussi étudié cela, et personnellement, je pense que c'est un bug. J'ai remarqué que le style est défini si vous nommez vos styles comme ceci:

<Style x:Key="BorderStyle" TargetType="{x:Type Border}"> 
etc... 

et définir explicitement votre DataTemplate utiliser ces styles:

<HierarchicalDataTemplate DataTemplate="TestElement"> 
    <Border Height="45" Width="120" Margin="5,5", Style="{StaticResource BorderStyle}"> 

Je pense qu'il est possible que pour DataTemplates (et peut-être ControlTemplates), ils ont par défaut un style nul, sauf si vous les définissez explicitement.

Pour moi, ce n'est pas censé se produire - ce n'est pas une façon logique de WPF travailler ...

0

C'est parce que ListBox est un parent logique de vos articles datatemplate, rappelez-vous maintenant, toutes les propriétés sont ces « héritable "comme police, forecolor etc, sont dérivés du parent logique et ListBox le remplace déjà dans son propre style par défaut, c'est pourquoi cela ne fonctionnera pas. Cependant, dans ce cas, vous pouvez utiliser des styles nommés comme M. Dave l'a suggéré, mais je pense que si cela ne fonctionne pas alors c'est un problème connu en cas de List Box etc, vous pouvez répondre à ma question here, i had similar problem in listbox, et les réponses dans Ma question est plus détaillée.

23

J'ai découvert une solution de contournement simple pour cela. Pour tous les éléments qui ne peuvent pas rechercher en dehors de la limite d'encapsulation des gabarits de données, vous pouvez simplement déclarer un style vide dans le gabarit de données pour ce type d'élément et utiliser l'attribut BasedOn du style pour rechercher le style vide. corriger le style implicite en dehors du modèle de données à appliquer.

Dans l'exemple ci-dessous, la zone de texte peut effectuer une recherche en dehors de la limite d'encapsulation de modèle de données (car elle hérite de Control?), mais le TextBlock ne peut pas, donc je déclare le style vide pour cela peut rechercher en dehors du modèle de données.

<ItemsControl.ItemTemplate> 
    <DataTemplate> 
     <DataTemplate.Resources> 
      <Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}" /> 
     </DataTemplate.Resources> 
     <DockPanel> 
      <TextBlock Text="{Binding Name}" /> 
      <TextBox Text="{Binding Value}" /> 
     </DockPanel> 
    </DataTemplate> 
</ItemsControl.ItemTemplate> 
Questions connexes