2009-03-25 11 views

Respuesta

40

Todo lo que necesita hacer es esto:

<Expander> 
    <Expander.Header> 
    <TextBlock 
     Text="I am header text..." 
     Background="Blue" 
     Width="{Binding 
     RelativeSource={RelativeSource 
      Mode=FindAncestor, 
      AncestorType={x:Type Expander}}, 
     Path=ActualWidth}" 
     /> 
    </Expander.Header> 
    <TextBlock Background="Red"> 
    I am some content... 
    </TextBlock> 
</Expander> 

http://joshsmithonwpf.wordpress.com/2007/02/24/stretching-content-in-an-expander-header/

+1

¿Cómo hago esto en el código? Me di cuenta de que tengo que dar cuenta de algo de espacio para un botón – Ngm

+0

Lo siento, no sé cómo hacerlo en el código. –

+3

TextBlock bx = new TextBlock(); bx.Text = "Tengo el texto del encabezado ..."; Encuadernación wdBind = new Binding ("ActualWidth"); wdBind.RelativeSource = new RelativeSource (RelativeSourceMode.FindAncestor, typeof (Expander), 1); bx.SetBinding (TextBlock.TextProperty, wdBind); –

10

no estirables Expander s es por lo general el problema de los controles de los padres no pueden ser estirados .. Tal vez uno de los controles de los padres ha definido una o HorizontalAlignmentVerticalAlignment propiedad?

Si puede publicar un código de muestra, podemos darle una mejor respuesta.

+0

Puedo confirmar que cambiar esta propiedad en el control principal solucionará el problema. Mucho más fácil que cualquier otra opción – Matt

1

Estoy de acuerdo con HTH - compruebe en qué tipo de contenedor está colocando el expansor ... el StackPanel siempre doblará sus hijos hasta el tamaño más pequeño al que puedan ir.

estoy usando expansores mucho en mi proyecto, y si las dejas caer en una cuadrícula/DockPanel, a continuación, el expansor va a llenar todo el espacio disponible (asumiendo que es vertical & orientaciones horizontales se establecen para estirar).

La sugerencia de Jonathan de vincular el ancho del expansor al ancho del contenedor puede ser un poco complicado ... Intenté esta técnica hace unas semanas y descubrí que puede producir resultados no deseables en algunos casos, porque puede inhibir el funcionamiento de el sistema de disposición.

PD: Como consejo general (y estoy seguro de que me van a entusiasmar por escribir esto), si no está seguro de qué tipo de contenedor de diseño tiene para sus controles, empiece con una Grilla . Usar la columna & Las definiciones de fila le permiten controlar fácilmente si los controles secundarios usan un espacio mínimo ("Auto"), un espacio máximo ("*") o una cantidad exacta de espacio ("[número]").

+0

Grid es definitivamente el contenedor más versátil y fácil de usar. He oído que también funciona mucho peor que la mayoría de los contenedores. –

+3

@Mark, quiere decir que está de acuerdo con Arcturus. HTH significa esperanza que ayuda y es un cierre común por aquí. –

0

Silverlight Toolkit incluye un control Accordion que actúa como un expansor que siempre se extiende hasta el espacio disponible. Aún no lo he probado, pero también podría ser funcional para WPF, al igual que los controles del gráfico de Silverlight.

6

Esta solución es mucho más sencilla y no afecta a otros controles de expansión que pueda utilizar en su aplicación.

<Expander ExpandDirection="Right" Grid.Column="0" Name="topOfB"> 
    <Expander.Header> 
     <Grid HorizontalAlignment="Stretch" Width="{Binding Path=ActualWidth, ElementName=topOfB}"> 
      <!-- control content goes here --> 

1
<Expander Name="EXPANDER_NAME"> 
    <Expander IsExpanded="True" Margin="0"> 
     <Expander.Header> 
      <Grid Background="Red" Width="{Binding ElementName=EXPANDER_NAME, Path=ActualWidth}"> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition/> 
        <ColumnDefinition Width="30"/> 
       </Grid.ColumnDefinitions> 
       <TextBlock>   HEADER TEXT   <TextBlock> 
      </Grid> 
     </Expander.Header> 
    </Expander> 
4

La respuesta aceptada dibuja fuera del control debido a que el contenido de la cabecera se encuentra en una columna y el botón de expansión está en el primer lugar. Podría ser lo suficientemente bueno para algunos casos.

Si desea una solución limpia, debe cambiar la plantilla del expansor.

Otra forma es una propiedad asociada:

using System.Collections.Generic; 
using System.Linq; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Media; 
public static class ParentContentPresenter 
{ 
    public static readonly System.Windows.DependencyProperty HorizontalAlignmentProperty = System.Windows.DependencyProperty.RegisterAttached(
     "HorizontalAlignment", 
     typeof(HorizontalAlignment), 
     typeof(ParentContentPresenter), 
     new PropertyMetadata(default(HorizontalAlignment), OnHorizontalAlignmentChanged)); 

    public static void SetHorizontalAlignment(this UIElement element, HorizontalAlignment value) 
    { 
     element.SetValue(HorizontalAlignmentProperty, value); 
    } 

    [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)] 
    [AttachedPropertyBrowsableForType(typeof(UIElement))] 
    public static HorizontalAlignment GetHorizontalAlignment(this UIElement element) 
    { 
     return (HorizontalAlignment)element.GetValue(HorizontalAlignmentProperty); 
    } 

    private static void OnHorizontalAlignmentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var presenter = d.Parents().OfType<ContentPresenter>().FirstOrDefault(); 
     if (presenter != null) 
     { 
      presenter.HorizontalAlignment = (HorizontalAlignment) e.NewValue; 
     } 
    } 

    private static IEnumerable<DependencyObject> Parents(this DependencyObject child) 
    { 
     var parent = VisualTreeHelper.GetParent(child); 
     while (parent != null) 
     { 
      yield return parent; 
      child = parent; 
      parent = VisualTreeHelper.GetParent(child); 
     } 
    } 
} 

Te permite hacer:

<Expander Header="{Binding ...}"> 
    <Expander.HeaderTemplate> 
     <DataTemplate> 
      <!--Using a border here to show how width changes--> 
      <Border BorderBrush="Red" BorderThickness="1" 
        local:ParentContentPresenter.HorizontalAlignment="Stretch"> 
       ...  
      </Border> 
     </DataTemplate> 
    </Expander.HeaderTemplate> 
</Expander> 

Tenga en cuenta que el uso de la propiedad adjunta es algo frágil, ya que asume que hay una ContentPresenter en la plantilla.

3

Estoy bastante sorprendido nadie ha mencionado que acaba de editar la plantilla de control, todas las otras soluciones tienen algunos inconvenientes muy serios tiempo su anchura no calcular correctamente, no volver a dibujar, tiempo de renderizado, etc ...

Esta plantilla de control modificará la alineación horizontal del presentador de contenido del encabezado para que coincida con los expansores reales (lo que significa que se ampliará)

<ControlTemplate x:Key="ExpanderControlTemplate1" TargetType="{x:Type Expander}"> 
     <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="3" SnapsToDevicePixels="True"> 
      <DockPanel> 
       <ToggleButton x:Name="HeaderSite" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" DockPanel.Dock="Top" Foreground="{TemplateBinding Foreground}" FontWeight="{TemplateBinding FontWeight}" FontStyle="{TemplateBinding FontStyle}" FontStretch="{TemplateBinding FontStretch}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" MinWidth="0" MinHeight="0" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"> 
        <ToggleButton.FocusVisualStyle> 
         <Style> 
          <Setter Property="Control.Template"> 
           <Setter.Value> 
            <ControlTemplate> 
             <Border> 
              <Rectangle Margin="0" SnapsToDevicePixels="True" Stroke="Black" StrokeThickness="1" StrokeDashArray="1 2"/> 
             </Border> 
            </ControlTemplate> 
           </Setter.Value> 
          </Setter> 
         </Style> 
        </ToggleButton.FocusVisualStyle> 
        <ToggleButton.Style> 
         <Style TargetType="{x:Type ToggleButton}"> 
          <Setter Property="Template"> 
           <Setter.Value> 
            <ControlTemplate TargetType="{x:Type ToggleButton}"> 
             <Border Padding="{TemplateBinding Padding}"> 
              <Grid Background="Transparent" SnapsToDevicePixels="False"> 
               <Grid.ColumnDefinitions> 
                <ColumnDefinition Width="19"/> 
                <ColumnDefinition Width="*"/> 
               </Grid.ColumnDefinitions> 
               <Ellipse x:Name="circle" Fill="White" HorizontalAlignment="Center" Height="19" Stroke="#FF333333" VerticalAlignment="Center" Width="19"/> 
               <Path x:Name="arrow" Data="M1,1.5L4.5,5 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="False" Stroke="#FF333333" StrokeThickness="2" VerticalAlignment="Center"/> 
               <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="1" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="4,0,0,0" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Center"/> 
              </Grid> 
             </Border> 
             <ControlTemplate.Triggers> 
              <Trigger Property="IsChecked" Value="True"> 
               <Setter Property="Data" TargetName="arrow" Value="M1,4.5L4.5,1 8,4.5"/> 
              </Trigger> 
              <Trigger Property="IsMouseOver" Value="True"> 
               <Setter Property="Stroke" TargetName="circle" Value="#FF5593FF"/> 
               <Setter Property="Fill" TargetName="circle" Value="#FFF3F9FF"/> 
               <Setter Property="Stroke" TargetName="arrow" Value="Black"/> 
              </Trigger> 
              <Trigger Property="IsPressed" Value="True"> 
               <Setter Property="Stroke" TargetName="circle" Value="#FF3C77DD"/> 
               <Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/> 
               <Setter Property="Fill" TargetName="circle" Value="#FFD9ECFF"/> 
               <Setter Property="Stroke" TargetName="arrow" Value="Black"/> 
              </Trigger> 
              <Trigger Property="IsEnabled" Value="False"> 
               <Setter Property="Stroke" TargetName="circle" Value="#FFBCBCBC"/> 
               <Setter Property="Fill" TargetName="circle" Value="#FFE6E6E6"/> 
               <Setter Property="Stroke" TargetName="arrow" Value="#FF707070"/> 
              </Trigger> 
             </ControlTemplate.Triggers> 
            </ControlTemplate> 
           </Setter.Value> 
          </Setter> 
         </Style> 
        </ToggleButton.Style> 
       </ToggleButton> 
       <ContentPresenter x:Name="ExpandSite" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" DockPanel.Dock="Bottom" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Visibility="Collapsed" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
      </DockPanel> 
     </Border> 
     <ControlTemplate.Triggers> 
      <Trigger Property="IsExpanded" Value="True"> 
       <Setter Property="Visibility" TargetName="ExpandSite" Value="Visible"/> 
      </Trigger> 
      <Trigger Property="ExpandDirection" Value="Right"> 
       <Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Right"/> 
       <Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Left"/> 
       <Setter Property="Style" TargetName="HeaderSite"> 
        <Setter.Value> 
         <Style TargetType="{x:Type ToggleButton}"> 
          <Setter Property="Template"> 
           <Setter.Value> 
            <ControlTemplate TargetType="{x:Type ToggleButton}"> 
             <Border Padding="{TemplateBinding Padding}"> 
              <Grid Background="Transparent" SnapsToDevicePixels="False"> 
               <Grid.RowDefinitions> 
                <RowDefinition Height="19"/> 
                <RowDefinition Height="*"/> 
               </Grid.RowDefinitions> 
               <Grid> 
                <Grid.LayoutTransform> 
                 <TransformGroup> 
                  <RotateTransform Angle="-90"/> 
                 </TransformGroup> 
                </Grid.LayoutTransform> 
                <Ellipse x:Name="circle" Fill="White" HorizontalAlignment="Center" Height="19" Stroke="#FF333333" VerticalAlignment="Center" Width="19"/> 
                <Path x:Name="arrow" Data="M1,1.5L4.5,5 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="False" Stroke="#FF333333" StrokeThickness="2" VerticalAlignment="Center"/> 
               </Grid> 
               <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="Center" Margin="0,4,0,0" Grid.Row="1" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Top"/> 
              </Grid> 
             </Border> 
             <ControlTemplate.Triggers> 
              <Trigger Property="IsChecked" Value="True"> 
               <Setter Property="Data" TargetName="arrow" Value="M1,4.5L4.5,1 8,4.5"/> 
              </Trigger> 
              <Trigger Property="IsMouseOver" Value="True"> 
               <Setter Property="Stroke" TargetName="circle" Value="#FF5593FF"/> 
               <Setter Property="Fill" TargetName="circle" Value="#FFF3F9FF"/> 
               <Setter Property="Stroke" TargetName="arrow" Value="Black"/> 
              </Trigger> 
              <Trigger Property="IsPressed" Value="True"> 
               <Setter Property="Stroke" TargetName="circle" Value="#FF3C77DD"/> 
               <Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/> 
               <Setter Property="Fill" TargetName="circle" Value="#FFD9ECFF"/> 
               <Setter Property="Stroke" TargetName="arrow" Value="Black"/> 
              </Trigger> 
              <Trigger Property="IsEnabled" Value="False"> 
               <Setter Property="Stroke" TargetName="circle" Value="#FFBCBCBC"/> 
               <Setter Property="Fill" TargetName="circle" Value="#FFE6E6E6"/> 
               <Setter Property="Stroke" TargetName="arrow" Value="#FF707070"/> 
              </Trigger> 
             </ControlTemplate.Triggers> 
            </ControlTemplate> 
           </Setter.Value> 
          </Setter> 
         </Style> 
        </Setter.Value> 
       </Setter> 
      </Trigger> 
      <Trigger Property="ExpandDirection" Value="Up"> 
       <Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Top"/> 
       <Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Bottom"/> 
       <Setter Property="Style" TargetName="HeaderSite"> 
        <Setter.Value> 
         <Style TargetType="{x:Type ToggleButton}"> 
          <Setter Property="Template"> 
           <Setter.Value> 
            <ControlTemplate TargetType="{x:Type ToggleButton}"> 
             <Border Padding="{TemplateBinding Padding}"> 
              <Grid Background="Transparent" SnapsToDevicePixels="False"> 
               <Grid.ColumnDefinitions> 
                <ColumnDefinition Width="19"/> 
                <ColumnDefinition Width="*"/> 
               </Grid.ColumnDefinitions> 
               <Grid> 
                <Grid.LayoutTransform> 
                 <TransformGroup> 
                  <RotateTransform Angle="180"/> 
                 </TransformGroup> 
                </Grid.LayoutTransform> 
                <Ellipse x:Name="circle" Fill="White" HorizontalAlignment="Center" Height="19" Stroke="#FF333333" VerticalAlignment="Center" Width="19"/> 
                <Path x:Name="arrow" Data="M1,1.5L4.5,5 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="False" Stroke="#FF333333" StrokeThickness="2" VerticalAlignment="Center"/> 
               </Grid> 
               <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="1" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="Left" Margin="4,0,0,0" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Center"/> 
              </Grid> 
             </Border> 
             <ControlTemplate.Triggers> 
              <Trigger Property="IsChecked" Value="True"> 
               <Setter Property="Data" TargetName="arrow" Value="M1,4.5L4.5,1 8,4.5"/> 
              </Trigger> 
              <Trigger Property="IsMouseOver" Value="True"> 
               <Setter Property="Stroke" TargetName="circle" Value="#FF5593FF"/> 
               <Setter Property="Fill" TargetName="circle" Value="#FFF3F9FF"/> 
               <Setter Property="Stroke" TargetName="arrow" Value="Black"/> 
              </Trigger> 
              <Trigger Property="IsPressed" Value="True"> 
               <Setter Property="Stroke" TargetName="circle" Value="#FF3C77DD"/> 
               <Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/> 
               <Setter Property="Fill" TargetName="circle" Value="#FFD9ECFF"/> 
               <Setter Property="Stroke" TargetName="arrow" Value="Black"/> 
              </Trigger> 
              <Trigger Property="IsEnabled" Value="False"> 
               <Setter Property="Stroke" TargetName="circle" Value="#FFBCBCBC"/> 
               <Setter Property="Fill" TargetName="circle" Value="#FFE6E6E6"/> 
               <Setter Property="Stroke" TargetName="arrow" Value="#FF707070"/> 
              </Trigger> 
             </ControlTemplate.Triggers> 
            </ControlTemplate> 
           </Setter.Value> 
          </Setter> 
         </Style> 
        </Setter.Value> 
       </Setter> 
      </Trigger> 
      <Trigger Property="ExpandDirection" Value="Left"> 
       <Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Left"/> 
       <Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Right"/> 
       <Setter Property="Style" TargetName="HeaderSite"> 
        <Setter.Value> 
         <Style TargetType="{x:Type ToggleButton}"> 
          <Setter Property="Template"> 
           <Setter.Value> 
            <ControlTemplate TargetType="{x:Type ToggleButton}"> 
             <Border Padding="{TemplateBinding Padding}"> 
              <Grid Background="Transparent" SnapsToDevicePixels="False"> 
               <Grid.RowDefinitions> 
                <RowDefinition Height="19"/> 
                <RowDefinition Height="*"/> 
               </Grid.RowDefinitions> 
               <Grid> 
                <Grid.LayoutTransform> 
                 <TransformGroup> 
                  <RotateTransform Angle="90"/> 
                 </TransformGroup> 
                </Grid.LayoutTransform> 
                <Ellipse x:Name="circle" Fill="White" HorizontalAlignment="Center" Height="19" Stroke="#FF333333" VerticalAlignment="Center" Width="19"/> 
                <Path x:Name="arrow" Data="M1,1.5L4.5,5 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="False" Stroke="#FF333333" StrokeThickness="2" VerticalAlignment="Center"/> 
               </Grid> 
               <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="Center" Margin="0,4,0,0" Grid.Row="1" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Top"/> 
              </Grid> 
             </Border> 
             <ControlTemplate.Triggers> 
              <Trigger Property="IsChecked" Value="True"> 
               <Setter Property="Data" TargetName="arrow" Value="M1,4.5L4.5,1 8,4.5"/> 
              </Trigger> 
              <Trigger Property="IsMouseOver" Value="True"> 
               <Setter Property="Stroke" TargetName="circle" Value="#FF5593FF"/> 
               <Setter Property="Fill" TargetName="circle" Value="#FFF3F9FF"/> 
               <Setter Property="Stroke" TargetName="arrow" Value="Black"/> 
              </Trigger> 
              <Trigger Property="IsPressed" Value="True"> 
               <Setter Property="Stroke" TargetName="circle" Value="#FF3C77DD"/> 
               <Setter Property="StrokeThickness" TargetName="circle" Value="1.5"/> 
               <Setter Property="Fill" TargetName="circle" Value="#FFD9ECFF"/> 
               <Setter Property="Stroke" TargetName="arrow" Value="Black"/> 
              </Trigger> 
              <Trigger Property="IsEnabled" Value="False"> 
               <Setter Property="Stroke" TargetName="circle" Value="#FFBCBCBC"/> 
               <Setter Property="Fill" TargetName="circle" Value="#FFE6E6E6"/> 
               <Setter Property="Stroke" TargetName="arrow" Value="#FF707070"/> 
              </Trigger> 
             </ControlTemplate.Triggers> 
            </ControlTemplate> 
           </Setter.Value> 
          </Setter> 
         </Style> 
        </Setter.Value> 
       </Setter> 
      </Trigger> 
      <Trigger Property="IsEnabled" Value="False"> 
       <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> 
      </Trigger> 
     </ControlTemplate.Triggers> 
    </ControlTemplate> 
Cuestiones relacionadas