John
John

Reputation: 1764

XAML How to get Canvas's Child to fill the entire Canvas?

if I have this XAML:

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
<StackPanel Orientation="Horizontal">
    <Grid Background="Gray" Margin="5"
        Height="200" Width="200">
        <Rectangle Fill="Blue" />
    </Grid>
    <Canvas Background="Gray" Margin="5"
        Height="200" Width="200">
        <Rectangle Fill="Blue" />
    </Canvas>
    <StackPanel Background="Gray" Margin="5"
        Height="200" Width="200">
        <Rectangle Fill="Blue" />
    </StackPanel>
</StackPanel>

Only the Grid is filled by the blue rectangle, But I would like the Canvas to operate the same way and be filled with the blue rectangle?

I am up for making a custom canvas, but not sure how to go about it.

Any suggestions?

Upvotes: 4

Views: 4896

Answers (2)

ChrisF
ChrisF

Reputation: 137178

You could try something like this:

<Canvas x:Name="myCanvas" Background="Gray" Margin="5"
    Height="200" Width="200">
    <Rectangle Fill="Blue"
               Height="{Binding ElementName=myCanvas, Path=ActualHeight}"
               Width="{Binding ElementName=myCanvas, Path=ActualWidth}" />
</Canvas>

This will tell the rectangle to take it's dimensions from the actual dimensions of the named element.

The reason only the Grid is filled is because it's the only one that tells it's children what size to be. The StackPanel takes it's size from the combined size of all it's children and the Canvas is the size you tell it to be but doesn't resize any child elements.

Upvotes: 11

Jim O&#39;Neil
Jim O&#39;Neil

Reputation: 23774

Since Canvas doesn't obey HorizontalAlignment and VerticalAlignment, you'll have to set the size of the nested element explicitly.

One option is element binding:

<Canvas x:Name="theCanvas" Background="Gray" Margin="5" Height="200" Width="200" >
     <Rectangle Fill="Blue" 
                Height="{Binding ElementName=theCanvas, Path=Height}" 
                Width="{Binding ElementName=theCanvas, Path=Width}"  />
</Canvas>

which is a bit fragile since it relies on the parent element name (here myCanvas). In WPF, you can get by this with a RelativeSource FindAncestor, but not in Silverlight or Windows 8.

You can find a number of workarounds/extensions to fill the FindAncestor gap - like this one - so that may be a more reusable option?

You might be able to do something in a converter as well, traversing the visual tree to grab the canvas dimensions.

Upvotes: 4

Related Questions