如何在 Listview 上使用 ScrollTo 方法

How to use ScrollTo method on a Listview

我有使用 prism 的 xamarin 表单应用程序。我正在使用绑定到 ObservableCollection<string>ListView,但是每当列表视图再次打开时,它需要滚动到列表视图中先前选择的项目。

有一个 ScrollTo 方法,但我如何使用 prism 实现它?

你能帮我解决这个问题吗?

  <ListView ItemsSource="{Binding obsCommonList}" HasUnevenRows="True" BackgroundColor="Black" SeparatorVisibility="None" SelectedItem="{Binding SelectedProp,Mode=TwoWay}">
      <ListView.Behaviors>
          <b:EventToCommandBehavior EventName="ItemTapped" Command="{Binding ItemTappedCommand}"  EventArgsParameterPath="Item"/>
      </ListView.Behaviors>

您可以尝试如下操作:

首先让 EventAggregator 在资源中可用,以便您可以将其添加到 XAML 中的行为 属性。

public class App : PrismApplication
{
    protected override async void OnInitialized()
    {
        Resources.Add("eventAggregator", Container.Resolve<IEventAggregator>());
        await NavigationService.NavigateAsync("MainPage");
    }
}

创建一个采用您在 ObservableCollection 中的模型类型的事件

public class ScrollToMyModelEvent : PubSubEvent<MyModel>
{
}

为 IEventAggregator 添加具有 属性 的行为。 注意您不需要 属性 成为可绑定的 属性,或者真正可观察的。您真正需要的是确保在设置 EventAggregator 时订阅事件。

public class ScrollToMyModelBehavior : BehaviorBase<ListView>
{
    private IEventAggregator _eventAggregator;
    public IEventAggregator EventAggregator
    {
        get => _eventAggregator;
        set
        {
            if(!EqualityComparer<IEventAggregator>.Default.Equals(_eventAggregator, value))
            {
                _eventAggregator = value;
                _eventAggregator.GetEvent<ScrollToMyModelEvent>().Subscribe(OnScrollToEventPublished);
            }
        }
    }

    private void OnScrollToEventPublished(MyModel model)
    {
        AssociatedObject.ScrollTo(model, ScrollToPosition.Start, true);
    }

    protected override void OnDetachingFrom(ListView bindable)
    {
        base.OnDetachingFrom(bindable);
        // The Event Aggregator uses weak references so forgetting to do this
        // shouldn't create a problem, but it is a better practice.
        EventAggregator.GetEvent<ScrollToMyModelEvent>().Unsubscribe(OnScrollToEventPublished);
    }
}

在您的 ViewModel 中,您现在只需发布事件。您可以按照我在此处展示的方式进行操作,您只能在导航回视图时执行此操作。这将在 Behavior 中处理并将其传递到 ListView 的 ScrollTo 方法中。

public class MyListPageViewModel : BindableBase, INavigatedAware
{
    private IEventAggregator _eventAggregator { get; }

    public MyListPageViewModel(IEventAggregator eventAggregator)
    {
        _eventAggregator = eventAggregator;
    }

    public ObservableCollection<MyModel> MyModels { get; set; }

    public MyModel SelectedModel { get; set; }

    public void OnNavigatedTo(NavigationParameters)
    {
        if(parameters.GetNavigationMode() == NavigationMode.Back && 
           SelectedModel != null)
        {
            _eventAggregator.GetEvent<ScrollToMyModelEvent>()
                            .Publish(SelectedModel);
        }
    }
}

然后在您的视图中

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:behavior="clr-namespace:AwesomeApp.Behaviors" 
             x:Class="AwesomeApp.ScrollToPage">
    <ListView>
        <ListView.Behaviors>
            <behavior:ScrollToMyModelBehavior EventAggregator="{StaticResource eventAggregator}" />
        </ListView.Behaviors>
    </ListView>
</ContentPage>