12

I am trying to create a canvas with scroll bars. Can anyone help me give some ideas on how to do this? I have already tried using grid of 1 row and 1 column but due to certain constraints I want to use canvas.

Thanks in advance!

Scooby
  • 635
  • 3
  • 9
  • 21

3 Answers3

20

You could put the canvas inside of a scrollviewer. I tried this quick test and it allowed me to scroll through the contents of the canvas.

<ScrollViewer Height="100" Width="200">
    <Canvas Height="400" Width="400">
            //Content here
    </Canvas>
</ScrollViewer>

edit: Here is an example where the scroll-bars show up only when needed, and it changes dynamically as the canvas size changes.

    <Button Content="Change Canvas Size" Click="ChangeCanvasSize_Click"/>
<ScrollViewer Height="100" Width="200" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
    <Canvas x:Name="TestCanvas">
            <TextBlock Text="Test Test"/>
    </Canvas>
 </ScrollViewer>

Changing canvas size with button click:

    private void ChangeCanvasSize_Click(object sender, RoutedEventArgs e)
    {
        TestCanvas.Width = 600;
        TestCanvas.Height = 600;
    }

In this example, I start out with no scroll-bars and when I click the button to expand the canvas, scroll-bars appear.

Andrea Antonangeli
  • 1,242
  • 1
  • 21
  • 32
Ben Collier
  • 2,632
  • 1
  • 23
  • 18
  • Thanks for your response. But the thing is I do not know the size of my canvas until runtime. So can not have a fixed size canvas. I will increase the dimension of canvas if user, say, clicks near the boundary of existing canvas then the canvas width and/or height will increase by say 50 units and scrollbar should appear. – Scooby May 13 '10 at 19:00
  • 1
    This should still work, if you set the visibility of the scroll-bars to "Auto". I modified my example to illustrate. – Ben Collier May 13 '10 at 20:17
3

Ok after working with it for sometime I figured out a way. Create a XAML like this

<ScrollViewer>
 <Grid x:Name="drawingGrid" SizeChanged="drawingGrid_SizeChanged">
<Canvas Name="drawingCanvas"> /<Canvas>
</Grid>
</ScrollViewer>

On windowLoad function set the canvas height/width equal to grid height/width. Update the canvas ht/wd:

  1. when grid size changes, due to mininmize/maximize.
  2. dragging an element beyond the boundaries of canvas or creating a new element too close the edge of canvas

    double dHeight = 220;
    if (drawingCanvas.Height < CurrentPosition.Y + dHeight)
    {
        // increase canvas height
        drawingCanvas.Height += (2 * dHeight);
    }
    

Hope this is of some help. Please share if anyone has any better idea or suggestions to improve this.

Mario S
  • 11,715
  • 24
  • 39
  • 47
Scooby
  • 635
  • 3
  • 9
  • 21
1

By combining Mario-sannum's answer and your question then I've made a solution that should work fine in most cases..

<ScrollViewer>
<Grid x:Name="drawingGrid" SizeChanged="drawingGrid_SizeChanged">
<Canvas Name="c">
<TextBlock x:Name="draw_Text" Text="Test Test"/>
</<Canvas>
</Grid>
</ScrollViewer>


void drawingGrid_SizeChanged(object sender, SizeChangedEventArgs e)
{
      try { c.Height = draw_Text.ActualHeight; } catch { }
      try { c.Width = draw_Text.ActualWidth; } catch { }
}

That should resize the Canvas so the scrollviewer can scroll...

ArchAngel
  • 634
  • 7
  • 16