2025-08-20 12:10:35 +08:00
|
|
|
|
namespace NeoUI.Assists;
|
2025-08-12 23:08:54 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// ScrollViewerAssist 类提供附加属性,用于同步多个 ScrollViewer 控件的滚动位置。通过设置 SynchronizedScroll 附加属性,可以使得一个 ScrollViewer 的滚动变化时,其他关联的 ScrollViewer 也会自动进行相应的滚动。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <remarks>
|
|
|
|
|
|
/// 该类主要用于在 WPF 应用程序中实现多 ScrollViewer 之间的滚动同步功能,特别适用于需要同时滚动显示不同内容但保持视觉一致性的场景。
|
|
|
|
|
|
/// </remarks>
|
|
|
|
|
|
public class ScrollViewerAssist
|
|
|
|
|
|
{
|
2025-08-20 12:10:13 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取指定依赖对象的SynchronizedScroll属性值。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="obj">要获取SynchronizedScroll属性值的依赖对象。</param>
|
|
|
|
|
|
/// <returns>返回与指定依赖对象关联的ScrollViewer。如果未设置,则返回null。</returns>
|
2025-08-12 23:08:54 +08:00
|
|
|
|
public static ScrollViewer GetSynchronizedScroll(DependencyObject obj)
|
|
|
|
|
|
{
|
|
|
|
|
|
return (ScrollViewer)obj.GetValue(SynchronizedScrollProperty);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-20 12:10:13 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设置指定依赖对象的SynchronizedScroll属性值。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="obj">要设置SynchronizedScroll属性的依赖对象。</param>
|
|
|
|
|
|
/// <param name="value">要设置的ScrollViewer值,用于同步滚动位置。</param>
|
2025-08-12 23:08:54 +08:00
|
|
|
|
public static void SetSynchronizedScroll(DependencyObject obj, ScrollViewer value)
|
|
|
|
|
|
{
|
|
|
|
|
|
obj.SetValue(SynchronizedScrollProperty, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-20 12:10:13 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// SynchronizedScrollProperty 是一个依赖属性,用于在多个 ScrollViewer 控件之间同步滚动位置。通过此属性,可以设置或获取与特定依赖对象关联的 ScrollViewer 实例,从而实现当一个 ScrollViewer 的滚动位置发生变化时,其他关联的 ScrollViewer 也能自动调整其滚动位置以保持一致。
|
|
|
|
|
|
/// </summary>
|
2025-08-12 23:08:54 +08:00
|
|
|
|
public static readonly DependencyProperty SynchronizedScrollProperty =
|
|
|
|
|
|
DependencyProperty.RegisterAttached("SynchronizedScroll",
|
|
|
|
|
|
typeof(ScrollViewer), typeof(ScrollViewerAssist),
|
|
|
|
|
|
new PropertyMetadata(null, OnSynchronizedScrollChanged));
|
|
|
|
|
|
|
|
|
|
|
|
private static void OnSynchronizedScrollChanged(DependencyObject d,
|
|
|
|
|
|
DependencyPropertyChangedEventArgs e)
|
|
|
|
|
|
{
|
2025-08-20 12:10:13 +08:00
|
|
|
|
if (d is not ScrollViewer scroll)
|
2025-08-12 23:08:54 +08:00
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//从无到有
|
|
|
|
|
|
if (e.OldValue == null && e.NewValue != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
scroll.ScrollChanged += SynchronizeScrollViewer;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static void SynchronizeScrollViewer(object sender, ScrollChangedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var senderScroll = sender as ScrollViewer;
|
|
|
|
|
|
if (senderScroll == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//获取要被驱动的ScrollViewer
|
|
|
|
|
|
var targetScroll = GetSynchronizedScroll(senderScroll);
|
|
|
|
|
|
targetScroll.ScrollToHorizontalOffset(senderScroll.HorizontalOffset);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|