Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a ScrollViewer with an ItemsControl with a Canvas as the ItemsPanel

I have an ItemsControl and I set the ItemsPanel to a Canvas. The Canvas needs to be able to dynamically size with the content I put in it, and I need to be able to scroll when content runs off the bounds of the control. The trouble is I can't get the content to scroll. I have the scroll bar visibilities set to auto, so I don't end up seeing the scroll bars pop up when content runs off the edge.

I tried both putting the ItemsControl inside a ScrollViewer, and I tried using a ScrollViewer in the ItemsControl's Template.

Here's the ItemsControl inside the ScrollViewer:

<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
    <ItemsControl ItemsSource="{Binding Tiles}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <ItemsControl.ItemContainerStyle>
            <Style>
                <Setter Property="Canvas.Left" Value="{Binding Left}" />
                <Setter Property="Canvas.Top" Value="{Binding Top}" />
            </Style>
        </ItemsControl.ItemContainerStyle>

        <ItemsControl.ItemTemplateSelector>
            ...
        </ItemsControl.ItemTemplateSelector>
    </ItemsControl>
</ScrollViewer>

And here it is with the ScrollViewer in the Template:

<ItemsControl ItemsSource="{Binding Tiles}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemContainerStyle>
        <Style>
            <Setter Property="Canvas.Left" Value="{Binding Left}" />
            <Setter Property="Canvas.Top" Value="{Binding Top}" />
        </Style>
    </ItemsControl.ItemContainerStyle>

    <ItemsControl.Template>
        <ControlTemplate>
            <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
                <ItemsPresenter />
            </ScrollViewer>
        </ControlTemplate>
    </ItemsControl.Template>

    <ItemsControl.ItemTemplateSelector>
        ...
    </ItemsControl.ItemTemplateSelector>
</ItemsControl>

This post on MSDN seemed promising, but implementing it on my code, or even explicitly with a Canvas in lieu of a WrapPanel wasn't working (or, should I say, I wasn't able to get it to work).

I've also taken a look at this post but the solution doesn't work for me as I need the canvas to be able to size with the content (otherwise the scroll bars are always visible).

Thank you kindly, in advance!

like image 245
Ian Wold Avatar asked Oct 23 '25 00:10

Ian Wold


1 Answers

The canvas's width/height when not explicitly set, will inherit from the ItemsControl. The "dynamic sizing" behavior you're expecting isn't how panels sizing and layout works out of the box.

You options are to:

  1. Explicitly set the ItemsControl Width/Height.
  2. Explicitly set the Canvas Width/Height.
like image 75
Michael G Avatar answered Oct 25 '25 19:10

Michael G