2009-03-25 36 views

Trả lời

40

Tất cả bạn cần làm là:

<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

Làm cách nào để làm điều này trong mã? Tôi nhận ra rằng tôi phải chiếm một số không gian cho một nút – Ngm

+0

Xin lỗi tôi không biết làm thế nào để làm điều đó trong mã. –

+3

TextBlock bx = new TextBlock(); bx.Text = "Tôi là văn bản tiêu đề ..."; Ràng buộc wdBind = Binding mới ("ActualWidth"); wdBind.RelativeSource = new RelativeSource (RelativeSourceMode.FindAncestor, typeof (Expander), 1); bx.SetBinding (TextBlock.TextProperty, wdBind); –

10

Non căng Expander s thường là vấn đề của các điều khiển cha mẹ không căng ra .. Có lẽ một trong những điều khiển cha mẹ đã xác định một HorizontalAlignment hoặc VerticalAlignment tài sản?

Nếu bạn có thể đăng một số mã mẫu, chúng tôi có thể cung cấp cho bạn câu trả lời tốt hơn.

+0

Tôi có thể xác nhận rằng việc thay đổi thuộc tính này trên kiểm soát gốc sẽ khắc phục sự cố. Vì vậy, dễ dàng hơn nhiều so với bất kỳ tùy chọn khác – Matt

1

Tôi đồng ý với HTH - kiểm tra loại thùng chứa bạn đang đặt Expander trong ... StackPanel sẽ luôn gấp trẻ em xuống kích thước nhỏ nhất mà chúng có thể truy cập.

Tôi đang sử dụng Vùng mở rộng trong dự án của mình và nếu bạn thả chúng vào Grid/DockPanel, khi đó trình giãn nở sẽ lấp đầy tất cả khoảng trống sẵn có (giả sử là Vertical & Hướng ngang được đặt thành Căng).

Jonathan đề xuất ràng buộc chiều rộng của Expander với chiều rộng của container có thể hơi phức tạp ... Tôi đã thử kỹ thuật này một vài tuần trước và thấy rằng nó có thể producte kết quả không mong muốn trong một số trường hợp, bởi vì nó có thể ức chế hoạt động hệ thống bố trí.

PS: Là một mẹo chung (và tôi chắc chắn mình sẽ bị quấy rầy khi viết bài này), nếu bạn không chắc chắn về loại bố cục nào trong bộ điều khiển của mình, hãy bắt đầu với một Lưới . Sử dụng cột & Định nghĩa hàng cho phép bạn dễ dàng kiểm soát việc điều khiển con có sử dụng không gian tối thiểu ("Tự động"), không gian tối đa ("*") hay không gian chính xác ("[số]").

+0

Lưới chắc chắn là linh hoạt nhất và dễ sử dụng container. Tôi đã nghe nói rằng nó thực hiện tồi tệ hơn nhiều so với hầu hết các container. –

+3

@Mark, bạn có nghĩa là bạn đồng ý với Arcturus. HTH có nghĩa là Hy vọng đó giúp và là một phổ biến đóng cửa xung quanh đây. –

0

Bộ công cụ Silverlight bao gồm điều khiển Accordion hoạt động như bộ mở rộng luôn kéo dài đến không gian có sẵn. Tôi chưa thử nghiệm nó, nhưng nó có thể là chức năng cho WPF quá, giống như các điều khiển biểu đồ Silverlight.

6

Giải pháp này đơn giản hơn nhiều và không ảnh hưởng đến các điều khiển giãn nở khác mà bạn có thể sử dụng trong ứng dụng của mình.

<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

Câu trả lời được chấp nhận rút bên ngoài sự kiểm soát vì nội dung tiêu đề là trong một cột và nút giãn nở là trong lần đầu tiên. Có thể đủ tốt cho một số trường hợp.

Nếu bạn muốn có giải pháp sạch, bạn phải thay đổi mẫu của thiết bị mở rộng.

Một cách khác là một tài sản gắn liền:

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); 
     } 
    } 
} 

Nó cho phép bạn làm:

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

Lưu ý rằng việc sử dụng các tài sản gắn liền có phần mong manh vì nó giả định rằng có một ContentPresenter trong mẫu.

3

Tôi khá ngạc nhiên chưa ai đề cập đến chỉ cần chỉnh sửa mẫu kiểm soát, tất cả các giải pháp khác có một số nhược điểm khá nghiêm trọng vượt qua chiều rộng không tính toán nó đúng cách, không vẽ lại, thời gian render vv ...

kiểm soát này mẫu sẽ sửa đổi căn chỉnh ngang của nội dung của tiêu đề để khớp với các bộ tăng tốc thực tế (có nghĩa là nó sẽ giãn ra)

<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> 
Các vấn đề liên quan