代码之家  ›  专栏  ›  技术社区  ›  Arian Motamedi

将UI操作委托给ViewModel执行

  •  3
  • Arian Motamedi  · 技术社区  · 13 年前

    我有一个 ScrollViewer 它持有 ItemsSource 。这些项绑定到ViewModel,并按升序排序。用户可以向该列表中添加项目,但是,由于排序顺序的原因,该列表需要滚动到底部。根据我的发现, 滚动条 没有“锁定到底”功能,但有 ScrollToEnd 方法,这就是我想要的。

    然而,问题是,这些项被添加到ViewModel中,而ViewModel显然没有访问View的权限来调用 滚动到结束 方法 滚动条 。为了解决这个问题,我在ViewModel中声明了一个操作委托,如下所示:

    public Action ScrollAction { get; set; }
    

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

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

    将项目添加到列表后,将在ViewModel中执行委托。尽管这很有效,但我觉得有点生气,因为这打破了ViewModel与View的隔离。有更好的方法来实现这一点吗?

    1 回复  |  直到 13 年前
        1
  •  1
  •   Rajiv    13 年前

    我也会投票给你的滚动查看器一个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();
    }
    .....