简体   繁体   English

WPF覆盖列表框中的ScrollVIewer

[英]WPF overriding ScrollVIewer in Listbox

I made a class named "AniScrollViewer," it can set the vertical scroll offset 我制作了一个名为“ AniScrollViewer”的类,它可以设置垂直滚动偏移量
to animate Scrollviewer code-behind. 动画化Scrollviewer背后的代码。

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 我想将此“ AniScrollViewer”推入列表框

I meet couple of problems: 我遇到几个问题:

  • The Listbox class already has 'scrollviewer' inside. Listbox类中已经包含“ scrollviewer”。 I want to replace 我要更换
    the default listbox scrollviewer with my custom AniScrollViewer, but I don't know how to do this. 默认的列表框scrollviewer和我的自定义AniScrollViewer,但是我不知道该怎么做。
  • I want to get ScrollViewer in Listbox code-behind. 我想在代码隐藏列表框中获取ScrollViewer。 Like this: 像这样:

Listbox listbox (this is already definded in XAML) 列表框列表框(已在XAML中定义)
AniScrollViewer scrollviewer = listbox.~~~~; AniScrollViewer scrollviewer =列表框。~~~~;

Please help. 请帮忙。

  • To replace the default 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 ). 要将默认的ScrollViewer替换为自定义Style ,请为ListBox定义自定义Style ,然后在ControlTemplate使用您的默认ScrollViewerlocal:AniScrollViewer )切换出来。 Now any ListBox using this Style will have your ScrollViewer . 现在,任何使用此Style ListBox都将具有ScrollViewer Default ControlTemplate and Style can be found Here 默认的ControlTemplateStyle可以在这里找到
  • To get the ScrollViewer in the code-behind, you can use this as a reference. 要在后面的代码中获取ScrollViewer ,可以将用作参考。 In the function 在功能上

GetScrollViewer(DependencyObject o)

check it to be type safe with your custom ScrollViewer such as 使用您的自定义ScrollViewer检查它是否安全,例如

if (o is AniScrollViewer)
  return o;

Alternate 备用

However in your case, am not sure why your opting to subclass the ScrollViewer for this. 但是,根据您的情况,不确定为什么要为此选择ScrollViewer子类。 Instead of the hassle of this with defining your own ListBox ControlTemplate , maybe try using an attached property. 定义您自己的ListBox ControlTemplate麻烦,可以尝试使用附加属性。 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. 这样,您无需定义自定义ControlTemplate及其附带的所有开销。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM