مقدار التمرير Wpf ScrollViewer
-
08-07-2019 - |
سؤال
هل من الممكن تغيير المقدار الذي يقوم WPF ScrollViewer بتمريره؟أنا أتساءل ببساطة عما إذا كان من الممكن تغيير عارض التمرير بحيث يمكن تغيير مقدار التمرير المتزايد عند استخدام عجلة الماوس أو أسهم عارض التمرير.
المحلول
والجواب القصير هو: لا توجد وسيلة للقيام بذلك دون كتابة بعض الرموز التمرير العرف، ولكن لا تدع هذا يخيف لكم انه ليس كل ما من الصعب
.ووScrollViewer إما يعمل عن طريق التمرير باستخدام وحدات المادية (أي بكسل) أو من خلال الانخراط مع تنفيذ IScrollInfo لاستخدام الوحدات المنطقية. يتم التحكم بذلك عن طريق إعداد الممتلكات CanContentScroll و> حيث قيمة وسائل كاذبة "انتقل إلى المحتوى باستخدام وحدات مادية" وقيمة وسائل الحقيقية "تمرير المحتوى منطقيا".
وهكذا كيف يمكن للScrollViewer تمرير المحتوى منطقيا؟ من خلال التواصل مع تنفيذ IScrollInfo. ولهذا كيف يمكن أن تولي بالضبط كم محتوى مخطوطات لوحة الخاص بك عندما يقوم شخص ما عمل منطقي. نلقي نظرة على وثائق IScrollInfo أ > للحصول على قائمة من كافة الوحدات المنطقية من القياس التي يمكن طلبها للتمرير، ولكن بما أنك ذكرت عجلة الماوس عليك أن تكون في الغالب ترغب في MouseWheelUp / أسفل / يسار / يمين الطرق.
نصائح أخرى
وهنا بسيطة وكاملة والعمل WPF ScrollViewer
فئة تحتوي على بيانات قابلة للربط SpeedFactor
خاصية ضبط حساسية عجلة الماوس.جلسة SpeedFactor
إلى 1.0 يعني السلوك المطابق لـ WPF ScrollViewer
.القيمة الافتراضية لخاصية التبعية هي 2.5, ، مما يسمح بتمرير العجلة بسرعة كبيرة.
بالطبع، يمكنك أيضًا إنشاء ميزات إضافية مفيدة عن طريق الارتباط بـ SpeedFactor
الخاصية نفسها، أي للسماح للمستخدم بالتحكم في المضاعف بسهولة.
public class WheelSpeedScrollViewer : ScrollViewer
{
public static readonly DependencyProperty SpeedFactorProperty =
DependencyProperty.Register(nameof(SpeedFactor),
typeof(Double),
typeof(WheelSpeedScrollViewer),
new PropertyMetadata(2.5));
public Double SpeedFactor
{
get { return (Double)GetValue(SpeedFactorProperty); }
set { SetValue(SpeedFactorProperty, value); }
}
protected override void OnPreviewMouseWheel(MouseWheelEventArgs e)
{
if (!e.Handled &&
ScrollInfo is ScrollContentPresenter scp &&
ComputedVerticalScrollBarVisibility == Visibility.Visible)
{
scp.SetVerticalOffset(VerticalOffset - e.Delta * SpeedFactor);
e.Handled = true;
}
}
};
عرض XAML الكامل لـ "التمرير السريع بعجلة الماوس" لحوالي 3200 عنصر بيانات:
<UserControl x:Class="RemoveDuplicateTextLines.FastScrollDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyApp"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<local:WheelSpeedScrollViewer VerticalScrollBarVisibility="Auto">
<ListBox ItemsSource="{Binding Source={x:Type sys:Object},Path=Assembly.DefinedTypes}" />
</local:WheelSpeedScrollViewer>
</UserControl>
عجلة الفأرة السريعة:
هل يمكن تنفيذ السلوك على scrollviewer. في حالتي CanContentScroll
لم تنجح. الحل أدناه يعمل من أجل التمرير مع عجلة الماوس، فضلا عن draging شريط التمرير.
public class StepSizeBehavior : Behavior<ScrollViewer>
{
public int StepSize { get; set; }
#region Attach & Detach
protected override void OnAttached()
{
CheckHeightModulesStepSize();
AssociatedObject.ScrollChanged += AssociatedObject_ScrollChanged;
base.OnAttached();
}
protected override void OnDetaching()
{
AssociatedObject.ScrollChanged -= AssociatedObject_ScrollChanged;
base.OnDetaching();
}
#endregion
[Conditional("DEBUG")]
private void CheckHeightModulesStepSize()
{
var height = AssociatedObject.Height;
var remainder = height%StepSize;
if (remainder > 0)
{
throw new ArgumentException($"{nameof(StepSize)} should be set to a value by which the height van be divised without a remainder.");
}
}
private void AssociatedObject_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
const double stepSize = 62;
var scrollViewer = (ScrollViewer)sender;
var steps = Math.Round(scrollViewer.VerticalOffset / stepSize, 0);
var scrollPosition = steps * stepSize;
if (scrollPosition >= scrollViewer.ScrollableHeight)
{
scrollViewer.ScrollToBottom();
return;
}
scrollViewer.ScrollToVerticalOffset(scrollPosition);
}
}
هل استخدام مثل هذا:
<ScrollViewer MaxHeight="248"
VerticalScrollBarVisibility="Auto">
<i:Interaction.Behaviors>
<behaviors:StepSizeBehavior StepSize="62" />
</i:Interaction.Behaviors>
وأنا لم هذا لضمان الأعداد الصحيحة على scrollbar1.ValueChanged:
scrollbar1.Value = Math.Round(scrollbar1.Value, 0, MidpointRounding.AwayFromZero)