JT Smith
JT Smith

Reputation: 381

Canvas causes contentcontrol children to spill out over control

I have the following XAML:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*"/>
        <ColumnDefinition Width="11" />
        <ColumnDefinition Width="3*"/>
    </Grid.ColumnDefinitions>
    <ListView ... Grid.Column="2"/>
    <controls:GridSplitter 
    Grid.Column="1"
        Width="11"
    ResizeBehavior="BasedOnAlignment"
    ResizeDirection="Auto"
        Background="Gray"
        Foreground="White" 
        FontSize="13">
        <controls:GridSplitter.Element>
            <Grid>
                <TextBlock HorizontalAlignment="Center" 
                           IsHitTestVisible="False"
                           VerticalAlignment="Center"  
                            Text="&#xE784;"
                           Foreground="Black" 
                           FontFamily="Segoe MDL2 Assets">
                </TextBlock>
            </Grid>
        </controls:GridSplitter.Element>
    </controls:GridSplitter>
    <Canvas Canvas.ZIndex="1">
        <ContentControl MaxWidth="750" Content="{Binding CAV, Mode=TwoWay}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" />
    </Canvas>
</Grid>

Without the Canvas wrapped around the ContentControl in the first column, the children of the ContentControl properly stay within the content control and I can make it wider to see more of the children horizontally.

When I add the Canvas and set the ZIndex, the children of the content control spill out over the gridsplitter and the ListView without respecting the width of the contentcontrol.

The effect I'm trying to get it to allow expanding the width of the content control with the grid splitter and having that content control expand "over" the listview (instead of reducing the width of the listview).

What am I missing? I'm confused as to why the width of the contentcontrol isn't being respected suddenly just because I wrap it in a Canvas. Or should I not be using Canvas to get the "overlay" effect I want?

Upvotes: 2

Views: 117

Answers (2)

Johnny Westlake
Johnny Westlake

Reputation: 1460

As an addendum Canvas tells the layout tree it uses no space. It doesn't care about the size of it's children, despite however many children it might have. For reference, here's the Canvas' MeasureOverride:

protected override Size MeasureOverride(Size constraint)
{
    Size childConstraint = new Size(Double.PositiveInfinity, Double.PositiveInfinity);

    foreach (UIElement child in InternalChildren)
    {
        if (child == null) { continue; }
        child.Measure(childConstraint);
    }

    return new Size();
}

Which effectively says "I'm not taking up any space and my children can use whatever space they want".

Upvotes: 1

Justin XL
Justin XL

Reputation: 39006

Canvas doesn't stretch its children. It only gives them the space they need. In fact, you don't have to wrap your ContentControl inside a Canvas to set the Canvas.ZIndex; it is an attached property that can be attached to the ContentControl directly. If you want a panel that allows its children/child to stretch, try a Border(single child only) or a Grid.

However, setting the ZIndex here seems to be unnecessary to me. Since the GridSplitter simply resizes the width of the columns, there won't be any overlay happening here.

If you want the overlay effect, you need to create another Grid with the same column layout and place your ListView there, something like the following -

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="2*" />
            <ColumnDefinition Width="11" />
            <ColumnDefinition Width="3*" />
        </Grid.ColumnDefinitions>
        <Grid x:Name="ListView" Background="LightGreen" Grid.Column="2" />
    </Grid>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="2*" />
            <ColumnDefinition Width="11" />
            <ColumnDefinition Width="3*" />
        </Grid.ColumnDefinitions>
        <controls:GridSplitter Grid.Column="1" Background="LightBlue">
        </controls:GridSplitter>
        <Grid x:Name="ContentControl" Background="LightPink" Opacity="0.5" />
    </Grid>
</Grid>

enter image description here

Upvotes: 3

Related Questions