Windows Phone 7 - ScrollViewer value changed

2019-05-11 19:05发布

问题:

I am searching all the time for solution and cant get correct one. I have grid that have width 960 and have ScrollViewer in it. Now i would like to know value (horizontal offset) of my scroll while scrolling. All solutions that i am finding is for wpf/silverlight and it wont works for me.

Edit

Ok, here is the example code, xaml:

<ScrollViewer Name="Scroll" LayoutUpdated="ScrollViewer_LayoutUpdated" IsEnabled="True" Width="480" ScrollViewer.HorizontalScrollBarVisibility="Auto">
    <Grid x:Name="ContentPanel" Background="Red" Margin="12,0,12,0" Width="960">
        <Rectangle Name="GreenRectangle" Fill="Green" Width="240" Height="240"></Rectangle>
    </Grid>
</ScrollViewer>

c#

private void ScrollViewer_LayoutUpdated(object sender, EventArgs e)
{
    GreenRectangle.Width = Scroll.HorizontalOffset;
    GreenRectangle.Height = Scroll.HorizontalOffset;
}

But the problem is that it is not changing size all the time. Maybe my English is not well and you cant uderstand me. Here is movie example, i am sliding left right and the size is always the same. When i stop sliding it is changing size.

https://www.dropbox.com/s/eh28oavxpsy19bw/20130122_1601_56.avi

回答1:

It is possible by using the scrollviewers dependency properties, it has a HorizontalOffset and a VerticalOffset. The trick is to bind event to the scrollviewer, but it can bee done in the load event handler. If you put a wide grid in your scrollviewer you can get the offset!

In your xaml file (MainPage sample here):

        <ScrollViewer Loaded="ScrollViewer_Loaded_1">
        <Grid x:Name="ContentPanel" Grid.Row="1" Width="1000" Margin="12,0,12,0">
            <StackPanel>
                ...

In your code behind file (MainPage.cs here):

        public static readonly DependencyProperty ScrollViewVerticalOffsetProperty =
        DependencyProperty.Register(
                                    "ScrollViewVerticalOffset",
                                    typeof(double),
                                    typeof(MainPage),
                                    new PropertyMetadata(new PropertyChangedCallback(OnScrollViewVerticalOffsetChanged))
                                    );

        public static readonly DependencyProperty ScrollViewHorizontalOffsetProperty =
        DependencyProperty.Register(
                                    "ScrollViewHorizontalOffset",
                                    typeof(double),
                                    typeof(MainPage),
                                    new PropertyMetadata(new PropertyChangedCallback(OnScollViewHorizontalOffsetChanged))
                                    );

    private ScrollViewer _listScrollViewer;

    private void ScrollViewer_Loaded_1(object sender, RoutedEventArgs e)
    {
        _listScrollViewer = sender as ScrollViewer;

        Binding binding1 = new Binding();
        binding1.Source = _listScrollViewer;
        binding1.Path = new PropertyPath("VerticalOffset");
        binding1.Mode = BindingMode.OneWay;
        this.SetBinding(ScrollViewVerticalOffsetProperty, binding1);

        Binding binding2 = new Binding();
        binding2.Source = _listScrollViewer;
        binding2.Path = new PropertyPath("HorizontalOffset");
        binding2.Mode = BindingMode.OneWay;
        this.SetBinding(ScrollViewHorizontalOffsetProperty, binding2);
    }

    public double ScrollViewVerticalOffset
    {
        get { return (double)this.GetValue(ScrollViewVerticalOffsetProperty); }
        set { this.SetValue(ScrollViewVerticalOffsetProperty, value); }
    }

    public double ScrollViewHorizontalOffset
    {
        get { return (double)this.GetValue(ScrollViewHorizontalOffsetProperty); }
        set { this.SetValue(ScrollViewHorizontalOffsetProperty, value); }
    }

    private static void OnScrollViewVerticalOffsetChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        MainPage page = obj as MainPage;
        ScrollViewer viewer = page._listScrollViewer;

        // ... do something here
    }

    private static void OnScollViewHorizontalOffsetChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        MainPage page = obj as MainPage;
        ScrollViewer viewer = page._listScrollViewer;

        // ... do something here
    }


回答2:

here's the XAML code I used

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" LayoutUpdated='ContentPanel_LayoutUpdated'>

        <ScrollViewer x:Name='scroller' VerticalAlignment='Stretch' VerticalScrollBarVisibility='Visible' >
            <StackPanel
                x:Name='listItems'></StackPanel>
        </ScrollViewer>
    </Grid>

and here's the C# code behind

private void ContentPanel_LayoutUpdated(object sender, EventArgs e)
    {
        var offset = scroller.VerticalOffset;
    }

whenever the scroller is scrolled then the layout of the Grid (Container grid) changes so layout updated event is fired ... please try debugging by placing break point inside the event and look for the offset value ..



回答3:

Add the property ManipulationMode="Control" to your ScrollViewer. This is needed because otherwise the UI thread will not be notified with enough ScrollViewer scroll values to get a fluid animation – the normal mode is a performance optimization from Windows Phone that you need to bypass!