Question

I need to implement a Canvas which scales its contents according to its size. I know there is Viewbox, which scales everything inside of it. However I cannot use that, because some elements have a fixed size and cannot be scaled.

Also how can I bind the size of the Canvas to the parent element (for example a resizable window). There is sizeToContent for windows, I want the size fitting exactly the other way round. Also the canvas uses some drawing based on the size of the hosting element, how is redraw triggered and how can I ensure that it only draws if it gets a valid (or min) size?

Was it helpful?

Solution

If you don't specify any width or height to the canvas it automatically uses all the available space. This is because the default VerticalAlignment and HorizontalAlignment are set to Stretch.

What do you mean by canvas that scales it's contents according to it's size without scaling all the contents as some have fixed size?

Update after comments

If your drawing algorithm already scales the content to the canvas' height and width then all you need to do is to resize the canvas to fit the area I believe? In that case just remove the hardcoded height/width values and the canvas will resize to fit the container.

You might need to use ActualHeight/ActualWidth instead of Height/Width in the drawing algorithm after this though. ActualHeight/ActualWidth return the values that the layout container will give your canvas so these represents the values the canvas is drawn with.

OTHER TIPS

I think you can find the answers to all your questions in my London Underground demo.

I'm doing this from memory, but if I recall correctly a Window uses either a Panel or a Canvas as part of it's ControlTemplate (in which lies the ContentPresenter), which means that a Canvas placed directly in a Window will have issues resizing automatically like it might elsewhere. There are a few basic ways to address this.

1 Write a new ControlTemplate for your Window to use. :(
2 Place your content directly in the Window rather than in a Canvas inside the Window. :/
3 Do a by-name binding. :)

<MyWindow x:Name="topWindow">
    <Canvas x:Name="topCanvas" Width="{Binding ElementName=topWindow, Path=ActualWidth}" Height="{Binding ElementName=topWindow, Path=ActualHeight}">
        ...Content...
    </Canvas>
</MyWindow>

(As it happens, I often bind grids inside Canvases in this fashion, so I can easily animate items moving from one grid position to another.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top