1

Based on this SO question, I've created a combobox with 2 columns, and a header. However, I needed the columns to be proportionally spaced, so I removed the shared size groups, and changed the width to "*". To stretch the the grid, I added the HorizontalContentAlignment on the ComboBox itself. See below for the complete xaml.

This worked for the rows with the actual data, but the headers kept left aligned. However, when I was inspecting it with Snoop, I noticed that the headers were fine.

Apparently, when I select the ComboBoxItem, which contains the header, the layout gets corrected (hence, the heisenbug).

Any ideas why this happens? How would you troubleshoot this? Do have the wrong approach in making the layout proportionally spaced?

The ComboBox looks like this. The employee is a simple POCO, and the collection a subclass of Collection<Employee> to make it work in the XAML. The full project can be found in this gist.

To reproduce this:

  1. start the application
  2. start Snoop, and inspect the application
  3. open the comboBox, and inspect an element
  4. select the first ComboBoxItem

        <ComboBox Name="cb" ItemsSource="{DynamicResource items}" HorizontalContentAlignment="Stretch">
        <ComboBox.DataContext>
            <obj:EmployeeCollection>
                <obj:Employee Name="John" Occupation="Developer" />
                <obj:Employee Name="Jack" Occupation="Spy" />
            </obj:EmployeeCollection>
        </ComboBox.DataContext>
        <ComboBox.Resources>
            <CompositeCollection x:Key="items">
                <ComboBoxItem IsEnabled="False">
                    <Grid TextElement.FontWeight="Bold">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>
                        <Grid.Children>
                            <TextBlock Grid.Column="0" Text="Name"/>
                            <TextBlock Grid.Column="1" Text="Occupation"/>
                        </Grid.Children>
                    </Grid>
                </ComboBoxItem>
                <Separator/>
                <CollectionContainer Collection="{Binding Source={x:Reference cb}, Path=DataContext}"/>
            </CompositeCollection>
            <DataTemplate DataType="{x:Type obj:Employee}">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.Children>
                        <TextBlock Grid.Column="0" Text="{Binding Name}"/>
                        <TextBlock Grid.Column="1" Text="{Binding Occupation}"/>
                    </Grid.Children>
                </Grid>
            </DataTemplate>
        </ComboBox.Resources>
    </ComboBox>
    
duplode
  • 33,731
  • 7
  • 79
  • 150
Ties
  • 1,205
  • 2
  • 15
  • 28
  • Why are you setting the `DataContext` to an `EmployeeCollection` and then bypassing it to use a separate object for the `ItemsSource`? – Sheridan Aug 21 '14 at 13:30
  • That's because the other stackoverflow question had that as solution to the problem. They're using a composite collection to combine a `ComboBoxItem` as header with the rest of the item collection. That's how you can make a popup with 2 columns and an header, without resorting to a listview. For that, you need to combine both in a composite collection, and bind that to the ItemsSource of the `ComboBox`. Since the `ItemsSource` has been used, they set the real source for the items using the `DataContext.Data` on the `Collection` property of the inner `CollectionContainer`. I just replaced that – Ties Aug 21 '14 at 17:41

1 Answers1

1

I don't experience the same problems as you do. The captions always stay completely left aligned, also not when I select it through XAML Spy (I don't use Snoop). But the problem is simply fixed by adding a HorizontalContentAlignment="Stretch" to the header ComboBoxItem.

XAML Spy reports the HorizontalContentAlignment to be Left with out it.

Willem van Rumpt
  • 6,490
  • 2
  • 32
  • 44
  • Ok, I tried `HorizontalContentAlignment`, but apparently not on the `ComboBoxItem`. That solves my probleem, indeed. Although, it doesn't explain the "heisenbug"... I actually wanted to investigate the issue with XAML Spy (we have a license for that ;)), however, I was unable to inspect the visual tree of the popup. When I try to select things in the popup, XAML Spy selects the elements beneath it... How do you do that? – Ties Aug 21 '14 at 17:46
  • I never saw a heisenbug. It simply didn't work, and the values reported by XAML Spy show it to be not a bug. I tried to see what happens with Snoop, but neither can, nor know how to reproduce the behavior you describe that way. To see the information in XAML Spy, you just cheat: Remove "IsEnabled" from the header item, and select it while running ;) – Willem van Rumpt Aug 21 '14 at 18:07
  • I wasn't talking about the ComboBoxItem, but popups in general. When I try to select anything in the popup (holding ctrl-shift), elements "beneath the popup" (so elements partly covered by the popup, that are in the window that holds the ComboBox) gets selected, instead of the elements in the popup itself. Do you need a different shortcut for popups? – Ties Aug 21 '14 at 20:16
  • Aaaaah, I see what you mean. No, there's no shortcut, it simply can't be done (AFAIK). You just have to "manipulate" your way around it so the visual element you're interested in somehow becomes part of the visual tree (in this case by selecting the combobox item). BTW: With a split view between XAML and design, you can also see the appearance in Visual Studio, if the element is a direct part of the visual tree, and not a DataTemplate (i.e. select your header ComboBoxItem in VS). – Willem van Rumpt Aug 22 '14 at 04:54