locked
Multiple ListView or GridView sharing the same ScrollView RRS feed

  • Question

  • I Have 2 ListView with 2 diferent DataSources but need to give the user the experience of using one single list.

    To do that, i need that both Lists share a single ScrollArea.

    I managed to do that by using

    <ScrollViewer VerticalScrollMode="Auto">
     <StackPanel x:Name="ListGroup">
      <ListView x:Name="list1" ... />
      <ListView x:Name="list2" ... />
     </StackPanel>
    </ScrollViewer>
    

    But when i put the mouse over an item and try to scroll with the mouse, the scroll area doesnt move.

    Do i have to use ScrollViewer.IsVerticalScrollChainingEnabled="true" on all ScrollViewer Childs to manage this?

    How this property works?

    Thanks!

    Thursday, July 12, 2012 3:13 PM

Answers

  • Unfortunately the ListView/GridView does not bubble its pointer/MouseWheel event to allow this scenario to work without some workaround code on your part. If you do not need the ability to touch swipe to select you can create a new ListView template (using Blend is the easiest way) and remove the ScrollViewer from the template. You could optionally attempt to "forward" the mouse wheel message yourself. Note It is noticeably different because there’s no inertia for the workaround mouse-wheeling, but it might be a doable workaround if you need the ability to cross slide and mouse scrolling.
     
    1)      Call this on the element at the root of your main ScrollViewer

    // AddHandler has the nifty side effect of letting you see events that were Handled below you in the tree.             
    AnyControlAtTheRoot.AddHandler(PointerWheelChangedEvent, new PointerEventHandler(Bubble_PointerWheelChanged), true);

    2)      In the handler do something like this:

            private void Bubble_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
            {
                // Could walk up the tree to find the next SV or just have a reference like here:
                ScrollViewerToDrive.ScrollToHorizontalOffset(ScrollViewerToDrive.HorizontalOffset - e.GetCurrentPoint(null).Properties.MouseWheelDelta);
            }

    -mark
    Program Manager
    Microsoft
    This post is provided "as-is"

    Friday, July 13, 2012 1:01 AM
  • Hi

    Is the parent of your ScrollViewer a StackPanel ? If so the issue you are seeing can be attribute to an oddity in the layout process. Try changing the parent of the ScrollViewer to a Grid.

    Scrolling will not work for the below scenario where the parent of the ScrollViewer is a StackPanel

      <StackPanel Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <ScrollViewer>
                <StackPanel>
                    <ListView x:Name="ListView1" Background="Blue"></ListView>
                    <ListView x:Name="ListView2" Background="Violet"></ListView>
                </StackPanel>
            </ScrollViewer>
        </StackPanel>

    Scrolling will work if you change the parent of the Scroll Viewer to a Grid as shown below

        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <ScrollViewer>
                <StackPanel>
                    <ListView x:Name="ListView1" Background="Blue"></ListView>
                    <ListView x:Name="ListView2" Background="Violet"></ListView>
                </StackPanel>
            </ScrollViewer>
        </Grid>

    Hope this helps.

    Thanks.


    Thursday, July 12, 2012 11:04 PM

All replies

  • Hi,

    The behavior you trying to produce is the Panning . To emulate that behavior you can, start your application in the Simulator and select the setting "Basic Touch Mode" to pan through the list using touch. With mouse, the behavior that can be generated is click / selection. If you want to scroll using mouse, then you can use the portions of the scroll-bar to pan through the list. Detailed information at http://msdn.microsoft.com/en-us/library/windows/apps/hh465310.aspx

    -Sagar

    Thursday, July 12, 2012 5:48 PM
  • Can you please send me the complete Xaml. I am specially interested in the parent of the ScrollViewer. I had a similar problem and it turned out be an oddity with the layout. I have a few ideas, if you can give more Xaml, it would be great.
    Thursday, July 12, 2012 6:24 PM
  • Hi

    Is the parent of your ScrollViewer a StackPanel ? If so the issue you are seeing can be attribute to an oddity in the layout process. Try changing the parent of the ScrollViewer to a Grid.

    Scrolling will not work for the below scenario where the parent of the ScrollViewer is a StackPanel

      <StackPanel Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <ScrollViewer>
                <StackPanel>
                    <ListView x:Name="ListView1" Background="Blue"></ListView>
                    <ListView x:Name="ListView2" Background="Violet"></ListView>
                </StackPanel>
            </ScrollViewer>
        </StackPanel>

    Scrolling will work if you change the parent of the Scroll Viewer to a Grid as shown below

        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <ScrollViewer>
                <StackPanel>
                    <ListView x:Name="ListView1" Background="Blue"></ListView>
                    <ListView x:Name="ListView2" Background="Violet"></ListView>
                </StackPanel>
            </ScrollViewer>
        </Grid>

    Hope this helps.

    Thanks.


    Thursday, July 12, 2012 11:04 PM
  • Unfortunately the ListView/GridView does not bubble its pointer/MouseWheel event to allow this scenario to work without some workaround code on your part. If you do not need the ability to touch swipe to select you can create a new ListView template (using Blend is the easiest way) and remove the ScrollViewer from the template. You could optionally attempt to "forward" the mouse wheel message yourself. Note It is noticeably different because there’s no inertia for the workaround mouse-wheeling, but it might be a doable workaround if you need the ability to cross slide and mouse scrolling.
     
    1)      Call this on the element at the root of your main ScrollViewer

    // AddHandler has the nifty side effect of letting you see events that were Handled below you in the tree.             
    AnyControlAtTheRoot.AddHandler(PointerWheelChangedEvent, new PointerEventHandler(Bubble_PointerWheelChanged), true);

    2)      In the handler do something like this:

            private void Bubble_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
            {
                // Could walk up the tree to find the next SV or just have a reference like here:
                ScrollViewerToDrive.ScrollToHorizontalOffset(ScrollViewerToDrive.HorizontalOffset - e.GetCurrentPoint(null).Properties.MouseWheelDelta);
            }

    -mark
    Program Manager
    Microsoft
    This post is provided "as-is"

    Friday, July 13, 2012 1:01 AM
  • I found an interesting post about ScrollView conflicts that solves my problem:

    The ScrollViewer in WinRT does work out of the box with the mouse wheel. However, in your scenario there are really two ScrollViewers, the one you created and the one inside the GridView template. These two conflict.

    To solve this problem, I removed the ScrollViewer from the GridView template as follows:

    <GridView.Template>
        <ControlTemplate>
            <ItemsPresenter />
        </ControlTemplate>
    </GridView.Template>

    http://stackoverflow.com/questions/9655992/how-can-i-make-a-windows-8-metro-scrollviewer-respond-to-mousewheel/10305608#10305608

    • Proposed as answer by sperniner Saturday, December 29, 2012 11:45 PM
    Wednesday, August 22, 2012 8:24 PM
  • This is THE answer for the GridView scenario. Much more elegant.  Nice find Icaldoncelli.
    Saturday, December 29, 2012 11:46 PM
  • Very good find! That solved it for me as well!
    Tuesday, April 23, 2013 8:41 AM