Listview Binding not working

I have the following in pcl

<?xml version="1.0" encoding="utf-8" ?>

<Label Text="Hello, XAML!"
        VerticalOptions="Start"
        HorizontalTextAlignment="Center"
        Rotation="-15"
        IsVisible="true"
        FontSize="Large"
        FontAttributes="Bold"
        TextColor="Aqua" />

<ListView ItemsSource="{Binding EmployeeList}"
        HasUnevenRows="True">
  <ListView.ItemTemplate>
    <DataTemplate>
      <ViewCell>
        <StackLayout Orientation="Vertical" Padding="12,6">
          <Label Text="{Binding Name}" />
        </StackLayout>
      </ViewCell>
    </DataTemplate>
  </ListView.ItemTemplate>
</ListView>

And the code behind:

    public partial class LoginPage : ContentPage
        {
            public LoginPage()
            {
                InitializeComponent();
                BindingContext = new LoginViewModel(this);
            }

            protected override void OnAppearing()
            {
                base.OnAppearing();
                LoginViewModel model = new LoginViewModel(this);
                model.GetEmployees();
            }
        }

And my viewmodel:

public class LoginViewModel : INotifyPropertyChanged
    {
        LoginPage page;
        private List<Employees> _employeeList;

        public List<Employees> EmployeeList
        {
            get { return _employeeList; }
            set
            {
                _employeeList = value;
                OnPropertyChanged();
            }
        }

        public LoginViewModel(LoginPage parent)
        {
            page = parent;
        }

        public async void GetEmployees()
        {
            var loginService = new LoginService();
            EmployeeList = await loginService.GetEmployeesAsync();
        }

        public Command GetListCommand //TODO: CHANGE ME
        {
            get
            {
                return new Command(async () =>
                {
                    var loginService = new LoginService();//should proc going to new page, stock for now
                    EmployeeList = await loginService.GetEmployeesAsync();
                });
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

        }
    }

Issue I have although my service is returning 427 results, and my employees list is populated with 1 property called "Name". its always blank when rendering. Have i missed something?

Tagged:

Best Answer

Answers

  • StevenSmith.6830StevenSmith.6830 USMember
    edited December 2016

    So using INotifyCollectionChanged and implimenting, OnCollectionChanged method on the invoke what NotifyCollectionChangedAction should i be using?

    protected virtual void OnCollectionChanged( NotifyCollectionChangedAction action)
            {
                CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(action));
            }
    

    Is what i have set up, threw a breakpoint here but only my propertychanged is hit not the collection. Am i on the correct path or did i miss something?

  • MikeRowley403MikeRowley403 CAMember ✭✭✭

    List doesn't implement INotifyChanged so it never fires, you need an ObservableCollection

    This stackoverflow answer is what you are looking for http://stackoverflow.com/a/8470177/4314198

  • voidstreamvoidstream FRMember ✭✭✭
    edited December 2016

    I use binding listview without INotifyChanged and ObservableCollection.

    Your XAML is okay
    I just put in the code behind, MyListView.ItemsSource = MyListOfObjects();
    :/
    You do that for the refresh of list?

  • StevenSmith.6830StevenSmith.6830 USMember
    edited December 2016

    @MikeRowley403 said:
    List doesn't implement INotifyChanged so it never fires, you need an ObservableCollection

    This stackoverflow answer is what you are looking for http://stackoverflow.com/a/8470177/4314198

    I changed my list to Observable collection, changed this throughout my code, still nothing, the only things thats ever called is the OnPropertyChanged method, which is correct as the employeelist property is being changed with the values i get back for my web api.

    The issue however is my list on my front end is still showing blank.

    EDIT: just realized i forgot to call my new method for collections. by the way my new method is:

     protected virtual void OnCollectionChanged( NotifyCollectionChangedAction action)
            {
                CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(action));
            }
    

    And i now call it like,

    public ObservableCollection<Employees> EmployeeList
        {
            get { return _employeeList; }
            set
            {
                _employeeList = value;
                OnPropertyChanged();
                OnCollectionChanged(NotifyCollectionChangedAction.Reset);
            }
        }
    

    Just stepped through and CollectionChanged is null so if im correct the Invoke never happens for the notify.
    Any reason why this would see it as null? what am i missing?

    I take it my OnAppearing method is ok on the xaml code behind?

  • MikeRowley403MikeRowley403 CAMember ✭✭✭
    edited December 2016

    @StevenSmith.6830 CollectionChanged is an event and will be null unless something is attached to that event, hence your null propagation to avoid a NullReferenceException when using it.
    As this is obviously an incomplete code set its almost impossible to say exactly what is wrong but this may push you in the correct direction. http://stackoverflow.com/questions/4588359/implementing-collectionchanged

    I think your biggest issue is that you are doing all of the heavy lifting unnecessarily, is there a reason why you aren't using an MVVM framework? Personally I use MVVM Light http://www.mvvmlight.net/ but MVVMCross is also very popular https://github.com/MvvmCross.
    With MVVM Light you simply call RaisePropertyChanged(() => EmployeeList); and it triggers the iNotify events automatically.

    An MVVM Framework would take care of much of the heavy lifting for you and I suspect it would simplify the process for you and likely solve your issue.

    The last gotcha I have run into often with ListView's being empty, is that the data actually loads but the bindings are wrong so the ViewCells are simply empty. Just something to be aware of.

Sign In or Register to comment.