2
votes

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

1
It is clear what you were doing, but not what you were actually trying to achieve. I give an answer below that is a general technique that will probably work for you, but it might be overkill. If I understood what you wanted to achieve I might be able to suggest a simpler approach. Some of the things that were unclear are: What should control the height of the gridline? What should change as the header grows and shrinks? Should the expander going down should displace content or cover over it? A mockup of your UI might help.Ray Burns
The upper grid line is fixed in size due to content such as logotypes and like. The lower grid lines is just "the rest", the "main" content. I want to align my expander to the bottom of the upper row and have it expand over the second row. I want it to cover any of the "main" content if necessary. That is basically it. If I can do that I am satisfied. The font size in the expander header might change so I cannot just offset the position using a negative margin (at least not a const one). In the end,if I could just alignment to position the expander I would be happy.Daniel

1 Answers

1
votes

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.