さて、これは本当に古い質問ですが、私はこれを自分で解決したので、後世のために共有したいと思いました。私が見つけた最善の解決策は、ScrollViewクラスから派生し、必要なプロパティを実装するユーザーコントロールを作成することです。もちろん、これらは基本クラスのバインド不可能なプロパティにリンクされています。
OnPropertyChanged関数を使用して、これらのプロパティを監視し、値の同期を維持できます。
これが、DynamicScrollViewerと呼ばれるカスタムユーザーコントロールの完全なコードビハインドです。DynamicHorizontalOffset、DynamicVerticalOffset、DynamicViewportWidth、およびDynamicViewportHeightという4つのバインド可能な依存関係プロパティがあることに注意してください。
2つのオフセットプロパティを使用すると、オフセットの読み取りと書き込みの両方を制御できますが、ビューポートプロパティは基本的に読み取り専用です。
さまざまなコンポーネント(左側のラベル、中央のノード、上部のタイムライン)が同期的にスクロールする必要がある複雑なアニメーションエディタコントロールを作成するときにこのクラスを使用する必要がありましたが、限られた側面でのみ、すべて共通の外部にバインドされていましたスクロールバー。スプレッドシートの行のセクションをロックすることを考えてみてください。そうすれば、そのアイデアが得られます。
using System.Windows;
using System.Windows.Controls;
namespace CustomControls
{
public partial class DynamicScrollViewer : ScrollViewer
{
public DynamicScrollViewer()
{
InitializeComponent();
}
public double DynamicHorizontalOffset
{
get { return (double)GetValue(DynamicHorizontalOffsetProperty); }
set { SetValue(DynamicHorizontalOffsetProperty, value); }
}
public static readonly DependencyProperty DynamicHorizontalOffsetProperty =
DependencyProperty.Register("DynamicHorizontalOffset", typeof(double), typeof(DynamicScrollViewer));
public double DynamicVerticalOffset
{
get { return (double)GetValue(DynamicVerticalOffsetProperty); }
set { SetValue(DynamicVerticalOffsetProperty, value); }
}
public static readonly DependencyProperty DynamicVerticalOffsetProperty =
DependencyProperty.Register("DynamicVerticalOffset", typeof(double), typeof(DynamicScrollViewer));
public double DynamicViewportWidth
{
get { return (double)GetValue(DynamicViewportWidthProperty); }
set { SetValue(DynamicViewportWidthProperty, value); }
}
public static readonly DependencyProperty DynamicViewportWidthProperty =
DependencyProperty.Register("DynamicViewportWidth", typeof(double), typeof(DynamicScrollViewer));
public double DynamicViewportHeight
{
get { return (double)GetValue(DynamicViewportHeightProperty); }
set { SetValue(DynamicViewportHeightProperty, value); }
}
public static readonly DependencyProperty DynamicViewportHeightProperty =
DependencyProperty.Register("DynamicViewportHeight", typeof(double), typeof(DynamicScrollViewer));
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == DynamicVerticalOffsetProperty)
{
if (ScrollInfo != null)
ScrollInfo.SetVerticalOffset(DynamicVerticalOffset);
}
else if (e.Property == DynamicHorizontalOffsetProperty)
{
if (ScrollInfo != null)
ScrollInfo.SetHorizontalOffset(DynamicHorizontalOffset);
}
else if (e.Property == HorizontalOffsetProperty)
{
DynamicHorizontalOffset = (double)e.NewValue;
}
else if (e.Property == VerticalOffsetProperty)
{
DynamicVerticalOffset = (double)e.NewValue;
}
else if (e.Property == ViewportWidthProperty)
{
DynamicViewportWidth = (double)e.NewValue;
}
else if (e.Property == ViewportHeightProperty)
{
DynamicViewportHeight = (double)e.NewValue;
}
}
}
}