有没有办法使用MVVM模式到达ListView的底部?我使用codebehind来完成这项工作,但如果可能的话,我希望使用MVVM来完成。
我使用ListView的ScrollTo()
方法。
感谢
实现这一点的一种方法是将委托方法附加到ViewModel并调用该委托。另一种方法是使用事件处理程序。如果使用ObservableCollection
,也可以订阅CollectionChanged
事件。无论采用哪种方法,都不会破坏MVVM模式,因为您正在应用控制反转。
请注意,在MVVM中,ViewModel必须不知道任何关于Views的信息,因此它也不能知道ScrollTo()
方法是否存在。也就是说,您将无法从View的代码背后调用ScrollTo()
方法
使用委托的解决方案
ViewModel
在ViewModel中,添加并调用一个委托,如下所示:
public class MyViewModel : INotifyPropertyChanged
{
public ObservableCollection<string> ListItems = new ObservableCollection<string>();
// delegate
public delegate void SomethingHappenedDelegate(string item);
public SomethingHappenedDelegate SomethingHappened = null;
private ICommand _someCommand;
public ICommand SomeCommand => _someCommand ??= new Command(SomeMethod);
private void SomeMethod()
{
var newItem = "hello";
ListItems?.Add(newItem);
SomethingHappened?.Invoke(newItem);
}
// skipping other stuff like initialization, INotifyPropertyChanged implementation, etc.
}
查看
然后,在视图后面的代码中,您可以设置委托:
public partial class MyPage : ContentPage
{
public MyPage(MyViewModel viewModel)
{
InitializeComponent();
viewModel.SomethingHappened = ScrollToBottom;
BindingContext = viewModel;
}
private void ScrollToBottom(string item)
{
MyListView.ScrollTo(item, ScrollToPosition.End, true);
}
}
在视图的XAML中,您绑定到以下命令:
<StackLayout>
<Button
Text="Add item and scroll"
Command="{Binding SomeCommand}" />
<ListView
x:Name="MyListView"
ItemsSource="{Binding ListItems}" />
</StackLayout>
您也可以实现自己的事件并订阅它,或者使用ObservableCollection
的内置事件。这取决于你,但基本概念是一样的。在不破坏MVVM的情况下,您无法将对ScrollTo()
的调用转移到View代码后面的某个位置。