Tim
Tim

Reputation: 1769

ScrollViewer and ScrollToVerticalOffset with mvvm

I would like to use the ScrollToVerticalOffset method of a ScrollViewer to go to the top of the scrollviewer.

But with a MVVM approch.

I think I have to create a dependency property to take this behavior.

EDIT : The behavior is :

public class ScrollPositionBehavior : Behavior<FrameworkElement>
{
    public double Position
    {
        get { return (double)GetValue(PositionProperty); }
        set { SetValue(PositionProperty, value); }
    }

    public static readonly DependencyProperty PositionProperty = DependencyProperty.Register("Position", typeof(double), typeof(ScrollPositionBehavior), new PropertyMetadata((double)0, new PropertyChangedCallback(OnPositionChanged)));

    protected override void OnAttached()
    {
        base.OnAttached();
    }

    private static void OnPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ScrollPositionBehavior behavior = d as ScrollPositionBehavior;
        double value = (double)e.NewValue;
        ((ScrollViewer)(behavior.AssociatedObject)).ScrollToVerticalOffset(value);
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
    }
}

used like :

    <ScrollViewer>
        <Interactivity:Interaction.Behaviors>
            <fxBehavior:ScrollPositionBehavior Position="{Binding Position}" />
        </Interactivity:Interaction.Behaviors>
        <other things ...>
    </ScrollViewer>

with

xmlns:Interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:fxBehavior="clr-namespace:MyNamespace.Behavior;assembly=MyAssembly"

I have a parser xaml exception :

this is a : AG_E_PARSER_BAD_PROPERTY_VALUE

Note that i'm using the behavior based on a FrameworkElement, as I'm using silverlight 3 (in fact, this is SL for WP7). I've seen that the binding should work only for FrameworkElement.

Thanks in advance for your help

Upvotes: 1

Views: 3145

Answers (1)

robertos
robertos

Reputation: 1796

You were on the right way. First of all you need to change your OnPositionChanged method to find out which instance of the behavior had its Position changed:

private static void OnPositionChanged(DependencyObject d,
                                      DependencyPropertyChangedEventArgs e)
{
    ScrollPositionBehavior behavior = d as ScrollPositionBehavior;
    double value = (double)e.NewValue;
    behavior.AssociatedObject.ScrollToVerticalOffset(value);
}

Then, you'll get the ScrollViewer as associated object when you attach the behavior to it:

<ScrollViewer>
    <i:Interaction.Behaviors>
        <my:ScrollPositionBehavior Position="{what you need, e.g. Binding}" />
    </i:Interaction.Behaviors>
</ScrollViewer>

Note that if you use a Binding it can be a OneWay binding, because the Position will never get updated by the behavior itself.

Upvotes: 1

Related Questions