通过viewmodel将scrollviewer滚动到顶部 [英] Scroll the scrollviewer to top through viewmodel
问题描述
我使用的是带有 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 AtachedProperty
as 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屋!