2009-03-19 9 views
45

Me gustaría aplicar un estilo en un encabezado de expansión de WPF. En el siguiente XAML tengo un expansor pero el estilo es para todo, no solo para el encabezado.Cómo diseñar un encabezado de expansión de WPF?

Gracias.

<Page 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Width="640" 
> 
    <StackPanel> 
     <StackPanel.Resources> 
      <Style TargetType="Expander"> 
       <Style.Resources> 
        <LinearGradientBrush x:Key="BackBrush" StartPoint="0.5,0" EndPoint="0.5,1"> 
         <GradientStop Color="#EF3132" Offset="0.1" /> 
         <GradientStop Color="#D62B2B" Offset="0.9" /> 
        </LinearGradientBrush> 
       </Style.Resources> 
       <Setter Property="Background" Value="{StaticResource BackBrush}"/> 
      </Style> 
     </StackPanel.Resources> 
     <Expander> 
      <StackPanel> 
       <TextBlock>Bike</TextBlock> 
       <TextBlock>Car</TextBlock> 
       <TextBlock>Truck</TextBlock> 
      </StackPanel> 
     </Expander> 
    </StackPanel> 
</Page> 

Respuesta

50

he combinado algunas de XAML Josh Smith y MSDN y se le ocurrió una solución. De hecho, el control (al menos el encabezado) debe ser re-reflejado.

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

      <Style TargetType="Border" x:Key="RacePitBorderStyle" > 
       <Style.Resources> 
        <LinearGradientBrush x:Key="BackBrush" StartPoint="0.5,0" EndPoint="0.5,1"> 
         <GradientStop Color="#EF3132" Offset="0.1" /> 
         <GradientStop Color="#D62B2B" Offset="0.9" /> 
        </LinearGradientBrush> 
       </Style.Resources> 
       <Setter Property="Background" Value="{StaticResource BackBrush}"/> 
      </Style> 

      <DataTemplate x:Key="titleText"> 
       <Border Style="{StaticResource RacePitBorderStyle}" Height="24"> 
        <TextBlock Text="{Binding}" 
         Margin="4 0" 
         VerticalAlignment="Center" 
         Foreground="White" 
         FontSize="11" 
         FontWeight="Normal" 
         Width="{Binding 
         RelativeSource={RelativeSource 
         Mode=FindAncestor, 
         AncestorType={x:Type Expander}}, 
         Path=ActualWidth}" 
         TextWrapping="Wrap"/> 
       </Border> 
      </DataTemplate> 

      <Style TargetType="{x:Type Expander}"> 
       <Setter Property="HeaderTemplate" Value="{StaticResource titleText}"/> 
      </Style> 

     </StackPanel.Resources> 

     <Expander Name="hcontCtrl" Header="This is the header."> 
      <StackPanel> 
       <TextBox>This is a textbox</TextBox> 
       <Button>A button</Button> 
      </StackPanel> 
     </Expander> 

    </StackPanel> 
</Page> 
+2

encontré conseguir el expansor ancho de un problema real, y que el código hace esto. Funciona en xamlpad sin problemas. Sin embargo, en mi código no lo hace y causa un retraso gráfico terrible. Ancho = "{vincular RelativeSource {RelativeSource Mode = FindAncestor, AncestorType = {x: Type Expander}}, Path = ActualWidth}"> Al agregar lo anterior, funciona, pero se retrasa. si lo elimino o cambio Path = Width, no funciona y el retraso se va. – JonWillis

+0

+1 a JonWillis para XamlPad – surfen

+1

Justo lo que necesitaba. ¡Gracias! A veces profundizar en XAML es un dolor de cabeza. –

6

Depende de lo que quieras estilizar, puedes darle estilo a cualquier parte del mismo. Si desea cambiar el contenido en el encabezado, simplemente coloque toda su UI en la propiedad Expander.Header, y se mostrará en el área del encabezado.

si eso no satisface sus necesidades, es probable que necesite volver a crear la plantilla del control. Echar un vistazo a las plantillas de control enviados en WPF here

11

creo que la respuesta de Vasile está en el camino correcto, pero parece que lo hace mucho más que el cartel original sea necesario. Toda la pregunta original que pedía era cambiar el fondo del encabezado. Si bien el cambio presentado sí lo hace, también hace otras cosas.

Una de estas cosas es reemplazar la implementación predeterminada, creo que es un ContentPresenter, con un TextBlock. Entonces, ¿qué sucede cuando más tarde agregamos un segundo expansor a este stackpanel? Tal vez algo como:

<Expander> 
    <Expander.Header> 
     <StackPanel> 
      <Border height="5" width="5" Foreground="Blue"/> 
      <TextBlock>Ha!</TextBlock> 
     </StackPanel> 
    </Expander.Header> 
</Expander> 

no sé, pero no es buena. En cambio, creo que queremos mantener esto simple.

<DataTemplate x:Key="expanderHeader"> 
    <ContentPresenter 
     Content={Binding} 
     TextBlock.Background={StaticResource myBrush}/> 
</DataTemplate> 

<Style TargetType="Expander"> 
    <Setter Property="HeaderTemplate" Value="{StaticResource expanderHeader}"/> 
</Style> 

De esa manera, cuando alguien pone algo que no es solo texto en nuestro expansor labrado, no nos rompemos. Si desea asegurarse de que usted envuelve la totalidad de lo que hacen con este telón de fondo, lo que probablemente se desee, que se vería así:

<DataTemplate x:Key="expanderHeader"> 
    <Border Background={StaticResource myBrush}> 
     <ContentPresenter Content={Binding}/> 
    </Border> 
</DataTemplate> 
Cuestiones relacionadas