2010-03-19 13 views
25

Estoy tratando de aprender algo sobre WPF y estoy bastante sorprendido por su flexibilidad.WPF Algunos estilos no se aplican en los controles de DataTemplate

Sin embargo, he encontrado un problema con Style sy DataTemplate s, que es un poco confuso. he definido a continuación página de prueba para jugar un poco con los estilos etc y encontraron que los Style s definen en <Page.Resources> para Border y TextBlock no se aplican en el DataTemplate, pero se aplica Style para ProgressBar definido exactamente de la misma manera.

El código fuente (sólo tiene que utilizar Kaxaml y XamlPadX para ver el resultado)

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

Sospecho que tiene algo que ver con los estilos por defecto, etc, pero más desconcertante es por qué se aplican algunas Style s y otros no . No puedo encontrar una explicación fácil para arriba en ningún lado y, por lo tanto, me gustaría preguntar si alguien sería tan amable de explicar este comportamiento en términos lamenses con posibles enlaces a la descripción técnica, es decir, a MSDN más o menos.

Gracias de antemano por su apoyo!

Respuesta

27

Esto es realmente por diseño. Los elementos que no se derivan de Control no recogerán Estilos implícitos, a menos que estén en los recursos de la aplicación.

Esto link lo explica con más detalle, o puede ver el Connent bug report.

+0

¡Gracias por el enlace! Explica lo que está pasando, pero el enlace a la documentación oficial sería bueno solo que sé dónde buscar tales cosas. – Martin

+0

Se agregó un enlace al informe de errores en el sitio Connect de Microsoft, no estoy seguro de que exista algún documento oficial que describa este comportamiento. – CodeNaked

+0

ambos enlaces están muertos ahora. encontrado [enlace de retroceso para el primero] (https://web.archive.org/web/20170201072114/http://www.11011.net/archives/000692.html). Por favor agrégalo a tu respuesta si quieres. – itsho

3

He investigado esto también, y personalmente creo que es un error. Me he dado cuenta de que el estilo se define si el nombre de sus estilos de este modo:

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

y establecer explícitamente su DataTemplate usar esos estilos:

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

Creo que es posible que para DataTemplates (y tal vez ControlTemplates), tienen un estilo nulo predeterminado, a menos que los establezcas explícitamente.

Eso para mí no está destinado a pasar - no es una forma lógica de WPF trabajo ...

0

Esto se debe a ListBox es una matriz lógica de sus artículos DataTemplate, ahora recuerde, todas las propiedades son esos "heredable "como font, forecolor, etc., se derivan del elemento primario lógico y ListBox ya lo reemplaza en su propio estilo predeterminado, por eso no funcionará. Sin embargo, en este caso, puede usar estilos con nombre como ha sugerido el Sr. Dave, pero creo que si no funciona, entonces este es un problema conocido en el caso de List Box, etc., puede referirse a mi pregunta here, i had similar problem in listbox, y las respuestas en mi pregunta está en más detalle.

23

Descubrí una solución simple para esto. Para cualquier elemento que no sea capaz de buscar fuera del límite de encapsulación de la plantilla de datos (es decir, que no tenga un estilo implícito), puede declarar un estilo vacío dentro de la plantilla de datos para ese tipo de elemento y usar el atributo BasedOn del estilo para encontrar el corregir el estilo implícito fuera de la plantilla de datos para aplicar.

En el ejemplo siguiente, TextBox puede buscar fuera del límite de encapsulación de la plantilla de datos (porque hereda de Control?), pero TextBlock no puede, entonces declaro el estilo vacío para el cual puede buscar fuera de la plantilla de datos.

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