Question

We have a requirement for an absolute layout that allows scrolling of it's content (child control's). The layout and all Child controls are created and added on the fly during the application run; As a result XAML is NOT an option for creating the layout.

Unfortunately with code behind it is extremely difficult to achieve the desired scrolling behaviour; unlike with XAML where we can achieve it quite simply.

The following XAML demonstrates the desired behaviour

<phone:PhoneApplicationPage
    x:Class="TestWP8App.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">
<ScrollViewer HorizontalAlignment="Left" VerticalAlignment="Top" Width="480">
    <Canvas Height="1500">
        <Button Content="1" Height="300" Canvas.Left="10" Canvas.Top="10" Width="120"/>
        <Button Content="2" Height="300" Canvas.Left="10" Canvas.Top="110" Width="120"/>
        <Button Content="3" Height="300" Canvas.Left="10" Canvas.Top="210" Width="120"/>
        <Button Content="4" Height="300" Canvas.Left="10" Canvas.Top="310" Width="120"/>
        <Button Content="5" Height="300" Canvas.Left="10" Canvas.Top="410" Width="120"/>
    </Canvas>
</ScrollViewer>
</phone:PhoneApplicationPage>

With the above properties translated to C# code, It's possible to achieve the same 'look', only the content never scrolls.

Does anyone know how to achieve the same result via code-behind? Or know the location of an example that does exactly this SOLELY using code-behind?

Was it helpful?

Solution 3

The problem was an issue with parent-child relationships.

Initially I had a ScrollViewer(SV) and a main Canvas(MC).

The problem was that the MC was being added as a child of other container's even though MC was set as the Content of the SV.

The solution was to reparent SV in a 3rd Canvas(3C) making the hierarchy [parent -> child]:

3C -> SV -> MC

The width and heights could then be applied to 3C & SV, leaving MC to autosize according to it's contents.

As MC gets larger than SV & 3C, it allows scrolling.

All children are added to MC exclusively

OTHER TIPS

Its Easy

            ScrollViewer sViewer = new ScrollViewer() {HorizontalAlignment=HorizontalAlignment.Left,VerticalAlignment=VerticalAlignment.Top,Width480 };
            Canvas cc = new Canvas() { Height=1500};
            //same for all the buttons 
            Button b1 = new Button() { Height=300,Width=120,Content="1"};
            Canvas.SetLeft(b1, 10);
            Canvas.SetTop(b1, 10);
            //adding the canvas into sViewer 
            sViewer.Content = cc;

Hope it helps

XAML code is translated into C# code in a straightforward manner. Here is the snippet of the C# code that will create the above XAML:

var scrollViewer = new ScrollViewer
{
    HorizontalAlignment = HorizontalAlignment.Left,
    VerticalAlignment = VerticalAlignment.Top,
    Width = 480
};

var canvas = new Canvas
{
    Height = 1500
};

scrollViewer.Content = canvas;

for (var i = 1; i <= 5; ++i)
{
    var button = new Button
    {
        Width = 120,
        Height = 300
        Content = i.ToString()
    };
    Canvas.SetLeft(button, 10);
    Canvas.SetTop(button, (i - 1) * 100 + 10));
    canvas.Children.Add(button);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top