Reputation: 37
I made a class named "AniScrollViewer," it can set the vertical scroll offset
to animate Scrollviewer code-behind.
public class AniScrollViewer : ScrollViewer {
public static readonly DependencyProperty CurrentVerticalOffsetProperty =
DependencyProperty.Register("CurrentVerticalOffset", typeof(double), typeof(AniScrollViewer),
new PropertyMetadata(new PropertyChangedCallback(OnVerticalChanged)));
public double CurrentVerticalOffset {
get { return (double)GetValue(CurrentVerticalOffsetProperty); }
set { SetValue(CurrentVerticalOffsetProperty, value); }
}
private static void OnVerticalChanged(DependencyObject property, DependencyPropertyChangedEventArgs e) {
AniScrollViewer viewer = property as AniScrollViewer;
viewer.ScrollToVerticalOffset((double)e.NewValue);
}
}
I want to push this 'AniScrollViewer' into a Listbox
I meet couple of problems:
Listbox listbox (this is already definded in XAML)
AniScrollViewer scrollviewer = listbox.~~~~;
Please help.
Upvotes: 1
Views: 2191
Reputation: 17380
ScrollViewer
with a custom one, Define a custom Style
for the ListBox
and in the ControlTemplate
switch out the default ScrollViewer
with your one(local:AniScrollViewer
). Now any ListBox
using this Style
will have your ScrollViewer
. Default ControlTemplate
and Style
can be found HereScrollViewer
in the code-behind, you can use this as a reference. In the function GetScrollViewer(DependencyObject o)
check it to be type safe with your custom ScrollViewer
such as
if (o is AniScrollViewer)
return o;
Alternate
However in your case, am not sure why your opting to subclass the ScrollViewer
for this. Instead of the hassle of this with defining your own ListBox
ControlTemplate
, maybe try using an attached property. Something like:
public class ScrollAnimator {
public static readonly DependencyProperty ScrollToProperty =
DependencyProperty.RegisterAttached(
"ScrollTo",
typeof(double),
typeof(ScrollAnimator),
new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.None, ScrollToChangedCallback));
private static void ScrollToChangedCallback(
DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) {
ScrollViewer viewer = GetScrollViewer(dependencyObject) as ScrollViewer;
if (viewer != null)
viewer.ScrollToVerticalOffset((double)dependencyPropertyChangedEventArgs.NewValue);
// Modify Above code to however you want to do the animation.
}
public static DependencyObject GetScrollViewer(DependencyObject o) {
if (o is ScrollViewer)
return o;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++) {
var child = VisualTreeHelper.GetChild(o, i);
var result = GetScrollViewer(child);
if (result == null)
continue;
return result;
}
return null;
}
public static void SetScrollTo(UIElement element, Orientation value) {
element.SetValue(ScrollToProperty, value);
}
public static Orientation GetScrollTo(UIElement element) {
return (Orientation)element.GetValue(ScrollToProperty);
}
}
and usage:
<ListBox ItemsSource="{Binding Items}"
local:ScrollAnimator.ScrollTo="{Binding ScrollTo}" />
This way you don't have the need to define custom ControlTemplate
's and all the overhead that come with it.
Upvotes: 1