2017-07-11 1 views
0

J'ai une application xamarin forms qui utilise le prisme. J'utilise un ListView qui est lié à un ObservableCollection<string>, cependant chaque fois que la liste s'ouvre à nouveau, il doit faire défiler jusqu'à l'élément précédemment sélectionné de la liste.Comment utiliser la méthode ScrollTo sur une Listview

Il existe une méthode ScrollTo mais comment l'implémenter en utilisant le prisme?

Pourriez-vous s'il vous plaît m'aider avec ce problème?

<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> 

+0

Vous pouvez consulter ce lien. [https://stackoverflow.com/a/40452064/5293268] – Sunny

Répondre

1

Vous pouvez essayer quelque chose comme ce qui suit:

Commencez par faire le EventAggregator disponible dans les ressources afin que vous puissiez ajouter à une propriété de comportement dans votre XAML.

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

Créer un événement qui prend le type de modèle que vous avez dans votre ObservableCollection

public class ScrollToMyModelEvent : PubSubEvent<MyModel> 
{ 
} 

Ajouter un comportement avec une propriété pour la IEventAggregator. REMARQUE Vous n'avez pas besoin que la propriété soit une propriété lisible ou réellement observable. Ce dont vous avez réellement besoin, c'est de vous assurer de vous abonner à l'événement lorsque EventAggregator est défini.

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); 
    } 
} 

Dans votre ViewModel, il vous suffit maintenant de publier l'événement. Vous pouvez faire ce que je montre ici où vous ne faites cela que lorsque vous revenez à la vue. Cela sera ensuite géré dans le comportement et le passera dans la méthode ScrollTo de ListView.

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); 
     } 
    } 
} 

Ensuite, dans votre vue

<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> 
+0

Merci Dan, dans la classe de comportement la méthode _OnAttachBehaviorChanged_ du _AttachBehaviorProperty_ est congédié, mais je ne suis pas en mesure de souscrire à l'événement comme _OnAttachBehaviorChanged_ est statique Pouvez-vous s'il vous plaît jeter un oeil à ma classe de comportement: [link] (https://gist.github.com/anonymous/eb01517dbec43a0d0ae0d0fcbc73c857) –

+0

S'il vous plaît voir la révision de la Behavior. Vous n'avez besoin de rien statique dans la classe du tout :) –

+0

Cela fonctionne Dan, merci beaucoup pour la solution et l'explication détaillée. –