3

我有一个ScrollViewer包含一个ItemsSource. 这些项目绑定到 ViewModel 并按升序排序。允许用户向此列表添加项目,但是,由于排序顺序,列表需要滚动到底部。根据我的发现,ScrollViewer没有“锁定到底部”功能,但有一种ScrollToEnd方法可以满足我的要求。

但问题是,项目是在 ViewModel 中添加的,而 ViewModel 显然无权访问 View 来ScrollToEnd调用ScrollViewer. 为了解决这个问题,我在 ViewModel 中声明了一个动作委托,如下所示:

public Action ScrollAction { get; set; }

并在创建 ViewModel 时将其设置在 View 中:

viewModel.ScrollAction = () => scrollViewer.ScrollToEnd();

一旦将项目添加到列表中,委托就会在 ViewModel 中执行。尽管这可行,但对我来说还是有点 hacky,因为这种方式打破了 ViewModel 与 View 的隔离。有没有更好的方法来实现这一目标?

4

1 回答 1

1

我还会为您的滚动查看器投票支持 AttachedProperty。

我创建了以下附加属性以将滚动绑定到以布尔变量结尾。

public static class ScrollViewerBehavior
    {
        public static readonly DependencyProperty ScrollToRightEndProperty =
            DependencyProperty.RegisterAttached("ScrollToRightEnd", typeof (bool), typeof (ScrollViewerBehavior),
                                                new PropertyMetadata(false, OnScrollToRightEndPropertyChanged));

        public static bool GetScrollToRightEnd(DependencyObject obj)
        {
            return (bool) obj.GetValue(ScrollToRightEndProperty);
        }

        public static void SetScrollToRightEnd(DependencyObject obj, bool value)
        {
            obj.SetValue(ScrollToRightEndProperty, value);
        }

        private static void OnScrollToRightEndPropertyChanged(DependencyObject sender,
                                                              DependencyPropertyChangedEventArgs e)
        {
            var sv = sender as ScrollViewer;
            if (sv == null) return;

            if ((bool) e.NewValue)
            {
                sv.ScrollToRightEnd();
            }
            else
            {
                sv.ScrollToLeftEnd();
            }
        }
    }

您可以在 XAML 中使用此附加属性...

<ScrollViewer ... local:ScrollViewerBehavior.ScrollToRightEnd="{Binding IsScrolledToEnd}" ... />

或者,如果您想保存问题中的操作委托,您可以在上面的 OnScrollToRightEndPropertyChanged 方法中执行以下操作。

.....
var viewModel = sv.DataContext as YourViewModel;
if (viewModel != null)
{
    viewModel.ScrollAction = () => sv.ScrollToRightEnd();
}
.....
于 2013-10-01T00:53:43.087 回答