3

カスタム ScrollViewer を使用する ListBox があります (Windows XP 埋め込みタッチパネルで偽の「タッチ」スクロール エクスペリエンスを提供するため)。

<ControlTemplate TargetType="{x:Type auc:DragSortableListView}">
    <auc:DragScrollViewer ...>
        <ItemsPresenter .../>
    </auc:DragScrollViewer>
</ControlTemplate>

その「DragScrollViewer」では、うまく機能するスクロールを実行するために IScrollInfo-Interface を使用します。

さらに、リスト ビューにバインドされた大量のデータがあり、スクロール (仮想化がオンになっている場合) がピクセル ベースではなくインデックス ベースで行われるため、UI 仮想化を使用します。つまり、IScrollInfo を介して垂直オフセット 5 までスクロールすると、5 番目の項目までスクロールします。

私の問題は、ピクセルベースのマウスオフセット(ユーザーが「マウス」を50ピクセル移動したとき)を、IScrollInfo.SetVerticalOffset()が期待するアイテムカウントベースのオフセットに変換する方法がわからないことです(オフセットは3 だった場合、アイテムは 10 ピクセル => オフセットを 8 に設定)。Item-Height を知っていれば簡単ですが、私は ScrollViewer の中にいます。ScrollViewer は、ビジュアル ツリーの下に ItemsPresenter があるかどうかをどうやって知ることができるのでしょうか? また、アイテムの高さが異なる場合はどうなりますか (実際にはそうではありませんが、仮説として)?

その問題を解決する方法について何か提案はありますか?

4

1 に答える 1

1

この記事をご覧になりましたか?

私の見方では、彼はマウス オフセットを _Offset に保存してから、InvalidateArrange() を呼び出しています。これにより、(ここでは推測ですが) VerticalOffset プロパティが照会され、適切なスクロールが処理される可能性があります。

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();
  }
}

これにより、実際にピクセルオフセットをアイテムカウントオフセットに変換する必要がなくなると思います。これが正しくない場合は、IScrollInfo の実装を提供してください。

于 2013-02-19T15:52:34.310 に答える