tags:

views:

539

answers:

1

tl;dr: I want detail views to appear in 2 columns if 2 items are selected, and to span 2 columns if only 1 item is selected.

I have a DockPanel with 2 ListBoxes docked on the left and a 2-column Grid on the right.

When an item is selected in listBox1, I display a details view in Column 0 of the Grid.

When an item is selected in listBox2, I display a details view in Column 1 of the Grid.

    <DockPanel>

        <StackPanel DockPanel.Dock="Left" Orientation="Horizontal">
            <ListBox x:Name="listBox1" ItemsSource="{Binding Items1}" SelectedItem="{Binding SelectedItem1}"/>                    
            <ListBox x:Name="listBox2" ItemsSource="{Binding Items2}" SelectedItem="{Binding SelectedItem2}"/>
        </StackPanel>

        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>

            <ContentControl Grid.Column="0" Content="{Binding SelectedItem1}" ContentTemplateSelector="{StaticResource SelectedItemTemplateSelector}"/>
            <ContentControl Grid.Column="1" Content="{Binding SelectedItem2}" ContentTemplateSelector="{StaticResource SelectedItemTemplateSelector}"/>
        </Grid>

    </DockPanel>

This works fine. However, I'd like to modify it so that the details view will span both grid columns when there is an item selected in one of the ListBoxes but not in the other.

My first thought was to create a couple of DataTriggers that modify the ColumnSpan of the ContentControls based on the SelectedIndex of the ListBoxes.

This works fine for the details view that normally lives in Grid.Column="0". However, it doesn't work for the details view that normally lives in Grid.Column="1" since the original column number is hard-coded:

            <ContentControl Grid.Column="0" Content="{Binding SelectedItem1}" ContentTemplateSelector="{StaticResource SelectedItemTemplateSelector}">
                <ContentControl.Style>
                    <Style TargetType="ContentControl">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding ElementName=listBox2, Path=SelectedIndex}" Value="-1">
                                <Setter Property="Grid.ColumnSpan" Value="2"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ContentControl.Style>
            </ContentControl>

            <ContentControl Grid.Column="1" Content="{Binding SelectedItem2}" ContentTemplateSelector="{StaticResource SelectedItemTemplateSelector}">
                <ContentControl.Style>
                    <Style TargetType="ContentControl">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding ElementName=listBox1, Path=SelectedIndex}" Value="-1">
                                <!--Can't modify Grid.Column since it's hardcoded above!-->
                                <Setter Property="Grid.Column" Value="0"/>
                                <Setter Property="Grid.ColumnSpan" Value="2"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ContentControl.Style>
            </ContentControl>

If I could create a DataTrigger that could do a value comparison against ListBox.SelectedIndex (ie. >=0), then I could avoid hard-coding the column numbers in the first place.

Is there any way to do something like this in XAML?

A: 

I ended up implementing the converter described here.