Reputation: 505
I have a ListBox which uses a custom ScrollViewer (to provide fake "Touch" scrolling experience on a windows xp embedded touchpanel)
<ControlTemplate TargetType="{x:Type auc:DragSortableListView}">
<auc:DragScrollViewer ...>
<ItemsPresenter .../>
</auc:DragScrollViewer>
</ControlTemplate>
In that "DragScrollViewer" I use the IScrollInfo-Interface to perform scrolling which works well.
Plus I use UI virtualization because we have large amounts of data bound to the list view and the scrolling (when virtualization turned on) happens not pixel based, but index based as I figured out. That means that if I scroll to vertical offset 5 via IScrollInfo, it scrolls to the 5th item.
My problem is, that I don't know how to convert the pixel-based-mouse-offset (when the user moved the "mouse" 50pixel) to the item-count-based offset the IScrollInfo.SetVerticalOffset() expects (offset has been 3, an item is 10pixel => set offset to 8). It'd be easy if I knew the Item-Height, but I'm inside the ScrollViewer. How can the ScrollViewer possibly know if there's a ItemsPresenter down the visual tree, right? And what if the items have different height (which is not the case, but hypothetically)?
Any suggestions on how to solve that issue?
Upvotes: 3
Views: 738
Reputation: 12319
Have you had a look at this article?
The way I see it, he is storing the mouse offset in _Offset, then calling InvalidateArrange(), which might (just guessing here) in turn query the VerticalOffset property and handle the appropriate scrolling.
private Vector _Offset;
public double VerticalOffset { get { return _Offset.Y; } }
public void SetVerticalOffset(double offset)
{
offset = Math.Max(0, Math.Min(offset, ExtentHeight - ViewportHeight));
if (offset != _Offset.Y)
{
_Offset.Y = offset;
InvalidateArrange();
}
}
I suppose this would then never require you to actually transform your pixel offset into item count offset. If this is incorrect, please provide your IScrollInfo implementation.
Upvotes: 1