Ok, c'est un vraiment vieille question, mais je pensais que je partage pour la postérité, depuis que je suis résolu ce problème un moi-même. La meilleure solution que j'ai trouvée est de créer un contrôle utilisateur qui dérive de la classe ScrollView et implémente les propriétés que vous voulez - qui sont bien sûr liées aux propriétés non-bindable de la classe de base.
Vous pouvez utiliser la fonction OnPropertyChanged pour surveiller ces propriétés et conserver les valeurs en synchronisation.
Voici le code complet de mon contrôle personnalisé appelé DynamicScrollViewer. Notez que j'ai quatre propriétés de dépendance liable appelées DynamicHorizontalOffset, DynamicVerticalOffset, DynamicViewportWidth et DynamicViewportHeight.
Les deux propriétés de décalage autorisent à la fois le contrôle en lecture et en écriture du décalage, tandis que les propriétés de la fenêtre d'affichage sont essentiellement en lecture seule.
Je devais utiliser cette classe lors de la création d'un contrôle d'éditeur d'animation complexe dans lequel différents composants (étiquettes à gauche, nœuds au milieu, timeline en haut) devaient défiler de manière synchrone, mais seulement de manière limitée. lié aux barres de défilement externes communes. Pensez à verrouiller une section de lignes dans une feuille de calcul, et vous obtenez l'idée.
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;
}
}
}
}