Daniel
Daniel

Reputation: 911

How to position WPF Expander based on Header height?

I have been struggling with a problem that at first glance might look easy for quite some time now. The problem in short is that I want to position an expander based on the height of the header in the expander.

The long story is that I have a grid with (currently, but that could be easily changed) two rows. At the bottom at the first row (kind of a header) I would like to put an Expander. However, I would like this expander to expand onto the second row. Simply putting the expander in the first row and setting vertical alignment to bottom positions my expander correctly but brakes the expansion (expands to same row only). Setting Grid.RowSpan="2" makes my expander expand correctly but that brakes my original vertical alignment to the bottom. I've tried putting the expander in the second row and then bind the margin of the expander to the ActualHeight of the expander (along with a converter which gave me a negative top margin equal to the height) which turned out great, until I clicked my expander :-). Setting the binding mode to "OneTime" gave me a zero margin for some reason.

Do anybody have an easy solution for this? Would it help to create a control template for my expander based on a canvas (my thinking is that canvas would be drawn on top of other controls)? I guess I could have done databinding to a descendant control if that was supported (which I don't think it is). Have I missed any obvious solutions?

I have the possibilty to change the control template for the expander and changing the grid layout of my window containing the control is not an issue if that could help me in anyway.

I am running Visual Studio 2008, .NET 3.5.

//daniel

Upvotes: 2

Views: 1822

Answers (1)

Ray Burns
Ray Burns

Reputation: 62919

There is a way to make it appear that a single expander has separate layout for its header and content, so they can be in separate grid cells or even totally separate parts of the window. This may be overkill for what you really want to accomplish, but here it is:

  1. Create an expander with your header but an empty body. Place it in the upper cell.
  2. Create another expander with the body you want but set its Template property to a template containing just a ContentPresenter so no header will be visible. Place it in the lower cell.
  3. Bind the second expander's IsExpanded property to the first expander's IsExpanded property
  4. Optionally adjust tab order so the two Expanders are together

Now when you expand the upper expander the lower expander will expand as well. If there is no gap between them, they will appear as if they were a single expander.

Another option which may be effective is to use a single Expander and modify its template so its entire header (including the button) has VerticalAlignment="Bottom" and is inside a zero-size Canvas. In that case the entire Expander would go in your lower cell. This has the disadvantage that layout of the upper cell would be unaware of the space used by the Expander so it would likely place other controls over or under it depending on the z-order.

Upvotes: 1

Related Questions