Xamarin forms scroll to buttom

2019-07-24 13:48发布

问题:

I am creation an Xamarin foms app where I will have messages coming over time, and I always want the new messages to show on the button of my ListView as they are coming in.

At the moment my page looks like this:

 <StackLayout>
   <Button  Text="Login"  />
   <ListView  x:Name="MessageBox" ItemsSource="{Binding TempTest}" ></ListView>
   <Button Command="{Binding AddMessage}" Text="Login"/>
 </StackLayout>

I cant figure out how to scroll from my ViewModel class, any ideas about how to achieve this?

The best that I have been able to find so far are this: http://www.infinite-x.net/2014/10/30/using-the-xamarin-forms-1-3-0-listview-scrollto-method/

But he is not even thinking about using MVVM at this stage.

回答1:

Well the one, less than elegant way, I would know to solve that would be to expose an Action<Message> from your ViewModel and then your ContentPage would initialize that Action and tell it to do the scrolling. Something like the following (just replace Message with what ever the real model name is).

ContentPage:

public partial class MessagePage : ContentPage {

    private MessageViewModel _viewModel;

    public MessagePage() {
        _viewModel = new MessageViewModel();

        BindingContext = _viewModel;

        _viewModel.OnMessageAdded = message => { //We tell the action to scroll to the passed in object here
            MessageBox.ScrollTo(message, ScrollToPosition.MakeVisible, true);
        }
    }
}

ViewModel:

public class MessageViewModel {
    public Action<Message> OnMessageAdded { get; set; }

    public ICommand AddMessage { get; protected set; }

    private ObservableCollection<Message> _tempTest;
    public  ObservableCollection<Message> TempTest {
        get { return _tempTest ?? (_tempTest = new ObservableCollection<Message>()); }
        set {
            if(_tempTest != value) {
                _tempTest = value;
                OnPropertyChanged();
            }
        }
    }

    public MessageViewModel() {
        AddMessage = new Command(async () => {
            Message message = SomeClass.GetMessage(); //Get your object from your separate class

            TempTest.Add(message); //Add it to the list that your ListView binds to

            OnMessageAdded?.Invoke(message); //Now run the Action which, if it is not null, your ContentPage should have set to do the scrolling

            //Or if you are not using C#6:
            //Action<Message> onMessageAdded = OnMessageAdded;

            //if(onMessageAdded != null) { onMessageAdded.Invoke(message); }
        });
    }
}