13

我在 a 中有一个Visuals集合ListBox。我需要在其中找到XPosition一个元素的 ,然后对 的 进行动画HorizontalOffset处理。本质上我想创建一个动画方法。ListBoxScrollViewerScrollIntoView

这给了我几个问题。首先,如何获得对ListBoxs 滚动查看器的引用?其次,我怎样才能获得中任意元素的相对XPosition或?HozintalOfffsetListBox

我没有回应任何关于ListBox自身的输入,所以我不能使用Mouse相关的属性。

4

2 回答 2

33

我认为您不能将 WPF 故事板用于动画,因为故事板会为 WPF 依赖属性设置动画。你需要打电话ScrollViewer.ScrollToHorizontalOffset(double)来滚动。

您可以尝试在 OnDependencyPropertyChanged() 函数中创建一个调用 SetHorizo​​ntalOffset 的自定义依赖项属性。然后你可以为这个属性设置动画。

public static readonly DependencyProperty ScrollOffsetProperty =
   DependencyProperty.Register("ScrollOffset", typeof(double), typeof(YOUR_TYPE),
   new FrameworkPropertyMetadata(0.0, new PropertyChangedCallback(OnScrollOffsetChanged)));


public double ScrollOffset
{
   get { return (double)GetValue(ScrollOffsetProperty); }
   set { SetValue(ScrollOffsetProperty, value); }
}

private static void OnScrollOffsetChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
   YOUR_TYPE myObj = obj as YOUR_TYPE;

   if (myObj != null)
      myObj.SCROLL_VIEWER.ScrollToHorizontalOffset(myObj.ScrollOffset);
}

要获得滚动查看器,您可以使用 VisualTreeHelper 搜索 ListBox 的可视子项。保存对 ScrollViewer 的引用,因为稍后您将需要它。试试这个:

public static childItem FindVisualChild<childItem>(DependencyObject obj)
   where childItem : DependencyObject
{
   // Iterate through all immediate children
   for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
   {
      DependencyObject child = VisualTreeHelper.GetChild(obj, i);

      if (child != null && child is childItem)
         return (childItem)child;

      else
      {
         childItem childOfChild = FindVisualChild<childItem>(child);

         if (childOfChild != null)
            return childOfChild;
      }
   }

   return null;
}

此函数返回参数类型的第一个可视子项。调用FindVisualChild<ScrollViewer>(ListBox)以获取 ScrollViewer。

最后,尝试使用UIElement.TranslatePoint(Point, UIElement)获取项目的 X 位置。在item上调用这个函数,传入0,0作为point,传入ScrollViewer。

希望这可以帮助。

于 2009-03-20T11:45:45.383 回答
1

我不确定我的方法是否是好的做法,但在有限的时间内我似乎可以正常工作。我没有使用故事板,而是使用了 DispatcherTimer。

ScrollLeftButtonCommand = new DelegateCommand(
    o =>
       {
           var scrollViewer = (ScrollViewer)o;

           scrollTimer = new DispatcherTimer();

           scrollTimer.Start();

           scrollTimer.Interval = TimeSpan.FromMilliseconds(30);

           scrollTimer.Tick += (s, e) =>
           {          
               scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset - 50);

               if (scrollViewer.HorizontalOffset <= 0)
               {
                   scrollTimer.Stop();
               }
           };
       });

确保它是 DispatchTimer,以便线程能够控制 UI 元素

还要记住在您的视图中绑定到您的对象!

<Button CommandParameter="{Binding ElementName=MyScrollViewer }"
        Command="{Binding ScrollLeftButtonCommand }"/>
于 2015-02-09T10:00:24.833 回答