Название: Исправление тряски и прыжков в пользовательской LoopPanel с помощью инерционной прокрутки и привязки к элементC#

Место общения программистов C#
Ответить
Anonymous
 Название: Исправление тряски и прыжков в пользовательской LoopPanel с помощью инерционной прокрутки и привязки к элемент

Сообщение Anonymous »

У меня есть специальная LoopPanel в WinUI, и я пытаюсь реализовать плавную инерционную прокрутку и функцию привязки к элементу.
Я реализовал обе функции, но наблюдаю странное поведение: панель трясется и подпрыгивает при завершении прокрутки. Это не тот плавный процесс, который мне нужен.
Я загрузил образец приложения, содержащий полный исходный код панели.
https://github.com/ghost1372/App10
Как исправить тряску и прыжки, сохраняя при этом функциональность инерционной прокрутки и привязки к элементам?
Изображение

Вот фрагмент того, что у меня есть на данный момент:

Код: Выделить всё

public class LoopPanel : Panel

{

private double _inertiaVelocity = 0;

private const double Deceleration = 0.95;

private bool _isInertiaActive = false;

private double _dragVelocity = 0;

private DateTime _lastDragTime;

private const double MinInertiaThreshold = 0.05;

private bool _isDragging = false;

private Point _lastDragPos;

public LoopPanel()

{

this.PointerWheelChanged += OnPointerWheelChanged;

this.PointerPressed += OnPointerPressed;

this.PointerMoved += OnPointerMoved;

this.PointerReleased += OnPointerReleased;

this.PointerCanceled += OnPointerCanceled;

}

private void OnPointerPressed(object sender, PointerRoutedEventArgs e)

{

_isDragging = true;

_lastDragTime = DateTime.Now;

_lastDragPos = e.GetCurrentPoint(this).Position;

CapturePointer(e.Pointer);

e.Handled = true;

}

private void OnPointerMoved(object sender, PointerRoutedEventArgs e)

{

if (!_isDragging) return;

Point current = e.GetCurrentPoint(this).Position;

double delta = Orientation == Orientation.Horizontal

? _lastDragPos.X - current.X

: _lastDragPos.Y - current.Y;

Scroll(delta * DragScrollFactor);

InvalidateArrange();

DateTime now = DateTime.Now;

double milliseconds = (now - _lastDragTime).TotalMilliseconds;

if (milliseconds > 0)

{

double v = delta / milliseconds * 16.6667;

_dragVelocity = _dragVelocity * 0.35 + v * 0.65;

}

_lastDragPos = current;

_lastDragTime = now;

e.Handled = true;

}

private void OnPointerReleased(object sender, PointerRoutedEventArgs e)

{

if (!_isDragging) return;

_isDragging = false;

ReleasePointerCapture(e.Pointer);

e.Handled = true;

if (IsInertiaEnabled && Math.Abs(_dragVelocity) > MinInertiaThreshold)

{

_inertiaVelocity = _dragVelocity;

StartInertia();

}

}

private void OnInertiaRendering(object sender, object e)

{

if (Math.Abs(_inertiaVelocity) <  MinInertiaThreshold)

{

_inertiaVelocity = 0;

DispatcherQueue.TryEnqueue(() =>

{

SnapToNearestChild();

});

StopInertia();

return;

}

Scroll(_inertiaVelocity);

InvalidateArrange();

_inertiaVelocity *= Deceleration;

}

private void SnapToNearestChild()

{

if (Children.Count == 0) return;

int nearest = (int)Math.Round(Offset);

Offset = nearest;

InvalidateArrange();

}

private void StartInertia()

{

if (_isInertiaActive) return;

_isInertiaActive = true;

CompositionTarget.Rendering += OnInertiaRendering;

}

private void StopInertia()

{

if (!_isInertiaActive) return;

_isInertiaActive = false;

CompositionTarget.Rendering -= OnInertiaRendering;

}

private void OnPointerCanceled(object sender, PointerRoutedEventArgs e)

{

if (!_isDragging) return;

_isDragging = false;

ReleasePointerCapture(e.Pointer);

e.Handled = true;

}

private void OnPointerWheelChanged(object sender, PointerRoutedEventArgs e)

{

var delta = e.GetCurrentPoint(this).Properties.MouseWheelDelta;

double scrollAmount = -delta * MouseWheelScrollFactor;

Scroll(scrollAmount);

InvalidateArrange();

if (IsInertiaEnabled)

{

_inertiaVelocity = scrollAmount;

StartInertia();

}

e.Handled = true;

}

}
Мы будем очень признательны за любые рекомендации или советы о том, как правильно реализовать плавную инерцию и привязку в пользовательской LoopPanel.

Подробнее здесь: https://stackoverflow.com/questions/798 ... olling-and
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»