4gus71n
4gus71n

Reputation: 4073

Xamarin.Forms - ListView isn't being updated in the OnAppearing method

I'm developing an app with Xamarin.Forms, I've a screen where the user can publish a feed update, this feed update contains text and some attached files. My xaml view is basically, a StackLayout that contains a ListView, and Editor and a couple of Buttons. The problem is that I'm trying to set the ItemSource of my ListView in the onAppearing method. The method is being called just fine. The collection that I'm setting changes as is expected. But for some reason the ListView isn't being updated. A workaround that made the ListView work was right after setting the Source call the Editor focus method. I did because I figured out that when I clicked in the editor after the collection was suppously set, the ListView rendered properly. But well is a very nasty workaround.

Here's my xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="HalliganTL.View.UpdateFeedPage">
  <StackLayout Orientation="Vertical" >
    <ListView x:Name="AttachedFilesListView" MinimumHeightRequest="50" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <StackLayout HorizontalOptions="StartAndExpand" Orientation="Horizontal">
              <Button Text="[X]" />
              <StackLayout Padding="5,0,0,0" VerticalOptions="StartAndExpand" Orientation="Vertical">
                <Label Text="{Binding Name}" VerticalTextAlignment="Center" FontSize="Medium" />
              </StackLayout>
            </StackLayout>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
    <Editor x:Name="UpdateFeedEditor" FontSize="15" Text="{Binding PostText}"  VerticalOptions="FillAndExpand" />
    <Button Text="Attach file" TextColor="White" BackgroundColor="#77D065" Clicked="onAttachFileClicked"/>
    <Button Text="Post" TextColor="White" BackgroundColor="#77D065" Clicked="onPostClicked"/>
  </StackLayout>
</ContentPage>

Here's my page code:

public partial class UpdateFeedPage : ContentPage
    {
        public static List<FileObject> CurrentSelectedFile = new List<FileObject>();
        public static string PostText = "";

        public UpdateFeedPage()
        {
            InitializeComponent();
            Title = "New Update";
            UpdateFeedEditor.Text = PostText;
        }

        protected override void OnAppearing()
        {
            AttachedFilesListView.ItemsSource = CurrentSelectedFile;
            UpdateFeedEditor.Focus();
            base.OnAppearing();
        }

        async void onPostClicked(object sender, EventArgs e)
        {
            await Navigation.PopAsync();
        }

        async void onAttachFileClicked(object sender, EventArgs e)
        {
            await Navigation.PushAsync(new FilePickerPage());
        }
    }

I played with a lot of things like:

But nothing worked so far, except calling the Editor, Focus method programatically

NOTE:

As you can see the ListView collection that I'm setting is static, I modify that collection directly from another page, but I think that is OK, because when I set a breakpoint in the OnAppearing the collection was being modify properly.

Upvotes: 2

Views: 5462

Answers (1)

SushiHangover
SushiHangover

Reputation: 74094

Two ways to fix that refresh issue.

1st way)

Force the ListView to refresh from your List<FileObject> collection by resetting the ItemsSource:

Current:

protected override void OnAppearing()
{
    AttachedFilesListView.ItemsSource = CurrentSelectedFile;
    UpdateFeedEditor.Focus();
    base.OnAppearing();
}

Change to:

protected override void OnAppearing()
{
    base.OnAppearing();
    AttachedFilesListView.ItemsSource = null;
    AttachedFilesListView.ItemsSource = CurrentSelectedFile;
}

2nd way)

Replace your List<FileObject> collection with an ObservableCollection<FileObject> so changes are published via NotifyCollectionChangedAction.Add|Remove|... based events that the ListView will be listening to.

Current:

public static List<FileObject> CurrentSelectedFile = new List<FileObject>();

Change to:

public static readonly ObservableCollection<FileObject> CurrentSelectedFile = new ObservableCollection<FileObject>();

Note: Also add a using System.Collections.ObjectModel;

Your OnAppearing becomes:

protected override void OnAppearing()
{
    base.OnAppearing();
    AttachedFilesListView.ItemsSource = CurrentSelectedFile;
}

Upvotes: 7

Related Questions