Reputation: 6147
Is there any way to make the Header
of an Expander
Fit the max-width in a resizeable window in WPF? It appears that no matter what I do I can't get the contents to expand to maximum width. It does work in the Content
section of the Expander
.
<Grid Background="LightGray">
<Expander IsExpanded="True">
<Expander.Header>
<Grid Width="100" Height="50">
<Rectangle Fill="Red"></Rectangle>
</Grid>
</Expander.Header>
<Rectangle Fill="Red"></Rectangle>
</Expander>
</Grid>
Upvotes: 2
Views: 3008
Reputation: 4202
The fastest way is to bind the width of the header to the width of the whole expander.
<Expander IsExpanded="True">
<Expander.Header>
<Grid Width="{Binding RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type Expander}},
Path=ActualWidth}"
Height="50">
<Rectangle Fill="Red"></Rectangle>
</Grid>
</Expander.Header>
<Rectangle Fill="Red"></Rectangle>
</Expander>
But it's not a precise method because you have the arrow which also takes some space and you can see that the header is a bit wider than you need.
You can override the standard template (HeaderTemplate
) of the expander's header.
UPDATE
I found a possible solution using the code-behind file (all credits go to @kmatyaszek).
Add a helper class to find the control we need to change the width. It checks the whole Visual Tree of the parent control and returns a child of the type we are looking for.
public static class VTHelper
{
public static T FindChild<T>(DependencyObject parent) where T : DependencyObject
{
if (parent == null) return null;
T childElement = null;
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
T childType = child as T;
if (childType == null)
{
childElement = FindChild<T>(child);
if (childElement != null)
break;
}
else
{
childElement = (T)child;
break;
}
}
return childElement;
}
}
Add a handler to process the loading event. It changes the HorizontalAlignment
property of the ContentPresenter
instance:
private void expander_Loaded(object sender, RoutedEventArgs e)
{
var tmp = VTHelper.FindChild<ContentPresenter>(sender as Expander);
if (tmp != null)
{
tmp.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
}
}
Attach this handler to the expander:
<Expander IsExpanded="True" Loaded="expander_Loaded">
This approach uses the code-behind but it doesn't work with any data (or ViewModel). It changes only the visual appearance of the control.
Upvotes: 7
Reputation: 45
<Expander Name="myexpander" IsExpanded="True" Margin="0,0,1,0">
<Expander.Header>
<Grid Width="{Binding ElementName=myexpander, Path=ActualWidth}" Height="50">
<Rectangle Fill="Red"></Rectangle>
</Grid>
</Expander.Header>
<Rectangle Fill="Red"></Rectangle>
</Expander>
</Grid>
give a name to your expander and bind the width property
Upvotes: 3