简体   繁体   中英

WP7 - Scrolling ListBox in external ScrollViewer

I have the following page layout in my application:

<Grid x:Name="ContentPanel"
      Grid.Row="1">

  <ScrollViewer x:Name="ScrollViewer1" 
                MaxHeight="600"
                VerticalAlignment="Top"
                HorizontalAlignment="Stretch">

    <StackPanel x:Name="StackPanel1" >
      <TextBlock x:Name="TextBlock1" />

      <toolkit:ListPicker  x:Name="ListPicker1" />

      <TextBlock x:Name="TextBlock2" />

      <TextBox x:Name="TextBlock3" />

      <TextBlock x:Name="TextBlock4" />

      <StackPanel x:Name="StackPanel2" >

        <TextBlock x:Name="TextBlock5" />

        <Image x:Name="Image1"/>

      </StackPanel>

      <ListBox x:Name="ListBox1">
        <!--Customize the ListBox template to remove the built-in ScrollViewer-->
        <ListBox.Template>
          <ControlTemplate>
            <ItemsPresenter />
          </ControlTemplate>
        </ListBox.Template>

        <ListBox.ItemTemplate>
          <DataTemplate>

            <!-- .... -->

          </DataTemplate>
        </ListBox.ItemTemplate>

        <ListBox.ItemContainerStyle>
          <Style TargetType="ListBoxItem">
            <Setter Property="HorizontalContentAlignment"
                    Value="Stretch" />
          </Style>
        </ListBox.ItemContainerStyle>
      </ListBox>

    </StackPanel>

  </ScrollViewer>

</Grid>

I added an external ScrollViewer instead of the using the ListBox 's because without it the stuff above the ListBox was taking too much room and not leaving enough space to view the ListBox contents.

Now, the problem is if I add an item to the end of the ListBox the ScrollIntoView method does not work. So I need to use the ScrollViewer 's ScrollToVerticalOffset method.

I'm adding the new item to an ObservableCollection that is bound to the ListBox when the user clicks a button on the application bar. How can I calculate the value to be passed to ScrollViewer.ScrollToVerticalOffset ?

Thanks for your help!

You can find the container that the ListBox has generated to host your element. Once you have this container, you can find its position relative to the scrollviewer:

  var newItem = // the item you just added to your listbox

  // find the ListBox container
  listBox.UpdateLayout()
  var element = listBox.ItemContainerGenerator.ContainerFromItem(newItem) as FrameworkElement;

  // find its position in the scroll viewer
  var transform = element.TransformToVisual(ScrollViewer);
  var elementLocation = transform.Transform(new Point(0, 0));
  double newVerticalOffset = elementLocation.Y + ScrollViewer.VerticalOffset;

  // scroll into view
  ScrollViewer.ScrollToVerticalOffset(newVerticalOffset);

Hope that helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM