locked
ListView jiggles horizontally when large item about to scroll in or out in Windows Phone 8.1 Preview RRS feed

  • Question

  • If you have a ListView (in a Windows Phone 8.1 Store app, running on the developer preview 8.10.123979.895) in which you do not explicitly constrain the size of your list view's item template (e.g., because you'd like it to resize automatically when the screen is rotated, or to adapt well to larger screen sizes), a problem arises if some of the items in your list want to be wider than the screen. They are correctly cropped, but as you scroll down through the list, the whole list jiggles left and right as the long item is about to scroll into view, or shortly after it has scrolled out of view.

    The built-in Calendar app suffers from this problem, by the way, so even if it's possible to avoid this in my own app, the Calendar app needs fixing... If you create a large number of appointments on a single day, where most of the appointments have short names, but one has a long name, and you then tap the day to expand its list of appointments for that day, you'll see this jiggling from left to right as you scroll through the appointments.

    Here's some code that reproduces the problem:

    XAML:

    <Page
        x:Class="Wp81ScrollBug.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    
        <Grid>
            <ListView
                x:Name="myList">
            </ListView>
        </Grid>
    </Page>
    

    Codehind for that:

    using System.Linq;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Navigation;
    
    namespace Wp81ScrollBug
    {
        public sealed partial class MainPage : Page
        {
            private string[] _source =
                Enumerable.Range(1, 80).Select(i => "Short " + i)
                    .Concat(new[] { "This item is much longer than the rest and causes problems as virtualization adds and removes it" })
                    .Concat(Enumerable.Range(81, 80).Select(i => "Short " + i)).ToArray();
            public MainPage()
            {
                InitializeComponent();
                NavigationCacheMode = NavigationCacheMode.Required;
    
                myList.ItemsSource = _source;
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
            }
        }
    }
    

    You can get rid of the problem by adding this inside the ListView:

                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ContentControl Width="480" Content="{Binding}" />
                    </DataTemplate>
                </ListView.ItemTemplate>
    

    but this is unsatisfactory, because it no longer handles orientation changes or different screen sizes - when you rotate the screen, the long item doesn't get to use the whole width.

    • Moved by Bryce B, Monday, June 23, 2014 10:46 PM Wrong forum
    Monday, June 23, 2014 1:31 PM

Answers

  • My solution to the problem was to bind the width of the Item Template to the ActualWidth of the container holding the ListView:

    <Grid x:name="contentRoot" Margin="19,9.5,19,0"> <ListView> <ListView.ItemTemplate> <DataTemplate>

    <Grid Width={Binding ActualWidth, ElementName=contentRoot} />

    </DataTemplate>

    </ListView.ItemTemplate> </ListView> </Grid>

    Hopefully they find non-hacky solution to the issue soon.

    • Marked as answer by IanG Wednesday, June 25, 2014 7:02 AM
    Wednesday, June 25, 2014 4:03 AM

All replies

  • The Jiggle is due to virtualization and an attempt to fit the contents.  The only solution I can think of is to set the width based on the orientation.

    Jeff Sanders (MSFT)

    @jsandersrocks - Windows Store Developer Solutions @WSDevSol
    Getting Started With Windows Azure Mobile Services development? Click here
    Getting Started With Windows Phone or Store app development? Click here
    My Team Blog: Windows Store & Phone Developer Solutions
    My Blog: Http Client Protocol Issues (and other fun stuff I support)

    Tuesday, June 24, 2014 12:25 PM
  • So are you saying that this is by-design? (And have you told the team that owns the built-in Calendar app, given that they seem to have run into this too, but apparently haven't noticed yet?)

    After posting my original message, I tried modifying my app so that the item template has a width bound to an object that implements INotifyPropertyChanged, and which provides a single property which returns the current screen width (with notifications when that changes, to handle device orientation changes). This seems to work. (It's not quite what you suggested - it's not a fixed width because that wouldn't cope with the variation in screen sizes - there are both 15:9 and 16:9 devices out there.)

    This is still a little unsatisfactory because a ListView won't necessarily be filling the whole screen width - if you have margins then you need to work out for yourself how to adjust the value returned by this screen width source, rather than just relying on the layout system. But it's usable as a workaround.

    Tuesday, June 24, 2014 3:07 PM
  • My solution to the problem was to bind the width of the Item Template to the ActualWidth of the container holding the ListView:

    <Grid x:name="contentRoot" Margin="19,9.5,19,0"> <ListView> <ListView.ItemTemplate> <DataTemplate>

    <Grid Width={Binding ActualWidth, ElementName=contentRoot} />

    </DataTemplate>

    </ListView.ItemTemplate> </ListView> </Grid>

    Hopefully they find non-hacky solution to the issue soon.

    • Marked as answer by IanG Wednesday, June 25, 2014 7:02 AM
    Wednesday, June 25, 2014 4:03 AM
  • Thanks for the work-around, better that nothing...

    I hope they'll fix this as soon as possible!

    Sunday, July 20, 2014 12:04 PM
  • I know this is an old thread. But this problem hasn't been fixed even in the most updated version of windows (phone) 8.1! The 'bind width to root container' does work however I have issues with refreshing contents when some items turn up blank. Can anyone provide a proper fix for this jiggle issue? Will this be resolved in Windows 10?
    Saturday, March 21, 2015 5:52 AM
  • I know this is an old thread. But this problem hasn't been fixed even in the most updated version of windows (phone) 8.1! The 'bind width to root container' does work however I have issues with refreshing contents when some items turn up blank. Can anyone provide a proper fix for this jiggle issue? Will this be resolved in Windows 10?

    I'm experiencing this exact same problem inside a Windows Phone 8.1 Runtime App.

    It's very annoying and even a little bit surprising...

    Is there some kind of working solution?

    Will this issue be resolved in Windows 10?



    Tuesday, March 31, 2015 10:20 AM