views:

448

answers:

1

I have good model (I think!) for how to allow a user to drag an element in a stackpanel and reposition it to another location within the stackpanel.

However, my Stackpanel is placed within a ScrollViewer, like this (generalized):

<ScrollViewer>
   <StackPanel>
        ....First item
        ....Second item
        ....Third item
        ....Etc.
    </StackPanel>
<ScrollViewer>

Here is the problem, I wish to simulate the functionality of programs like word, where if I am dragging selected content (or an object) outside the viewable area, the window will scroll in the direction of the mouse to see more places to drop my nifty little object.

...i.e. If I move the mouse to the top of my ScrollViewer while dragging a stackpanel's contents, I want the scrollviewer to slowly move up so I can see more locations to drop my content.

Any suggestions?

If you can help me solve this, you will be a godsend!

A: 

No problem. Handle the DragOver routed event at the ScrollViewer level. Get the position. If it is near the top of the ScrollViewer bounds, scroll up. If it is near the bottom of the ScrollViewer bounds, scroll down.

The scrolling itself is done by calling scrollViewer.LineUp() or scrollViewer.LineDown().

The DragOver events come frequently, so save the value of DateTime.Now in a field each time you call LineUp() or LineDown(). Before calling them again, check DateTime.Now and if not enough time has elapsed, don't call LineUp() or LineDown().

For better control over scrolling speed you can use scrollViewer.ScrollToVerticalOffset(scrollViewer.ContentVerticalOffset + delta) instead of scrollViewer.LineUp() and scrollViewer.LineDown().

You can provide a better user experience if you allow faster scrolling when nearer to the top or bottom of the scroll viewer. This can be done by dividing the scroll area into zones, or calculating the speed from the mouse position. In this case, speed changes can be done by calling LineUp()/LineDown() multiple times when closer to the edge, or by increasing the delta value if you are using ScrollToVerticalOffset. You probably should not modify the timing (DateTime.Now comparison) for this purpose, because it will be unreliable.

Ray Burns
Awesome, I'll give that a try first thing tomorrow. Moving is a mindbender, though it's definitely coming together. Thanks!
Matt H.