通过viewmodel将scrollviewer滚动到顶部 [英] Scroll the scrollviewer to top through viewmodel

查看:63
本文介绍了通过viewmodel将scrollviewer滚动到顶部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是带有 MVVM 模式的 ScrollViewer,并且 ScrollViewer 包装了一个项目列表,例如

I am using the ScrollViewer with the MVVM pattern, and a list of items is wrapped by the ScrollViewer, such as

<ScrollViewer>
  <ListView>
    <ListView.View>
        <GridView>
            <GridViewColumn
                Header = "Name"
                DisplayMemberBinding="{Binding Path=Name}"
            />              
        </GridView>
    </ListView.View>
  </ListView>
</ScrollViewer>

listview 的items 绑定到viewmodel 中的对象集合.我希望滚动查看器在从集合中添加或删除项目时滚动到顶部.
我需要视图模型来触发事件,而不是在视图的代码隐藏中使用 ScrollToTop() 方法.

The items of the listview are bound to a collection of objects in the viewmodel. I want the scrollviewer to scroll to the top whenever a item is added or removed from the collection.
I need the viewmodel to trigger the event, rather than using the ScrollToTop() method in the code-behind of the view.

推荐答案

恕我直言,最清晰的方法是通过 AttachedProperty 使用行为".AttachedProperty 是一种扩展现有控件功能的机制.

IMHO, the clearest way to do this is using a "Behavior" via an AttachedProperty. An AttachedProperty is a mechanism to extend existing controls functionality.

首先,创建一个类来保存AtachedProperty,例如:

First, create a class to hold the AtachedProperty, for instance:

public class ScrollViewerBehavior
{
    public static bool GetAutoScrollToTop(DependencyObject obj)
    {
        return (bool)obj.GetValue(AutoScrollToTopProperty);
    }

    public static void SetAutoScrollToTop(DependencyObject obj, bool value)
    {
        obj.SetValue(AutoScrollToTopProperty, value);
    }

    public static readonly DependencyProperty AutoScrollToTopProperty =
        DependencyProperty.RegisterAttached("AutoScrollToTop", typeof(bool), typeof(ScrollViewerBehavior), new PropertyMetadata(false, (o, e) =>
            {
                var scrollViewer = o as ScrollViewer;
                if (scrollViewer == null)
                {
                    return;
                }
                if ((bool)e.NewValue)
                {
                    scrollViewer.ScrollToTop();
                    SetAutoScrollToTop(o, false);
                }
            }));
}

此附加属性允许 ScrollViewer 具有神奇地"类型 Boolean 的新属性,就像 XAML 中的 DependencyProperty.如果您将此属性绑定到 ViewModel 中的标准属性,例如:

This attached property allows a ScrollViewer having "magically" a new property of type Boolean, acting like a DependencyProperty in your XAML. If you bind this property to a standard property in your ViewModel, for instance:

private bool _reset;
public bool Reset
{
    get { return _reset; }
    set
    {
        _reset = value;
        if(PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("Reset"));
    }
}

(同样,名称由您决定)然后您将此 Reset 属性设置为 true,您的 ScrollViewer 将滚动到顶部.我已将 AtachedProperty 命名为 AutoScrollToTop,但名称对于此目的并不重要.

(again, the name is up to you) and then you set this Reset property to true, your ScrollViewer will scroll to top. I have named the AtachedPropertyas AutoScrollToTop, but the name is not important for this purpose.

XAML 将类似于:

<ScrollViewer my:ScrollViewerBehavior.AutoScrollToTop="{Binding Reset, Mode=TwoWay}">
    <ListView>
        <ListView.View>
            <GridView>
                <GridViewColumn
                    Header = "Name"
                    DisplayMemberBinding="{Binding Path=Name}"
                />
            </GridView>
        </ListView.View>
    </ListView>
</ScrollViewer>

注意:my 是您的 ScrollViewerBehavior 类所在的命名空间.例如:xmlns:my="clr-namespace:MyApp.Behaviors"

Note: my is the namespace where your ScrollViewerBehavior class lives. For example: xmlns:my="clr-namespace:MyApp.Behaviors"

最后,您在 ViewModel 中唯一需要做的就是在您喜欢的时候设置 Reset = true,在您的情况下,当您从集合中添加或删除元素时.

Finally, the only thing you have to do in your ViewModel is to set Reset = true when you like, in your case, when you add or remove an element from the collection.

这篇关于通过viewmodel将scrollviewer滚动到顶部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆