Getting WPF Expander and Listbox Alignment Happy

January 20 2009

Burnt a little time on this one: I had a WPF Expander inside a ListBox and couldn’t get the Expander to align to the top when one expander was collapsed and another expander was uncollapsed.  Consider the following XAML:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid> <ListBox VerticalAlignment="Top"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <StackPanel IsItemsHost="True" Orientation="Horizontal"/> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBoxItem> <Expander ExpandDirection="Right"> <Grid> <ListBox> <ListBox.Items> <ListBoxItem Name="Item0">Option 0 </ListBoxItem> <ListBoxItem Name="Item1">Option 1 </ListBoxItem> <ListBoxItem Name="Item2">Option 2 </ListBoxItem> </ListBox.Items> </ListBox> </Grid> </Expander> </ListBoxItem> <ListBoxItem> <Expander ExpandDirection="Right"> <Grid> <ListBox> <ListBox.Items> <ListBoxItem>Option 0 </ListBoxItem> <ListBoxItem>Option 1 </ListBoxItem> <ListBoxItem>Option 2 </ListBoxItem> <ListBoxItem>Option 0 </ListBoxItem> <ListBoxItem>Option 1 </ListBoxItem> <ListBoxItem>Option 2 </ListBoxItem> <ListBoxItem>Option 0 </ListBoxItem> <ListBoxItem>Option 1 </ListBoxItem> <ListBoxItem>Option 2 </ListBoxItem> <ListBoxItem>Option 0 </ListBoxItem> <ListBoxItem>Option 1 </ListBoxItem> <ListBoxItem>Option 2 </ListBoxItem> <ListBoxItem>Option 0 </ListBoxItem> <ListBoxItem>Option 1 </ListBoxItem> <ListBoxItem>Option 2 </ListBoxItem> <ListBoxItem>Option 0 </ListBoxItem> <ListBoxItem>Option 1 </ListBoxItem> <ListBoxItem>Option 2 </ListBoxItem> </ListBox.Items> </ListBox> </Grid> </Expander> </ListBoxItem> </ListBox> </Grid> </Page>

It would look fine if both were collapsed:

But if one was collapsed and one wasn’t:

Or even if both were uncollapsed:

It wouldn’t align. It was driving me crazy. I snooped around and tried all kinds of shenanigans in various control templates and styles to make it behave. But it turned out the fix was easy: I needed to set the VerticalAlignment on the ListboxItem itself as follows. (See bold.)

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <Grid>
      <ListBox VerticalAlignment="Top">
         <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
               <StackPanel IsItemsHost="True" Orientation="Horizontal"/>
            </ItemsPanelTemplate>
         </ListBox.ItemsPanel>
         <ListBoxItem VerticalAlignment="Top">
            <Expander ExpandDirection="Right">
               <Grid>
                  <ListBox>
                     <ListBox.Items>
                        <ListBoxItem Name="Item0">Option 0
                        
                        </ListBoxItem>
                        <ListBoxItem Name="Item1">Option 1
                        
                        </ListBoxItem>
                        <ListBoxItem Name="Item2">Option 2
                        
                        </ListBoxItem>
                     </ListBox.Items>
                  </ListBox>
               </Grid>
            </Expander>
         </ListBoxItem>
         <ListBoxItem  VerticalAlignment="Top">
            <Expander ExpandDirection="Right">
               <Grid>
                  <ListBox>
                     <ListBox.Items>
                        <ListBoxItem>Option 0
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 1
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 2
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 0
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 1
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 2
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 0
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 1
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 2
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 0
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 1
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 2
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 0
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 1
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 2
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 0
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 1
                        
                        </ListBoxItem>
                        <ListBoxItem>Option 2
                        
                        </ListBoxItem>
                     </ListBox.Items>
                  </ListBox>
               </Grid>
            </Expander>
         </ListBoxItem>
      </ListBox>
   </Grid>
</Page>

And then I got:

Yeah! I could of course put this in a style, etc.  And if this were a datatemplate instead of a listboxitem, I would style the listboxitem.

(Shout out to KAXAML as tool of choice when breaking down problems like this…)

Add comment

Enter your name, handle, alias, or email.

We'll incarnate your avatar from the services below.



biuquote
Loading